server, post: add about images for social media
Signed-off-by: Naman Sood <mail@nsood.in>
This commit is contained in:
parent
4fd8925116
commit
4c39700474
36 changed files with 216 additions and 3 deletions
BIN
fonts/JetBrainsMono-Bold.ttf
Normal file
BIN
fonts/JetBrainsMono-Bold.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-BoldItalic.ttf
Normal file
BIN
fonts/JetBrainsMono-BoldItalic.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-ExtraBold.ttf
Normal file
BIN
fonts/JetBrainsMono-ExtraBold.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-ExtraBoldItalic.ttf
Normal file
BIN
fonts/JetBrainsMono-ExtraBoldItalic.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-ExtraLight.ttf
Normal file
BIN
fonts/JetBrainsMono-ExtraLight.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-ExtraLightItalic.ttf
Normal file
BIN
fonts/JetBrainsMono-ExtraLightItalic.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-Italic.ttf
Normal file
BIN
fonts/JetBrainsMono-Italic.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-Light.ttf
Normal file
BIN
fonts/JetBrainsMono-Light.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-LightItalic.ttf
Normal file
BIN
fonts/JetBrainsMono-LightItalic.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-Medium.ttf
Normal file
BIN
fonts/JetBrainsMono-Medium.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-MediumItalic.ttf
Normal file
BIN
fonts/JetBrainsMono-MediumItalic.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-Regular.ttf
Normal file
BIN
fonts/JetBrainsMono-Regular.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-SemiBold.ttf
Normal file
BIN
fonts/JetBrainsMono-SemiBold.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-SemiBoldItalic.ttf
Normal file
BIN
fonts/JetBrainsMono-SemiBoldItalic.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-Thin.ttf
Normal file
BIN
fonts/JetBrainsMono-Thin.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-ThinItalic.ttf
Normal file
BIN
fonts/JetBrainsMono-ThinItalic.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-Black.ttf
Normal file
BIN
fonts/Nunito-Black.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-BlackItalic.ttf
Normal file
BIN
fonts/Nunito-BlackItalic.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-Bold.ttf
Normal file
BIN
fonts/Nunito-Bold.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-BoldItalic.ttf
Normal file
BIN
fonts/Nunito-BoldItalic.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-ExtraBold.ttf
Normal file
BIN
fonts/Nunito-ExtraBold.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-ExtraBoldItalic.ttf
Normal file
BIN
fonts/Nunito-ExtraBoldItalic.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-ExtraLight.ttf
Normal file
BIN
fonts/Nunito-ExtraLight.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-ExtraLightItalic.ttf
Normal file
BIN
fonts/Nunito-ExtraLightItalic.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-Italic.ttf
Normal file
BIN
fonts/Nunito-Italic.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-Light.ttf
Normal file
BIN
fonts/Nunito-Light.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-LightItalic.ttf
Normal file
BIN
fonts/Nunito-LightItalic.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-Regular.ttf
Normal file
BIN
fonts/Nunito-Regular.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-SemiBold.ttf
Normal file
BIN
fonts/Nunito-SemiBold.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-SemiBoldItalic.ttf
Normal file
BIN
fonts/Nunito-SemiBoldItalic.ttf
Normal file
Binary file not shown.
93
fonts/OFL.txt
Normal file
93
fonts/OFL.txt
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
Copyright 2014 The Nunito Project Authors (https://github.com/googlefonts/nunito)
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
http://scripts.sil.org/OFL
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
3
go.mod
3
go.mod
|
@ -4,12 +4,15 @@ go 1.15
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/aymerick/raymond v2.0.2+incompatible
|
github.com/aymerick/raymond v2.0.2+incompatible
|
||||||
|
github.com/fogleman/gg v1.3.0 // indirect
|
||||||
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||||
github.com/mitchellh/mapstructure v1.4.1
|
github.com/mitchellh/mapstructure v1.4.1
|
||||||
github.com/rjeczalik/notify v0.9.2
|
github.com/rjeczalik/notify v0.9.2
|
||||||
github.com/wellington/go-libsass v0.9.2
|
github.com/wellington/go-libsass v0.9.2
|
||||||
github.com/yuin/goldmark v1.3.1
|
github.com/yuin/goldmark v1.3.1
|
||||||
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691
|
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691
|
||||||
github.com/yuin/goldmark-meta v1.0.0
|
github.com/yuin/goldmark-meta v1.0.0
|
||||||
|
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d // indirect
|
||||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777 // indirect
|
golang.org/x/net v0.0.0-20210119194325-5f4716e94777 // indirect
|
||||||
golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46 // indirect
|
golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46 // indirect
|
||||||
)
|
)
|
||||||
|
|
7
go.sum
7
go.sum
|
@ -23,6 +23,10 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||||
github.com/dlclark/regexp2 v1.1.6/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
github.com/dlclark/regexp2 v1.1.6/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
||||||
github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk=
|
github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk=
|
||||||
github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
||||||
|
github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
|
||||||
|
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
||||||
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
||||||
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||||
github.com/gorilla/csrf v1.6.0/go.mod h1:7tSf8kmjNYr7IWDCYhd3U8Ck34iQ/Yw5CJu7bAkHEGI=
|
github.com/gorilla/csrf v1.6.0/go.mod h1:7tSf8kmjNYr7IWDCYhd3U8Ck34iQ/Yw5CJu7bAkHEGI=
|
||||||
github.com/gorilla/handlers v1.4.1/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
github.com/gorilla/handlers v1.4.1/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||||
|
@ -60,6 +64,8 @@ github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691 h1:VWSx
|
||||||
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691/go.mod h1:YLF3kDffRfUH/bTxOxHhV6lxwIB3Vfj91rEwNMS9MXo=
|
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691/go.mod h1:YLF3kDffRfUH/bTxOxHhV6lxwIB3Vfj91rEwNMS9MXo=
|
||||||
github.com/yuin/goldmark-meta v1.0.0 h1:ScsatUIT2gFS6azqzLGUjgOnELsBOxMXerM3ogdJhAM=
|
github.com/yuin/goldmark-meta v1.0.0 h1:ScsatUIT2gFS6azqzLGUjgOnELsBOxMXerM3ogdJhAM=
|
||||||
github.com/yuin/goldmark-meta v1.0.0/go.mod h1:zsNNOrZ4nLuyHAJeLQEZcQat8dm70SmB2kHbls092Gc=
|
github.com/yuin/goldmark-meta v1.0.0/go.mod h1:zsNNOrZ4nLuyHAJeLQEZcQat8dm70SmB2kHbls092Gc=
|
||||||
|
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jpsYr0ADedCk1wq6fTMTvs=
|
||||||
|
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
|
||||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777 h1:003p0dJM77cxMSyCPFphvZf/Y5/NXf5fzg6ufd1/Oew=
|
golang.org/x/net v0.0.0-20210119194325-5f4716e94777 h1:003p0dJM77cxMSyCPFphvZf/Y5/NXf5fzg6ufd1/Oew=
|
||||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
@ -69,6 +75,7 @@ golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46 h1:V066+OYJ66oTjnhm4Yrn7SXIw
|
||||||
golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
|
7
post.go
7
post.go
|
@ -31,6 +31,7 @@ type Post struct {
|
||||||
Slug string
|
Slug string
|
||||||
Metadata Metadata
|
Metadata Metadata
|
||||||
Contents string
|
Contents string
|
||||||
|
Image bytes.Buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPost(slug string) (*Post, error) {
|
func newPost(slug string) (*Post, error) {
|
||||||
|
@ -73,6 +74,12 @@ func newPost(slug string) (*Post, error) {
|
||||||
Contents: converted.String(),
|
Contents: converted.String(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
url := blogURL + "/" + slug
|
||||||
|
err = createImage(post.Metadata.Title, post.Metadata.Summary, url, &post.Image)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("could not create post image: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
return post, nil
|
return post, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
108
server.go
108
server.go
|
@ -1,12 +1,22 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
"log"
|
"log"
|
||||||
|
"math"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/aymerick/raymond"
|
"github.com/aymerick/raymond"
|
||||||
|
"github.com/fogleman/gg"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
blogTitle = "Prose"
|
||||||
|
blogURL = "https://prose.nsood.in"
|
||||||
|
blogSummary = "Where I infodump in Markdown and nobody can stop me."
|
||||||
)
|
)
|
||||||
|
|
||||||
type server struct {
|
type server struct {
|
||||||
|
@ -15,7 +25,8 @@ type server struct {
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
templates map[string]*raymond.Template
|
templates map[string]*raymond.Template
|
||||||
postList
|
postList
|
||||||
styles map[string]string
|
styles map[string]string
|
||||||
|
homeImage bytes.Buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
func newServer() (*server, error) {
|
func newServer() (*server, error) {
|
||||||
|
@ -23,6 +34,11 @@ func newServer() (*server, error) {
|
||||||
staticHandler: http.FileServer(http.Dir("static/")),
|
staticHandler: http.FileServer(http.Dir("static/")),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err := createImage(blogTitle, blogSummary, blogURL, &s.homeImage)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
posts, err := newPostList()
|
posts, err := newPostList()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -92,11 +108,18 @@ func (s *server) router(res http.ResponseWriter, req *http.Request) {
|
||||||
s.homePage(res, req)
|
s.homePage(res, req)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if slug == "about.png" {
|
||||||
|
s.renderImage(res, req, &s.homeImage)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
for _, p := range s.postList {
|
for _, p := range s.postList {
|
||||||
if p.Slug == slug {
|
if slug == p.Slug {
|
||||||
s.postPage(p, res, req)
|
s.postPage(p, res, req)
|
||||||
return
|
return
|
||||||
|
} else if slug == p.Slug+"/about.png" {
|
||||||
|
s.renderImage(res, req, &p.Image)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +175,7 @@ func (s *server) homePage(res http.ResponseWriter, req *http.Request) {
|
||||||
posts = posts + summary
|
posts = posts + summary
|
||||||
}
|
}
|
||||||
|
|
||||||
page, err := s.createWebPage("Home", "Where I infodump in Markdown and nobody can stop me.", posts)
|
page, err := s.createWebPage("Home", blogSummary, posts)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.errorInRequest(res, req, err)
|
s.errorInRequest(res, req, err)
|
||||||
|
@ -161,6 +184,14 @@ func (s *server) homePage(res http.ResponseWriter, req *http.Request) {
|
||||||
res.Write([]byte(page))
|
res.Write([]byte(page))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *server) renderImage(res http.ResponseWriter, req *http.Request, img io.Reader) {
|
||||||
|
res.Header().Add("content-type", "image/png")
|
||||||
|
_, err := io.Copy(res, img)
|
||||||
|
if err != nil {
|
||||||
|
s.errorInRequest(res, req, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (s *server) loadStylesheet(res http.ResponseWriter, req *http.Request, filename string) (ok bool) {
|
func (s *server) loadStylesheet(res http.ResponseWriter, req *http.Request, filename string) (ok bool) {
|
||||||
contents, ok := s.styles[filename]
|
contents, ok := s.styles[filename]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -170,3 +201,74 @@ func (s *server) loadStylesheet(res http.ResponseWriter, req *http.Request, file
|
||||||
res.Write([]byte(contents))
|
res.Write([]byte(contents))
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func createImage(title, summary, url string, out io.Writer) error {
|
||||||
|
imgWidth, imgPaddingX, imgPaddingY := 800, 30, 60
|
||||||
|
titleSize, summarySize, urlSize := 42.0, 28.0, 18.0
|
||||||
|
lineHeight := 1.5
|
||||||
|
textWidth := float64(imgWidth - 2*imgPaddingX)
|
||||||
|
|
||||||
|
// temporarily set height = 0 for context only used to generate
|
||||||
|
// wrapped strings
|
||||||
|
draw := gg.NewContext(imgWidth, 0)
|
||||||
|
|
||||||
|
titleFont, err := gg.LoadFontFace("fonts/Nunito-Bold.ttf", titleSize)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
summaryFont, err := gg.LoadFontFace("fonts/Nunito-LightItalic.ttf", summarySize)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
urlFont, err := gg.LoadFontFace("fonts/JetBrainsMono-ExtraLight.ttf", urlSize)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
draw.SetFontFace(titleFont)
|
||||||
|
wrappedTitle := draw.WordWrap(title, textWidth)
|
||||||
|
draw.SetFontFace(summaryFont)
|
||||||
|
wrappedSummary := draw.WordWrap(summary, textWidth)
|
||||||
|
|
||||||
|
imgHeight := 2 * imgPaddingY
|
||||||
|
for range wrappedTitle {
|
||||||
|
imgHeight += int(math.Ceil(lineHeight * titleSize))
|
||||||
|
}
|
||||||
|
for range wrappedSummary {
|
||||||
|
imgHeight += int(math.Ceil(lineHeight * summarySize))
|
||||||
|
}
|
||||||
|
imgHeight += int(math.Ceil(lineHeight * urlSize))
|
||||||
|
|
||||||
|
// actual context with actual height
|
||||||
|
draw = gg.NewContext(imgWidth, imgHeight)
|
||||||
|
draw.SetHexColor("#fff")
|
||||||
|
draw.DrawRectangle(0, 0, float64(imgWidth), float64(imgHeight))
|
||||||
|
draw.Fill()
|
||||||
|
draw.SetHexColor("#3498db")
|
||||||
|
accentHeight := 5.0
|
||||||
|
draw.DrawRectangle(0, float64(imgHeight)-accentHeight, float64(imgWidth), accentHeight)
|
||||||
|
draw.Fill()
|
||||||
|
|
||||||
|
offset := float64(imgPaddingY)
|
||||||
|
|
||||||
|
draw.SetFontFace(titleFont)
|
||||||
|
draw.SetHexColor("#333")
|
||||||
|
for _, line := range wrappedTitle {
|
||||||
|
draw.DrawString(line, float64(imgPaddingX), offset)
|
||||||
|
offset += lineHeight * titleSize
|
||||||
|
}
|
||||||
|
|
||||||
|
draw.SetFontFace(summaryFont)
|
||||||
|
draw.SetHexColor("#999")
|
||||||
|
for _, line := range wrappedSummary {
|
||||||
|
draw.DrawString(line, float64(imgPaddingX), offset)
|
||||||
|
offset += lineHeight * summarySize
|
||||||
|
}
|
||||||
|
|
||||||
|
draw.SetHexColor("#333")
|
||||||
|
draw.SetFontFace(urlFont)
|
||||||
|
urlY := float64(imgHeight - imgPaddingY)
|
||||||
|
draw.DrawStringWrapped(url, float64(imgPaddingX), urlY, 0, 0, textWidth, lineHeight, gg.AlignRight)
|
||||||
|
|
||||||
|
return draw.EncodePNG(out)
|
||||||
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
<meta property="og:type" content="website">
|
<meta property="og:type" content="website">
|
||||||
<meta property="og:title" content="{{title}} – Prose">
|
<meta property="og:title" content="{{title}} – Prose">
|
||||||
<meta property="og:description" content="{{subtitle}}">
|
<meta property="og:description" content="{{subtitle}}">
|
||||||
|
<meta property="og:image" content="./about.png">
|
||||||
<meta name="twitter:creator" content="@tendstofortytwo">
|
<meta name="twitter:creator" content="@tendstofortytwo">
|
||||||
<meta name="color-scheme" content="dark light">
|
<meta name="color-scheme" content="dark light">
|
||||||
<meta name="viewport" content="width=device-width">
|
<meta name="viewport" content="width=device-width">
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue