Notes
Github Actions + fonttools 拉取字符并创建中文字体子集
创建子集部分参考自谢益辉老师的做法。如果你需要的中文字体在字图CDN有覆盖,用这个也能一定程度上提升性能。
本文将通过解释写好的workflow文件来展开,完整代码见最下方。
on:
workflow_dispatch:
workflow_run:
workflows: ["deploy"]
types:
- completed
告诉Github Actions什么时候自动运行,workflow_dispatch:
使得这个workflow能在对应页面手动点击运行,workflow_run:
这里我定义了使其在名字为deploy
的workflow完成后运行。
steps:
- name: Checkout repository
uses: actions/checkout@v3
checkout
把仓库的代码从Github克隆到workflow构建的运行环境中。
steps:
- name: Install fonttools
run: sudo apt-get update && sudo apt-get install -y fonttools
安装fonttools
。
steps:
- name: Extract used characters from content
run: |
mkdir -p font
find . -name '*.md' -o -name '*.html' | xargs cat \
| grep -oP '[\x{3000}-\x{30FF}\x{31F0}-\x{31FF}\x{4E00}-\x{9FFF}\x{AC00}-\x{D7AF}\x{FF00}-\x{FFEF}\x{FE10}-\x{FE1F}]' \
| sort | uniq > used-chars.txt
从所在项目的.md
和.html
提取出出现过的中日韩字符(CJK):在工作环境创建/font
文件夹,查找当前目录及子目录下所有以.md
或.html
结尾的文件,用cat
拼接成一个文件,用grep
来匹配字符范围(Unicode区间可自行重新设定),sort
排序,uniq
去重,> used-chars.txt
保存到一个文本文件。
Hugo Markdownify 无法生成 <p> tag
在尝试为Stream页面利用Hugo Shortcodes添加新的movie
和tv
标签时,使用{{ .Inner | Markdownify }}
无法正确对Markdown文本生成HTML<p>
tag。
例如:
{{ $text .= "What a *nice* day!" }}
{{ $text | Markdownify}} -> What a <em>nice</em> day!
但我预期生成的应是:
{{ $text | Markdownify }} -> <p>What a <em>nice</em> day!</p>
这是个老问题:Markdownify
最主要被用来生成标题之类的inline元素,而不是类似段落的blocks。但很多Hugo主题都在使用Markdownify
,所以一时想要用RenderString
取代也不太可能。
在我的情况中,先识别是否存在<p>
tag的方式:
{{ $markdown := .intro | markdownify }}
{{ if not ( strings.Contains $markdown "<p>" ) }}
<p>{{ $markdown }}</p>
{{ else }}
{{ $markdown }}
{{ end }}
或进一步匹配以h
、p
开头的tag都可以:
{{ $markdown := .text | markdownify }}
{{ if not ( findRE "<[h|p][^>]*>" $markdown ) }}
<p>{{ $markdown }}</p>
{{ else }}
{{ $markdown }}
{{ end }}
用 Webmention 接收 Mastodon 互动
更新于2024-07-09:
已删去此功能。原因:
- 维护麻烦(大改了一下Stream页面后,没法正常同步fediverse上回应,跟这个issue差不多)
- 用的人少(well, that’s what we called indie)
- 确实有一些ethical problem
什么是 webmention
Webmention是由IndieWeb发起的W3C标准,用来实现网页间相互提及,不必借助平台或引入评论系统。它的工作流程如下:
斜交策略 Oblique Strategies
被我们落下的想象力,以什么挽留他?
Brian Eno和Peter Schmidt设计了超过一百个prompt,写在卡片上,来帮你打破寻找创意的障碍。这里有英文版本的完整列表。
这组卡片叫Oblique Strategies,有人翻译成迂回策略或间接策略。我喜欢叫它“斜交策略”。因素分析中,你会遇到“正交旋转”与“斜交旋转”,激发创造力,就像从这些卡片中寻找能联动我们潜意识的相关因素。
当创作的工作属性变强、时间压力变重时,Eno和Schmidt意识到这会让他们偏离思考和创作的本质。于是他们都写下一些要旨,帮助保持思维活跃,提醒自己不要忘记那些能从侧面推进的有趣方法,整合成了这组卡片。
1980年初,Eno在接受Charles Amirkhanian采访时说道:
The Oblique Strategies evolved from me being in a number of working situations when the panic of the situation - particularly in studios - tended to make me quickly forget that there were others ways of working and that there were tangential ways of attacking problems that were in many senses more interesting than the direct head-on approach. If you’re in a panic, you tend to take the head-on approach because it seems to be the one that’s going to yield the best results Of course, that often isn’t the case - it’s just the most obvious and - apparently - reliable method. The function of the Oblique Strategies was, initially, to serve as a series of prompts which said, “Don’t forget that you could adopt this attitude,” or “Don’t forget you could adopt that attitude.
使用 Github Actions 自动部署 Hugo
回应痛点:
- 写作所用的设备不带环境,没有Git,必须换回原来用的设备
hugo
生成网页并部署- 只想好好写东西,不想再管我的终端/命令行
本文假设你已经在本地拥有一个用Hugo搭建的完整站点,且已经
push
到了username/username.github.io
这个仓库。1. 把源仓库传到一个新库
整体上传到一个新库后,我们可以使用Git方便地进行管理,相当于把原本在本地的博客系统传到网盘。在设置好Github Actions后,既可以整个库
clone
下来,也可以通过上传单个.md
文件到content/posts
文件夹的手动push
方式来自动部署,而这都不需要重新搭建Hugo环境。在这里我们使用Github Desktop:
- 点击菜单栏File,选择Create a new repository。
- 为了避免文件夹识别的混乱,在设置local path时,可以新建一个文件夹,之后再将博客系统文件(
config.toml
所在的整个文件夹和子文件夹)复制进来。- 复制后,回到Github Desktop,填写Summary,Commit to main,然后Push。
2. 将新库和Github Pages仓库串起来
在
username/username.github.io
下是public
文件夹内生成的静态网页(你一定记得的,在本地我们需要cd public
),而我们希望通过添加或修改源仓库的.md
来实现这一系列的生成和部署,这涉及到跨仓库的联动,需要通过token实现。网页版,点击头像,进入Github个人的Settings:
边栏最下方Developer Settings,
- 选择Personal access tokens下的Tokens (classic)
- 点击右方Generate a new token (classic)
输入密码后进入设置,在Note框中填写方便识别的名字,如
Deploy
,有效期(Expiration)建议选择永不过期(No expiration),访问范围(Scopes)我们需要选中repo和workflow点击生成后token即出现,注意它只会出现这唯一的一次,将其复制保存下来
得到token后,进入源仓库的Settings:
- 选择Secrets and variables下的Actions,在右侧选择New repository secret
- 在Name中填入
PERSONAL_TOKEN
- 在Secret中填入刚才生成的token,点击Add secret保存
3. 设置好Github Actions
接下来我们进入源仓库的Actions,若之前有使用过,点击左侧New workflow;若无,默认会给出许多推荐,我们任选一个开始configure即可:
- 重命名
.yml
为方便识别的名字,如deploy.yml
- 修改编辑框内容如下:
name: deploy # 这个 action 的名字 on: push: # 代表每次 push 都会 turn on action workflow_dispatch: # 代表我们也可以手动 turn on jobs: build: runs-on: ubuntu-latest steps: - name: checkout uses: actions/checkout@v2 with: submodules: true fetch-depth: 0 - name: setup uses: peaceiris/actions-hugo@v2.6.0 with: hugo-version: "latest" extended: true # 按需选择是否使用 hugo-extended - name: build run: hugo - name: deploy uses: peaceiris/actions-gh-pages@v3 with: PERSONAL_TOKEN: ${{ secrets.PERSONAL_TOKEN }} # 生成的 token 就用在这里,因为下面用到 external repository EXTERNAL_REPOSITORY: username/username.github.io # 修改为你的 Github Pages 仓库 PUBLISH_BRANCH: main # 以及对应的分支 main/master PUBLISH_DIR: ./public # 指定将自动部署得到的 public 文件夹 push 上去 commit_message: ${{ github.event.head_commit.message }}
若点击保存,则将自动完成第一次commit,注意提前备份原Github Pages仓库里的内容。(没备份也可以通过历史commit找到啦,哈哈)
汉字标准格式
汉字标准格式 「 是一套支援各种印刷效果的 」 Sass + JavaScript 排版框架 包含相邻文字装饰线跳脱 , 、 汉 ㄏㄢ ˋ 字 ㄗ ˋ 标 ㄅㄧㄠ 音 ㄧㄣ 着重号 、 标点符号修正 、 中文四大印刷体 、 汉字 、 - 西文mixed 间隙 、 标点 「 挤压 『 与 』 悬挂 『 章节边界调整 』 」 、 …… 높임법 / 경어법 / 존대법 / 대우법:韩语敬语梳理
tl;dr 小结
- 说的是谁?:主体敬语法(对其人的尊敬 + 对其动作的尊敬)
- 句中是否涉及第三人/各种所属物?:客体敬语法
- 对谁说?:对听者的尊敬与否:相对敬语法
- 主语和听者之间谁更“大”?:压尊法
- (主体如果是尊敬的人的所属事物:事物尊称)
“该尊敬谁?”“什么场合?”等因人而异的话题,本文不做过多讨论。
对句中主体/主语:주체(主體) 높임법
主要有三:
- 谓词:添加“-(으)시-”
- 以及需要换用的情况,如:(잠을) 자다→주무시다, 먹다→드시다, 주다→드리다, 있다→계시다(be; be located)
- 注意계시다只表示있다中“在”的意思,不表示“有”的意思,如:
- 선생님께서는 교실에 계시다.
- 선생님의 따님이 있으시다.
- 助词:主格助词께서(以及再附加“는”“도”等),与格助词께
- 人名/称呼:在之后添加“님”
对第三人/各种所属物:객체(客體) 높임법
- 对于第三人(即客体,此时他作为句子中的目的语(목적어)或副词语(부사어))
- 所跟的谓词需要换用
- 例如:데리다→모시다, 주다→드리다, 뵈다(보이다)/만나다→뵙다, 묻다→여쭈다→여쭙다(主要是这四个)
- 对于各种所属物
- 名词的换用
- 例如:밥→진지, 집→댁, 생일→생신, 나이→연세, 이름→성함, 딸→따님, 아들→아드님
不过,在说话人身份高于客体时,可选择性使用:
- 할아버지: 네 어머니를 데리고 시장에 가라.
- 할아버지: 네 어머니를 모시고 시장에 가라.
对听者:상대(相對) 높임법
关注划分的两大层次:
- 正式性(formality):格式体、非格式体
- 礼貌程度(politeness):尊敬阶、卑阶
两张表:1
对应的英文如下2:
주다, 드리다, 주시다 + 간접인용 명령문
tl;dr 小结
주다, 드리다, 주시다
在间接引语命令文(Quoted Imperative)中的变化
주다, 주시다, 드리다
A가/는 B에게/한테 N을 주다
- A给B某物
- 平辈之间
그는 생일 선물로 친구에게 책을 줬다.
A가/는 C께 N을 드리다
- A给C某物
- C为需要尊敬的人(下同),如长辈或陌生人,对“给长辈”使用敬语:께, 주다 -> 드리다,类似“献上”“奉上”
저는 생일 선물로 선생님께 책을 드렸다.
C께서 A에게/한테 N을 주시다
- C给A某物
- 对C“长辈给”使用敬语:주다 -> 주시다,类似“赐予”
선생님께서 생일 선물로 저에게 책을 주셨다.
例:V아/어/여 주다/드리다
以“帮助”(돕다)为例:
A为B做某事:
- A主动:
- A给予B帮助:A 도와 줄까?
- B接受A的给予:B 응, 도와 줘.
- B主动:(反写问答)
- B请求A的帮助:B 도와 줄래?
- A答应B,给予B帮助:A 응, 도와 줄게.
A为C做某事:
Windows 11 的新字体:Segoe UI Variable
微软在 2021 年 5 月 6 日于 Windows 10 Insider Preview Build 21376 发布了 Segoe UI 的可变字体版本:Segoe UI Variable,在 Windows 11 正式作为系统默认字体。得益于可变字体特性,Segoe UI Variable 可以根据不同的字重选择做出调整,在低分屏下也具有较高可读性。此次还同步推出了 Text 和 Display 两个版本,前者常用于内文,后者的装饰性元素或字体的风格更加突出,所以更常用于标题。Text 版本增加字重,x-字高更高,字母的开口以及间距更大。Display 版本字母尾部曲度更大,字间距对应缩紧,存在感更强。
风格上与旧 Segoe UI 相比,Segoe UI Variable 更圆,字母尾部增加曲度并切平,同时去掉了字母 I 和数字 1 的 crossbars,字母 Q 的小尾巴缩短改平直,整体更干练和紧凑,
看起来也更像 Product Sans 了。
可以通过 Windows 的官方文档,或直接访问此链接下载 Segoe UI Variable。
C++ 模版类重载流输入输出运算符
在 C++ 中只能通过友元函数来重载流输入输出运算符
<<
>>
。由于搭配模板类的使用,编译器可能在对应编译友元函数时无法确定其为模版,需要事先声明。方法 1:提前声明并使用 <> 确认
#include <iostream> using namespace std; //需要提前进行声明,以使类中对友元函数的声明进一步确认函数为模板函数 template <class A> class complex; template <class A> ostream & operator << (ostream &newout, const complex<A> &m); template <class A> class complex{ //以复数类为例 private: A real, image; public: complex(A a, A b):real(a),image(b){ } //在运算符 << 后加入 <> 以帮助编译器进一步确定该友元函数为模板函数 friend ostream & operator << <>(ostream &newout, const complex<A> &m); }; template <class A> ostream & operator << (ostream &newout, const complex<A> &m){ newout<<"("<<m.real<<","<<m.image<<")"; return newout; } int main(){ complex<int> a(1,2); cout<<a<<endl; return 0; }
方法 2:在声明友元函数的同时定义友元函数
#include <iostream> using namespace std; template <class A> class complex{ private: A real, image; public: complex(A a, A b):real(a),image(b){ } //在声明友元函数的同时定义友元函数 friend ostream & operator << (ostream &newout, const complex<A> &m){ newout<<"("<<m.real<<","<<m.image<<")"; return newout; } }; int main(){ complex<int> a(1,2); cout<<a<<endl; return 0; }
如果可以不使用友元函数
如果模板类中的成员为公有,则完全不需要在模板类中声明友元。
C++ 中的拷贝构造函数:浅拷贝、深拷贝
什么时候会调用拷贝构造函数
- 一个对象以值传递的方式传入函数体
- 一个对象以值传递的方式从函数返回
- 一个对象通过另一个对象以进行初始化
默认拷贝构造函数:浅拷贝
即:将被拷贝对象的数据成员的值一一赋值给新创建的对象
- 如果数据成员中有指针成员
- 浅拷贝只是增加了一个指针指向已经存在的内存
- 则新对象的指针所指向的地址与被拷贝对象的指针所指向的地址相同
- 则析构 delete 对象时会重复 delete 两次同一个内存空间而出错
实例
class Rect{ private: int *p; // 一指针成员 public: Rect(){ // 构造函数,p 指向堆中分配的一内存 p = new int(100); // new 动态分配 } ~Rect(){ // 析构函数,释放动态分配的内存 if(p != NULL){ delete p; // delete 释放 p 所指向的内存 } } }; int main(){ Rect rect1; Rect rect2(rect1); // 拷贝 rect1 来构造 rect2 // 也即: Rect rect2 = rect1; // 浅拷贝,将成员的值进行拷贝 rect2.p = rect1.p (地址 = 地址) // 会出现错误 // 在 delete 时既要 delete rect2.p 指向的空间,又要 delete rect1.p 指向的内存。但这是同一个内存(地址 = 地址),导致同一个内存被释放两次 return 0; }
同时还造成另外两个错误:
Winslow Homer 温斯洛·霍默
发布于 Matters.news。
首要的是,关注你自己最真实、直观冒出来的想法与情感。花上哪怕只是三五秒钟,先去观看和感受作品的本身。
Prout’s Neck, Breakers, 1883, Winslow Homer, Painting, watercolor on wove paper
Source: The Art Institute of Chicago
很偶然,从这幅画初次得知霍默大名,之后开始继续寻找他的画作,感叹于他融会贯通的技艺和想法。我其实不曾在阴天见过这样蓝的海浪,也许最接近画中景象的一次是在乔伊斯博物馆前的海角处。大概是被这种未曾见过的模样吸引着。
除了十分显然的深蓝、亮蓝叠加使用以塑造前后关系,还能看到他多利用了纸张本身的白色,例如下半部分近礁石的部分。这也是水彩常用的方法。整幅画也给我一种非常轻快的感觉,倒不是因为画面主体的海浪,而是它前侧用或大或小的色块柔和铺排开的、礁石上附着的细浪。
Paul Morphy, the Chess Champion, 1859, Winslow Homer, Print, wood engraving
Credit line: The Museum of Fine Arts, Houston, The Mavis P. and Mary Wilson Kelsey Collection of Winslow Homer Graphics
Source: Google Arts & Culture
温斯洛·霍默(Winslow Homer, 1836-1910)出生于波士顿,童年在剑桥长大,父母皆为新英格兰移民。父亲是典型的商人,而母亲有着画水彩的天赋异禀,顺理成章地成为霍默的“第一任老师”。19 岁高中毕业,父亲安排他去做广告平板印刷。就这样重复进行日常工作近两年后,他开始为一些杂志刊物制作插画,在当时那个年代也意味着就是木版画。霍默的线条感和对黑白分明的把握很好,不几笔就能把最鲜明的特点勾勒出来,如上图。
初探 Fluent Design System
微软在 Build 2017 Day Two 主旨演讲中正式宣布 Fluent Design System,即先前传言为 Project Neon 的设计语言。通用,可拓展,横跨多种设备,可以说微软这一设计语言就是为 Mixed Reality 的发展做好准备。该设计语言涵盖五种理念,分别是 Light, Depth, Motion, Material, Scale。
宣传视频
官方网页 (无法在以中文为界面语言的 Chrome 正常浏览)| 优酷 (来自 Livesino)
Light (光)
利用光线引导用户使用,增强现实感,使得目标和行动更加集中和准确。将光作为设计理念的一部分,或许是一种高出平面、回归自然的目的。实际应用中,设计人员需要充分考虑场景光线排布和导向性操作是否可行,需要基于用户心理的考察得出最终的设计。
Light has a way of drawing our attention. It’s warm and inviting; it’s fluid and purposeful. Light creates atmosphere and a sense of place, and it’s a practical tool to illuminate information.
引用部分是微软官方的定义。
光线引起人们注意,而其特点也正是温和友好、流畅、目的性明确。光能创造氛围更能营造范围,是阐述信息的实用工具。
Depth (深)
Material Design 为 UI 元素引入高度。高度将帮助用户了解每个元素的相对重要性,让他们能够集中于手边的工作,即引入了 Z 轴这一属性。Fluent Design System 中体现为 Depth,在微软尚未公布更多细节前,我们可以参考 Material Design 中相关的规范得出初步思考。