Commit 014d2d68 authored by eternal-flame-AD's avatar eternal-flame-AD

custom font init

parent 8eca39cb
......@@ -19,7 +19,7 @@ featured_image: /images/feature.jpg
申请季,忙里偷闲,小透明作为一位<del>假的</del>文科生和两位<del>真的</del>文科生同学一起参加了西塘的汉服文化周。虽然很遗憾因为申请的关系没能全程参与,算头算尾也就去了四天,不过也算是一次和同学,和环境,和民族的感情交流了~
> 悲欢聚散一杯酒,南北东西万里程。
> <span data-font="chanyu.ttf">悲欢聚散一杯酒,南北东西万里程。</span>
>
> <cite><a href="https://so.gushiwen.org/shiwenv_1f43a6466faa.aspx">长亭送别</a>&nbsp;&nbsp;&nbsp; 元 王实甫</cite>
......@@ -27,7 +27,7 @@ featured_image: /images/feature.jpg
脱产之后才发现,其实之前自己百般期待的每天不用上课的日子也没有那样的美好——在学校的时候,大家能够交谈共同的兴趣,给考试加油,玩那些怎么玩都不会无聊的只有本班同学能懂的梗……一直以为自己是个圈子很大的人,脱产以后才意识到原来失去了一起上课这一层羁绊,没有几个人是能够继续保持联系的。ED申请截止日临近,几个月后当我们都收到了来自各个城市,各个州,甚至是各个国家的admission letter时,离别大概就是一杯酒的距离了吧。
> 夜市千灯照碧云,高楼红袖客纷纷。
> <span data-font="chanyu.ttf">夜市千灯照碧云,高楼红袖客纷纷。</span>
>
> <cite><a href="https://so.gushiwen.org/shiwenv_807a6380e165.aspx">夜看扬州市</a> 唐 王建<br /></cite>
......@@ -37,7 +37,7 @@ featured_image: /images/feature.jpg
说到汉服,真的想说,看到有那么多穿汉服的同僚就觉得好开心www(PS:没有抢到线上的免票名额不过和小伙伴竟然赶上了最后一小时的现场免票!!小声:也算是从汉服大坑回了一点血)当看到从像我们这样的刚刚走进成年的人到年过半百的汉文化爱好者都在这里相聚,小透明还是燃起了一些曾经快要消逝的对汉文化的信心和自知——中国传统文化在大众心目中不只是景区摆着奇怪造型的佛像、叫不上名字的挂着LED彩灯的亭子、被呛人的烟味笼罩的功德箱和中小学生必背<del>矫情</del>古诗文1e+9999篇,而是确确实实地在不少人人心中留下了一些实实在在的东西的
> 山有木兮木有枝,心悦君兮君不知。
> <span data-font="chanyu.ttf">山有木兮木有枝,心悦君兮君不知。</span>
>
> <cite><a href="https://so.gushiwen.org/shiwenv_4a96c8287eb5.aspx">越人歌</a></cite>
......
{{ partial "head.html" .}}
<div class="container">
<div class="jumbotron jumbotron-narrow">
<h3 class="display-4">{{ .Title }}</h3>
<h3 class="display-4" data-font="chanyu.ttf">{{ .Title }}</h3>
{{if .Draft }}
<i class="fas fa-edit text-danger">Draft</i> <br />
{{end}}
{{ if .Params.signature }}<hr class="my-4" /><p class="text-muted">{{ .Params.signature }}</p>{{end}}
{{ if .Params.signature }}<hr class="my-4" /><p class="text-muted" data-font="chanyu.ttf">{{ .Params.signature }}</p>{{end}}
</div>
<article>
{{ .Content }}
......
......@@ -6,9 +6,9 @@
<div class="container">
<div class="jumbotron">
<h1 class="display-4">Blog</h1>
<p class="lead">小透明的小想法~~</p>
<p class="lead" data-font="chanyu.ttf">小透明的小想法~~</p>
<hr class="my-4" />
<p class="text-muted">{{len .Pages}} 篇文章, {{$wordCount}}字。</p>
<p class="text-muted" data-font="chanyu.ttf">{{len .Pages}} 篇文章, {{$wordCount}}字。</p>
</div>
{{ range .Paginator.Pages }}
{{ partial "articlemeta.html" .}}
......
{{ partial "head.html" .}}
<div class="container">
<div class="jumbotron jumbotron-narrow">
<h3 class="display-4">{{ .Title }}</h3>
<h3 class="display-4" data-font="chanyu.ttf">{{ .Title }}</h3>
<i class="text-muted"><i class="fas fa-user"></i>{{ .Params.author }}</i> <br />
<i class="text-muted"><i class="fas fa-clock"></i>{{ .Date.Format "Mon, Jan 2, 2006" }}</i> <br />
{{ if .Params.tags}}<i class="text-muted"><i class="fas fa-tags"></i>{{range $i, $t := .Params.tags}}{{$t}} {{end}}</i> <br />{{end}}
......@@ -12,7 +12,7 @@
{{if .Draft }}
<i class="fas fa-edit text-danger">Draft</i> <br />
{{end}}
{{ if .Params.signature }}<hr class="my-4" /><p class="text-muted">{{ .Params.signature }}</p>{{end}}
{{ if .Params.signature }}<hr class="my-4" /><p class="text-muted" data-font="chanyu.ttf">{{ .Params.signature }}</p>{{end}}
</div>
<article>
{{ .Content }}
......
......@@ -2,7 +2,7 @@
<div class="container">
<div class="jumbotron">
<h1 class="display-4">Eternal-flame-AD</h1>
<p class="lead" id="signature"><noscript>{{index (shuffle .Site.Data.signature.signature) 0}}</noscript></p>
<p class="lead" id="signature" data-font="chanyu.ttf"><noscript>{{index (shuffle .Site.Data.signature.signature) 0}}</noscript></p>
<script>
var s = {{.Site.Data.signature.signature}};
document.querySelector("#signature").innerHTML = s[Math.floor(Math.random()*s.length)];
......
......@@ -3,7 +3,7 @@
{{ if not (fileExists ( path.Join ( slice "static/" .Params.featured_image )))}}{{errorf "Feature image not found for article: %s. Path: %s" .Title .File.Path}}{{end}}
<img src="{{.Params.featured_image}}" class="img-fluid feature-img" />
{{end}}
<h3 class="list-title"><a href="{{ .Permalink }}">{{ .Title }}</a></h3>
<h3 class="list-title" data-font="chanyu.ttf"><a href="{{ .Permalink }}">{{ .Title }}</a></h3>
<i class="text-muted"><i class="fas fa-user"></i>{{ .Params.author }}</i> <br />
<i class="text-muted"><i class="fas fa-clock"></i>{{ .Date.Format "Mon, Jan 2, 2006" }}</i> <br />
{{ if .Params.categories}}<i class="text-muted"><i class="fas fa-shapes"></i>{{range $i, $t := .Params.categories}}<a href="/categories/{{lower $t}}">{{$t}}&nbsp;</a>{{end}}</i><br />{{end}}
......@@ -13,7 +13,7 @@
<i class="fas fa-edit text-danger">Draft</i>
{{end}}
<hr />
<p class="text-muted">
<p class="text-muted" data-font="chanyu.ttf">
{{if .Params.signature }}
{{ .Params.signature }}
{{else}}
......
......@@ -11,6 +11,54 @@
{{ if .RSSLink }}<link href="{{ .RSSLink }}" rel="alternate" type="application/rss+xml" title="{{ .Title }}" />{{ end }}
{{ partial "head_includes.html" . }}
<!-- Custom Font start -->
{{if .Site.IsServer }}
<script>
window.onload = function() {
console.log("Adding custom fonts")
const template = `
@font-face {
font-family: <fa>;
src: url(<url>);
}
[data-font="<ff>"] {
font-family: <fa>,-apple-system,BlinkMacSystemFont,Helvetica Neue,PingFang SC,Microsoft YaHei,Source Han Sans SC,Noto Sans CJK SC,WenQuanYi Micro Hei,sans-serif;
}
`
let nodes = document.querySelectorAll("[data-font]")
let fonts = [];
for (let node of nodes) {
let ff = node.getAttribute("data-font");
if (!fonts.includes(ff)) {
fonts.push(ff)
}
}
let style = "";
for (let font of fonts) {
let fa = font
if (fa.indexOf(".")!==-1) {
fa = fa.substr(0,fa.indexOf("."))
}
style += template.replace(/<fa>/g, fa).replace(/<ff>/g, font).replace(/<url>/g, "/fonts/"+font)
}
function appendStyle(styles) {
var css = document.createElement('style');
css.type = 'text/css';
if (css.styleSheet) css.styleSheet.cssText = styles;
else css.appendChild(document.createTextNode(styles));
document.getElementsByTagName("head")[0].appendChild(css);
}
appendStyle(style)
};
</script>
{{end}}
<!-- Custom Font end -->
</head>
<body lang="en">
{{ partialCached "navbar.html" . .Section .Dir}}
\ No newline at end of file
......@@ -2,9 +2,9 @@
publish = "public/"
command = "curl -fsSL https://gist.githubusercontent.com/eternal-flame-AD/7877ac56ef650e6e10b1d1c435973880/raw/e6e168646358bd73732fced16a0d352e23119a19/netlify-hugo-extended.sh | bash && LD_LIBRARY_PATH=$(pwd)/tmp/usr/lib/x86_64-linux-gnu $(pwd)/tmp/usr/local/bin/hugo --baseURL $BASE --minify"
command = "curl -fsSL https://gist.githubusercontent.com/eternal-flame-AD/7877ac56ef650e6e10b1d1c435973880/raw/e6e168646358bd73732fced16a0d352e23119a19/netlify-hugo-extended.sh | bash && LD_LIBRARY_PATH=$(pwd)/tmp/usr/lib/x86_64-linux-gnu $(pwd)/tmp/usr/local/bin/hugo --baseURL $BASE --minify && ./post.sh"
environment = { HUGO_FLAVOUR = "hugo_extended", HUGO_VERSION = "0.52" }
environment = { HUGO_FLAVOUR = "hugo_extended", HUGO_VERSION = "0.52", GIMME_GO_VERSION = "1.11.2" }
[context.production]
......@@ -12,7 +12,7 @@
[context.dev]
command = "curl -fsSL https://gist.githubusercontent.com/eternal-flame-AD/7877ac56ef650e6e10b1d1c435973880/raw/e6e168646358bd73732fced16a0d352e23119a19/netlify-hugo-extended.sh | bash && LD_LIBRARY_PATH=$(pwd)/tmp/usr/lib/x86_64-linux-gnu $(pwd)/tmp/usr/local/bin/hugo --baseURL $BASE -D -F"
command = "curl -fsSL https://gist.githubusercontent.com/eternal-flame-AD/7877ac56ef650e6e10b1d1c435973880/raw/e6e168646358bd73732fced16a0d352e23119a19/netlify-hugo-extended.sh | bash && LD_LIBRARY_PATH=$(pwd)/tmp/usr/lib/x86_64-linux-gnu $(pwd)/tmp/usr/local/bin/hugo --baseURL $BASE -D -F && ./post.sh"
environment = { BASE = "https://dev.eternalflame.cn/" }
......
#!/bin/bash
if [ ! -x $(which pyftsubset) ] ; then
pip3 install fonttools
fi
DIR=`pwd`
shopt -s dotglob
find postprocess/* -prune -type d | while IFS= read -r d; do
cd $d
echo "Entering $d"
if [ -f go.mod ]; then
echo "Found go.mod, installing modules"
go get
fi
go run *.go
cd $DIR
done
\ No newline at end of file
module font
require (
github.com/PuerkitoBio/goquery v1.5.0
github.com/gammazero/deque v0.0.0-20180920172122-f6adf94963e4 // indirect
github.com/gammazero/workerpool v0.0.0-20180920155329-48371c973101
)
github.com/PuerkitoBio/goquery v1.5.0 h1:uGvmFXOA73IKluu/F84Xd1tt/z07GYm8X49XKHP7EJk=
github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg=
github.com/andybalholm/cascadia v1.0.0 h1:hOCXnnZ5A+3eVDX8pvgl4kofXv2ELss0bKcqRySc45o=
github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
github.com/gammazero/deque v0.0.0-20180920172122-f6adf94963e4 h1:R+19WKQClnfMXS60cP5BmMe1wjZ4u0evY2p2Ar0ZTXo=
github.com/gammazero/deque v0.0.0-20180920172122-f6adf94963e4/go.mod h1:GeIq9qoE43YdGnDXURnmKTnGg15pQz4mYkXSTChbneI=
github.com/gammazero/workerpool v0.0.0-20180920155329-48371c973101 h1:6f48SdG6iWh/KZUmd4bRuAPXjddVBCAKiBdgXfzlKl0=
github.com/gammazero/workerpool v0.0.0-20180920155329-48371c973101/go.mod h1:w9RqFVO2BM3xwWEcAB8Fwp0OviTBBEiRmSBDfbXnd3w=
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a h1:gOpx8G595UYyvj8UK4+OFyY4rx037g3fmfhe5SasG3U=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
package main
import (
"bytes"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"path"
"strings"
"time"
"github.com/PuerkitoBio/goquery"
"github.com/gammazero/workerpool"
)
const Heading = "# generated by postprocess/font.go; DO NOT EDIT"
var ProjectDir = ""
func addHtmlFile(wd string, fileList *[]string) {
files, err := ioutil.ReadDir(wd)
if err != nil {
panic(err)
}
for _, f := range files {
if f.IsDir() {
addHtmlFile(path.Join(wd, "./", f.Name()), fileList)
} else if path.Ext(f.Name()) == ".html" {
*fileList = append(*fileList, path.Join(wd, "./", f.Name()))
}
}
}
type FontRequest map[string]string
func (c FontRequest) Append(font string, text string) {
if existSet, ok := c[font]; ok {
c[font] = UniqString(existSet + text)
} else {
c[font] = UniqString(text)
}
}
func getHTMLFontSubsetSlice(fn string) (FontRequest, error) {
f, err := os.Open(fn)
if err != nil {
return nil, err
}
defer f.Close()
doc, err := goquery.NewDocumentFromReader(f)
if err != nil {
return nil, err
}
res := make(FontRequest)
doc.Find("[data-font]").Each(func(i int, s *goquery.Selection) {
font, _ := s.Attr("data-font")
text := s.Text()
res.Append(font, text)
})
return res, nil
}
func makeFontSubset(fontfile string, text string) (string, error) {
flavor := "woff"
output := fmt.Sprintf("%s.%s.subset.%s", fontfile, SignStringMD5(text), flavor)
if _, err := os.Stat(output); err == nil {
return output, nil
}
unicodes := bytes.NewBuffer([]byte{})
for _, r := range text {
unicodes.WriteString(toUnicodeCodePoint(r))
unicodes.WriteRune(',')
}
unicodes.Truncate(unicodes.Len() - 1)
args := []string{fontfile}
args = append(args, "--unicodes="+unicodes.String())
args = append(args, "--output-file="+output)
args = append(args, "--flavor="+flavor)
cmd := exec.Command("pyftsubset", args...)
return output, cmd.Run()
}
func generateCSSForFont(font string, URL string) string {
fontSimple := font
dotPos := strings.IndexRune(font, '.')
if dotPos != -1 {
fontSimple = font[:dotPos]
}
return fmt.Sprintf(`
@font-face {
font-family: %s;
src: url(%s);
}
[data-font="%s"] {
font-family: %s,-apple-system,BlinkMacSystemFont,Helvetica Neue,PingFang SC,Microsoft YaHei,Source Han Sans SC,Noto Sans CJK SC,WenQuanYi Micro Hei,sans-serif;
}`, fontSimple, URL, font, fontSimple)
}
func appendStyleToFile(fn string, style string) error {
f, err := os.Open(fn)
if err != nil {
return err
}
doc, err := goquery.NewDocumentFromReader(f)
if err != nil {
f.Close()
return err
}
doc.Find("head").AppendHtml(fmt.Sprintf("<style>%s</style>", style))
f.Close()
f, err = os.OpenFile(fn, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
defer f.Close()
if err != nil {
return err
}
html, err := doc.Html()
if err != nil {
return err
}
_, err = f.WriteString(html)
if err != nil {
return err
}
return nil
}
func processHTMLFile(fn string) error {
fReq, err := getHTMLFontSubsetSlice(fn)
if err != nil {
return err
}
if len(fReq) == 0 {
return nil
}
style := bytes.NewBuffer([]byte{})
for font, text := range fReq {
fn, err := makeFontSubset(fmt.Sprintf("public/fonts/%s", font), text)
if err != nil {
log.Println(err)
}
style.WriteString(generateCSSForFont(font, fn[len("public"):]))
}
err = appendStyleToFile(fn, style.String())
if err != nil {
return err
}
return nil
}
func main() {
for {
_, err := os.Stat("config.toml")
if err == nil {
break
} else {
if err := os.Chdir("../"); err != nil {
panic(err)
}
}
}
ProjectDir, err := os.Getwd()
if err != nil {
panic(err)
}
fmt.Printf("Working at %s\n", ProjectDir)
filelist := make([]string, 0)
addHtmlFile("public/", &filelist)
pool := workerpool.New(10)
for _, htmlF := range filelist {
f := htmlF
pool.Submit(func() {
start := time.Now()
err := processHTMLFile(f)
if err != nil {
log.Println(err)
}
fmt.Printf("%s %dms \n", f, time.Now().Sub(start).Nanoseconds()/1000000)
})
}
pool.StopWait()
}
package main
import (
"crypto/md5"
"encoding/hex"
)
func SignStringMD5(s string) string {
digest := md5.New()
digest.Write([]byte(s))
hash := digest.Sum(nil)
return hex.EncodeToString(hash)
}
package main
import (
"bytes"
"sort"
)
type sortRunes []rune
func (s sortRunes) Less(i, j int) bool {
return s[i] < s[j]
}
func (s sortRunes) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s sortRunes) Len() int {
return len(s)
}
func sortString(s string) string {
r := []rune(s)
sort.Sort(sortRunes(r))
return string(r)
}
func UniqString(s string) string {
s = sortString(s)
res := bytes.NewBuffer([]byte{})
var last rune
for _, r := range s {
if r != last {
res.WriteRune(r)
}
last = r
}
return res.String()
}
package main
import "fmt"
func toUnicodeCodePoint(r rune) string {
return fmt.Sprintf("%U", r)
}
3.6
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment