梅花雀莊

何震邦的個人網站,通常寫電腦和橋牌相關的文章,未來可能會寫關於日本麻將的東西

分類:電腦

polish.club 的花色配色

我的叫牌系統書都是用 mdBook 寫的。最近幾週先拿 polish.club 當試驗場,在版面上做了幾個小改動,改好再推到其他幾本。改動都繞著同一件事:♠♥♦♣ 四個花色符號要在每個主題、每個位置都看得清楚。整份 style.css 只有七十幾行,改動也都是幾行的事,但效果值得記一下。

下面這個 demo 把 mdBook 的五種主題和側欄、表格搬了過來,用的是同一份 CSS。切換主題,勾選「改動前」就能比較。

Natural 1♥

1♥ -
1♠F, 4+♠
1NTNAT NF, 0–3♠, 0–3♥
2♣!(R), FG, 0–3♥, 0–3♠
2♦!TRF, CONST+ 3+♥
2♥PRE, 3+♥
2♠!PRE, 6+♠

紅色依主題調整

原本 ♥♦ 寫死 #d33,淺色底還行,深色底就顯得暗沉。現在用一個 --red 變數,依主題給值:

  • Light 用 #b22,比原本深一點,對白底的對比較好。
  • Coal、Navy、Ayu 三個深色主題用 #f66,深底要亮紅才跳得出來。
  • Rust 是淺褐底,用 #a21。但 Rust 的側欄是深色的,側欄另外給 #f77。

mdBook 的主題靠 JavaScript 切換,沒有 JavaScript 時會照系統偏好退回 Light 或 Coal。所以多一條 @media (prefers-color-scheme: dark) 配 html:not(.js),讓沒腳本的深色模式也拿到亮紅。

側欄的黑花色

♠♣ 原本 color: var(--fg),用的是內文的前景色。在 Rust 主題下,內文 --fg 是深色,側欄背景也是深色,側欄裡的 ♠♣ 就幾乎看不見。 Demo 切到 Rust 再勾「改動前」,「Polish 1♣」和「Natural 1♠」的花色就消失了。

第一版修法是在側欄把 --fg 覆寫成 --sidebar-fg。能看見了,但滑鼠移到連結上、或是目前章節的連結變色時,花色不跟著變,一行字兩種顏色。最後改成側欄的 ♠♣ 直接 color: inherit,跟著連結走;♥♦ 則在 :hover、.active 時把 --red 設成 --sidebar-active。這樣整行連結連花色一起變色,而且不用動 mdBook 自己的變數。

表格

瀏覽器預設把表頭置中,叫牌表格的表頭是「1♥ -」這類叫牌序列,置中反而和下面的叫品對不齊,改成靠左。

叫牌記法也順手統一:叫品之間留空格,對手的叫品加括號,pass 用 -,每一輪用 <br> 分開。有個 fmt.py 幫忙對齊 Markdown 表格,只動兩欄的叫牌表,其他表格留給手排。

網址

檔名原本有 COMP_1、CB_Gladiator、BTUVU 這種縮寫加底線的組合,現在拼成 Competition、CheckbackGladiator、BTUvsUnusual。各開叫下的兩個競叫頁面也合併成一頁。舊網址都在 book.toml 裡設了轉址。

姊妹系統書

在 polish.club 上試好的 style.css,接著推到 Blueberry Precision、Watermelon Dutch、Muscat Walsh 和橋牌入門。沒有共用的 theme 套件,就寫了個 sync-css.sh,把 style.css 的 commit 用 git format-patch 丟給姊妹 repo git apply。作者頁也補上各系統的 favicon 連結。

萬年曆與八字命盤

最近做了兩個跟日期有關的小工具:日常・萬年曆和八字命盤。 都是繁體中文網頁,打開就能用,不用安裝或註冊,手機也可以操作。

日常・萬年曆

想知道某一天是農曆幾月幾日,或是今年的農曆生日落在西曆哪一天,可以用這個 萬年曆查詢。支援西元 1801–2100 年,月曆上並列西曆與農曆, 點選日期可以看干支年、生肖、節氣和節慶;「查詢換算」也能從農曆反查西曆,包含閏月。

除了日期,還並列清朝/民國紀年與日本年號,方便對照不同的紀年方式。 其中日本 1873 年以前的年號是西曆推算,沒有還原日本舊曆的年界與改元日。

二十四節氣另外有全年一覽,採用日本國立天文台的資料,以 UTC+8 顯示到分鐘。 月曆也收錄台灣常見節日與部分世界節慶,不過節慶不等於放假,這裡沒有計算補班補假。 選好日期後,複製網址就可以分享同一天。

八字命盤

八字命盤則是輸入出生日期、時間與性別,就能排出年、月、日、時四柱, 以及十神、藏干、納音、十二長生、空亡等資料。下方有格局、胎元、命宮、身宮, 也列出起運時間與各步大運,展開大運可以看流年,年齡以虛歲表示。

另外放了依日主排列的十神對照表和五行生剋圖,方便一邊看命盤,一邊對照彼此的關係。 格局依《子平真詮》的月令取格方式判定,目前只處理正格。

子時有兩種設定可以切換:「23:00 起算隔日」與「早晚子時」,後者在晚子時不換日柱。 輸入內容與設定也會保存在網址裡,可以收藏或分享同一張命盤。

兩個工具都固定使用台灣標準時間 UTC+8,支援 1801–2100 年,不還原歷史夏令時間; 八字排盤也不校正真太陽時。萬年曆的節氣時刻取自天文台表,八字則使用 lunar-javascript 的演算法,出生時間若恰好在節氣交接附近,排盤結果可能與其他曆書不同。

農曆換算與八字排盤使用的套件是 lunar-javascript,計算都在瀏覽器裡完成。 兩個專案的原始碼也都以 MIT 授權公開:calendar、bazi。 歡迎試用!

東方風格的圖示

將棋裡有個 ♣

將棋棋駒的圖樣由 peanatsu 製作,為 lishogi 上的 Western 樣式,採用 CC BY-SA 3.0 授權。

梅花字樣來自思源黑體 (Noto Sans TC)。

在 Linux 上使用 Nintendo Switch Pro 手把

今年發現用鍵鼠玩遊戲會導致機械鍵盤暫時接觸不良,於是 11 月初在朋友的推薦下就買了 Switch Pro 手把。按起來真的很很舒服,不過卻從此開啟了惡搞之路……。

首先,在 Linux < 5.16 並沒有 hid-nintendo 這個任天堂系列手把的驅動程式,所以 Steam 自幹了透過 hidraw 去抓手把的動作的驅動程式。所以如果插線接電腦然後打開 Steam,其實 Steam 可以抓到手把。然而最初我遇到的問題就是右蘑菇頭會一直亂飄,飄到我需要用 Steam 的手把校正功能把死區調大才解決。

圖:死區調到比預設值大才能讓它安靜……

然後到月底直接不演了,放在桌上都可以各種亂飄,並且產生莫名其妙的按鍵輸入。用 Gamepad Tester 一看才知道原來時脈被當成按鍵,然後被當成軸的意義不明,可能是陀螺儀吧。

hid-nintendo 核心模組

Daniel Ogorchock 大大寫的 hid-nintendo 終於要進 Linux 5.16 了。然而,我所使用的 Fedora 35 此時的核心版本仍然是 5.15.4。幸好我們可以利用 dkms-hid-nintendo 自行安裝。(-v 所接的版本可能會再更新,請到官網再確認。)

git clone https://github.com/nicman23/dkms-hid-nintendo
cd dkms-hid-nintendo

sudo dkms add .
sudo dkms build nintendo -v 3.2
sudo dkms install nintendo -v 3.2

安裝過後,一般的 Linux 程式和瀏覽器都能正確讀取 Switch Pro 手把的輸入。

joycond 常駐程式

然而 Steam 直至今日仍然不支援 hid-nintendo,所以我們還需要 Daniel Ogorchock 大大的 joycond 才能玩 Steam。它的原理是去模擬一個未知的任天堂手把,然後再讓 Steam 讀取這個虛擬的手把。

既然是不認識的手把,那就需要自己定義按鍵的定義了。我建議直接使用 Steam 預設的按鍵配置就好。雖然它看起來是 Xbox 或美版 PS 的配置,但是最後存檔的時候只要選擇它是 Switch Pro 手把,Steam 就能透過「使用 Nintendo 按鍵配置」(Use Nintendo Button Layout) 把 A/B 和 X/Y 調整回來。

圖:使用 Steam 預設的按鍵配置就好

然後因為 hid-nintendo 會過濾掉雜訊,所以死區也可以再縮小,讓手把的反應更敏捷。

圖:死區可以調小了

思源宋體來啦!

思源宋體真的來啦!

終於有字重齊全的宋體啦!不用再讓思源黑體 cosplay serif 字型啦!本來我還想要募資把王漢宗明體補完的說……。XD

我已經把字型檔整理起來,並且也附上轉換成更適合作為網路字型的 WOFF 檔。歡迎各位下載或以 @font-face 套用於網頁上。感謝 GitHub 願意成為大家的 CDN。

讓 nginx 重定向遵循 HTTP

根據 RFC 2616,除了 Location 標頭外,回覆實體(也就是一般使用者看到的網頁)裡面也需要包含重定向的目標。不過基於程式的健壯性原則,瀏覽器等 user agents 會選擇只看 Location,而且從網頁中找尋正確的連結對程式來說比較困難。然而,一般使用者還是有機會看到重定向的網頁,例如重定向失敗1的時候。

不過 nginx 的錯誤頁面(狀態碼 ≥ 300)其實都沒有附連結。以 302 重定向為例:

幸好 nginx 可以讓我們自訂錯誤頁面,並且支援 SSI。所以我就自己寫了重定向頁面。這樣就有符合 HTTP 標準的重定向頁面了。

該頁面已經搬家囉!
==================
它的新家在 <a href='<!--# echo var="sent_http_location" -->'><!--# echo var="sent_http_location" --></a>。
  1. 依規定 301, 302 重定向只接受 GET 和 HEAD,因此以其他請求方式就會停在回覆實體。 ↩

在 nginx 上調整所有文本的編碼

全站的文字檔都使用相同編碼是很常見的。尤其是 UTF-8 儼然是今日的實作標準。然而,nginx 預設的 charset_types 設定不包括 text/css,遑論其他非純文本。(例如 text/markdown)

預設的 charset_types 應該要是 text/* 才對,因為為了向後相容,許多 text/* 格式預設解讀為 ASCII (us-ascii)。就連 text/xml 也是如此,即使檔案中有 BOM 和 XML 宣告也徒勞無功。所以,現在我們應該用 application/xml 來傳遞 XML。

然而 charset_types 設定只檢查完全符合的 MIME,不然就必須用 * 匹配所有類型。幸好 nginx 有可以匹配正則表達式的 map,而且 charset_types 也接受變數。

map $sent_http_content_type $charset {
    ~^text/   utf-8;
}

charset       $charset;
charset_types *;

這樣的設定會讓 nginx 指定所有文本為 UTF-8,例如 text/css; charset=utf-8。

如何用嘸蝦米打出〇

嘸蝦米從〇到十都是一碼字。取 O 就可以打出〇了。

事情不是憨人想的這麼簡單。

實際在 Unicode 查碼網站查詢用嘸蝦米打出來的○其實是空心圓圈 (U+25CB WHITE CIRCLE) 而不是漢字〇(U+3007 IDEOGRAPHIC NUMBER ZERO)

為什麼會用錯誤的○代替漢字〇呢?這也不是嘸蝦米願意的。過去台灣使用的中文編碼是 Big5,當初 1970 年的溪頭會議就堅決把〇當成符號而不是字,因此也就只收錄符號○。在嘸蝦米輸入法設計的時候,Unicode 尚未興盛,當然就是收錄 Big5 中的○了。

直到 Unicode 興盛以後,嘸蝦米也從善如流把〇加入字根。然而為了向後相容,要打出〇必須選字。不過多數使用者,包括過去的我,仍然一直傻傻地把 ○ 當成中文的〇……。

把 ○ 當成〇有什麼影響

對機器來說 ○ 就只是個符號。這對於電腦翻譯是一大阻礙,更會干擾視障人士的輔助設備。視障輔助軟體把二○一七唸成二, white circle, 一七甚至二、十七都有可能,留下滿頭問號的使用者。

此外,對明眼人來說,把 ○ 當成〇也很醜。因為 ○ 是符號,所以字型的設計上會與漢字脫鉤,和漢字擺在一起就很不協調。而且文字加粗時,符號應該保持原狀。粗體的 ♠、斜體的 ♠ 看起來仍是 ♠。

錯誤版正確版
二○一七二〇一七
二○一七二〇一七
二○一七二〇一七
二○一七二〇一七
二○一七二〇一七
二○一七二〇一七

〇字的身世

〇是則天文字中的星。南宋算草中亦以圓圈符號代表 0,於是後來〇才假借為 0。雖然〇也可以算是符號,但是使用上與一、二、三等漢字無異,字型設計上應視為漢字。而且〇與表示正確、圈選的○的意義迥異,應該視為不同的字元。

智力測驗

本文所稱的臺灣包含臺灣本島、周圍外島以及澎湖群島。

中華民國之於臺灣就如同以色列之於巴勒斯坦。臺灣與巴勒斯坦在二戰前分別是日本和英國的殖民地,在戰後獲得解放,理應經由住民自決成立新政府或選舉決定併入現存國家。但在英美的主導下,巴勒斯坦被猶太人的以色列國管轄,而臺灣則是被中華民國管轄,並未經過住民的同意。

巴勒斯坦已經在 2012 年加入聯合國。希望有生之年能看見臺灣遲來的住民自決。

下載

本圖以 CC BY-SA 4.0 釋出。國旗都取自維基共享資源。

在 C++98 模擬 enum class

使用巢狀類別 (nested class) 可以達到類似的效果。因為我們不需要這些類別的實例 (instance),所以只需要宣告 (declaration),不需要定義 (definition)。

struct Color
{
    class Red;
    class Green;
    class Blue;
};

template<typename ColorType>
struct hex;

template<>
struct hex<Color::Red>
{ enum { value = 0xff0000 }; };

template<>
struct hex<Color::Green>
{ enum { value = 0x00ff00 }; };

template<>
struct hex<Color::Blue>
{ enum { value = 0x0000ff }; };

貼圖討論版開張

在同學的慫恿下,我架了貼圖討論版。源碼擺在 GitHub 讓全世界幫我備份。不過目前我提交的多已匯入 vichan 主線。請下載官方版以獲得其他人的本月貢獻。

[同學……等等,你不是唸醫學系嗎?先承認你就是你同學!] [阿就真的偶同學咩!]

技術細節

它採用 vichan,是一款高效能的貼圖討論版程式。它的特點是在伺服器上產生靜態的網頁、資源,因此能應付高流量。

目前中文化已進入 beta 階段,也就是已完成,但還可能有些 bugs。

而為了好好利用 nginx 的 gzip_static 模組,我在 inc/functions.php 加了一段程式碼,讓它在寫檔的時候順便產生 .gz 檔。

此外,為了在行動裝置上有較好的表現,我在內建佈景中設定 viewport。

Tinyboard/vichan 的特點

Tinayboard 給閱聽人跑的程式只有 post.php 一支,給職員的只有 mod.php 一支,其他都是靜態資源。他們只在閱聽人貼文及職員修改設定時重建 (rebuild) 網站⸺重新產生靜態網頁。職員在修改設定時,可能因為網站未重建,新設定尚未生效。職員可於 GET /mod.php?/rebuild 的頁面中重建網站,讓閱聽人看見更新的資源。

本站 QR code

jdh8.org

給 nginx 和 php-fpm 的 AppArmor 設定檔

AppArmor 是 Ubuntu 預設的 MAC 模組。不像傳統 Unix 的 DAC,AppArmor 設定檔列出什麼是行程該存取的。處於強制模式 (enforced) 的行程只能存取已列舉的路徑。處於抱怨模式 (complaining)

然而 nginx 和 php-fpm 沒有預設的設定檔。為了避免網頁伺服器遭駭造成系統性感染,自己的設定檔自己寫!我們有 aa-genprof 這個有用的工具完成大部份的工作,但是它還是會遺漏一些路徑,特別是 sockets。因此我把我的設定檔放上來作為他山之石。

以下是 nginx 的設定檔。

#include <tunables/global>

/usr/sbin/nginx {
	#include <abstractions/apache2-common>
	#include <abstractions/base>
	#include <abstractions/nis>

	capability dac_override,
	capability net_bind_service,
	capability setgid,
	capability setuid,

	/etc/nginx/** r,
	/etc/ssl/openssl.cnf r,
	/proc/*/auxv r,
	/run/nginx.pid rw,
	/run/nginx.pid.oldbin w,
	/run/php5-fpm.sock rw,
	/srv/www/** r,
	/usr/sbin/nginx mr,
	/var/log/nginx/* w,
}

以下是 php-fpm 的設定檔。

#include <tunables/global>

/usr/sbin/php5-fpm {
	#include <abstractions/base>
	#include <abstractions/nameservice>
	#include <abstractions/php5>

	capability kill,
	capability setgid,
	capability setuid,

	/etc/php5/** r,
	/proc/*/auxv r,
	/proc/sys/kernel/ngroups_max r,
	/run/mysqld/mysqld.sock rw,
	/run/php5-fpm.pid rw,
	/run/php5-fpm.sock w,
	/srv/www/** r,
	/srv/www/html/wp-content/** rw,
	/srv/www/html/wp-content/cache/** rwk,
	/srv/www/magento/media/** rw,
	/srv/www/magento/var/** rwk,
	/tmp/ r,
	/tmp/** rwk,
	/usr/sbin/php5-fpm mrix,
	/var/log/php5-fpm.log* w,
}

北醫 DNS 評測

為了自由,我在校內常常使用 GNU/Linux 的作業系統們上網。然而當我使用學校預設的 DNS 服務會發現有些網域名稱無法正常解析1。所以我希望能找到對校內來說最快的其他 DNS 服務。

於是我帶著我的筆電在校園內散步,假文青真宅男。結果評測失敗。在 2104 教室內 10.31.13.97 從 被封鎖至 ,在資訊處咖啡廳 10.1.1.73 從 被封鎖至 。一個 move 手動輸入 IP 位址繼續活命。

學網的防火牆給我以下的錯誤訊息。

UDP_IP

據網路管理系統記錄,您的電腦連續密集使用 UDP 連線多個不同 IP,疑似有 P2P 之行為。

解決方法:
請停止使用 P2P 之不當行為。

  1. 你™ 不知道 53/udp 是什麼埠嗎?
  2. 你™ 不覺得UDP → P2P → BitTorrent → 盜版很滑坡嗎?

既然一般用戶會受到控管,伺服器總不會了吧?所以後來我改在 civics.tmu.edu.tw 上評測,結果讓我嚇了一大跳!最快的居然是 Google 的 8.8.8.8,比校內的都快。

  1. 此問題在一、兩年後好像就修好了。 ↩