桌面應用程式 · Electron

ㄐㄧㄢ

寫公文時,幫你看格式與用語對不對。

依《行政院文書處理手冊》檢查稱謂語、期望語與分項標號。 完全離線、不使用 AI,以「零誤報」為最高設計原則。

Electron 32 Three.js 10 種文別 138 項測試
文箋的首頁:軟體圖示、新增公文與最近草稿清單

01 — 動機與目標

不是不會寫,是不知道該怎麼講

我知道我要跟教育局申請經費,也知道公文有主旨、說明、辦法。
但我不知道該用「鈞局」還是「貴局」, 也不知道主旨結尾要寫「請查照」還是「請鑒核」。

卡住的地方不在內容,在格式跟用語。 而這件事有個很重要的特性:

公文用語就那幾十個。

稱謂語、期望語都寫在《文書處理手冊》裡,數量是固定的。 不用自己想,查就有,而且查到的一定對

ㄐㄧㄢ

wén jiān

,本義是小幅而精美的紙。信箋、便箋、花箋, 都是拿來寫字的紙。後來也指書信,或是為古書作的註解, 像鄭玄的《毛詩箋》。

取這個名字,是因為工具做的事就是「在紙上把字寫對」。 這裡沒有 AI 會擅自改你的意思,只做一件事: 把你寫的內容,用對的格式跟用詞擺到對的位置。

目標

  • 每一則提示都能追溯到手冊條次
  • 完全離線,草稿不離開這台電腦
  • 使用者用過幾次就能自己記住規則

刻意不做

  • 不產生公文內容,不替使用者決定寫什麼
  • 不判斷法規適用或行文關係之實質認定
  • 不處理機密文書,不發文、不核章

02 — 功能介紹

先確定關係,才知道用哪個字

手冊十八、(三) 規定稱謂語完全取決於行文關係。 這是全工具的地基,也是新手最常錯的地方。

有隸屬的上級 鈞局、鈞部
無隸屬的上級 大部、大院
平行機關 貴校、貴園
下級機關 貴局、貴校

市立國中行文教育部(無隸屬)用「大部」; 行文所屬教育局(有隸屬)用「鈞局」。用錯不只是格式問題,是失禮。

動手試試

改改看下面這句話,檢查結果會即時更新。

節選 5 條規則完整版 18 條
載入範例:

此處執行的是與軟體相同的規則邏輯,非另外撰寫的簡化版。

10

種文別

函、簽、公告、令、書函、開會通知單、公務電話紀錄、箋函、呈、咨。 僅收錄手冊明定結構或附有作法舉例者。

17

種事由範本

選一個接近的情況,架構直接帶進去,剩下把〔方括號〕換成自己的內容就好。

3

種提示強度

不符規定、建議、請確認。要看語意才知道的,工具不下判斷,只把兩種用法擺出來讓你自己選。

行文關係選擇畫面:以具體例子取代術語
不要求使用者理解「上行文」,改以具體例子提問
填寫畫面:左側表單,右側 A4 即時預覽
左側填寫,右側 A4 預覽即時更新
檢查結果畫面:三種強度的提示並列
每則提示可展開「為什麼?」查看白話說明

03 — 系統架構

規則是資料,不是程式碼

10 種文別共用同一套引擎,而非 10 套邏輯。新增文別只需加資料。

資料層(JSON) 10 種文別定義 行文關係與詞庫 17 種事由範本 統一用字表 規則引擎 18 條檢查規則 純函式 · 無 DOM 依賴 介面層 動態表單 提示面板 A4 即時預覽 測試(node:test) 手冊 11 份官方範例 讀取 檢查結果 直接呼叫 不需啟動瀏覽器
引擎與 DOM 完全分離,因此 75 項單元測試可在無瀏覽器環境下直接驗證規則, 並以手冊自己的範例作為零誤報的判準。

為什麼引擎要與 DOM 分離

要證明沒有誤報,就必須能測。引擎如果綁著畫面,每次測都得開瀏覽器,慢又不穩。拆開之後,測試直接呼叫同一個函式: check(draft, docType, relationId) 輸入純資料、輸出純資料、無副作用。

為什麼規則要寫成資料

10 種文別如果各寫一套邏輯,之後改一個地方要動十次。 文別定義、詞庫、檢查規則全部寫成 JSON,程式只負責跑。要加新文別的話,加資料就好,不用動到程式。

04 — 使用的 Package

全部本機打包,執行期不連網

原型版本以 CDN 載入 docx 與 Three.js,與「單一 exe 離線可用」的目標直接衝突, 故全數改為本機打包。

Electron 32.3.3

桌面應用程式框架。原型的網頁程式碼可直接沿用,開發速度優先於體積。

Three.js 0.160

背景的書齋場景:箋紙、竹簡、硯台、印章、落墨。萬一載入失敗會自動換成靜態紙紋,不影響主要功能。

docx 8.5

產出可以再編輯的 Word 初稿。10 種文別的版面不一樣,分成標準公文、書信體、定型化表單三種。

Noto Serif / Sans TC SIL OFL

打包了 27.5 MB 的中文字型。不打包的話 Windows 會退回新細明體,換一台電腦看起來就不一樣了。

electron-builder 25.1

產出單一可攜式 exe(83 MB),免安裝、可自隨身碟執行。

語言模型 未使用

刻意不採用。理由見下一節。

05 — 目前成果

四個「可以做,但選擇不做」的決定

這個專案我覺得最值得講的,不是做了哪些功能,而是想清楚哪些不該做。

不使用 AI

公文用語數量固定,查表就有答案,而且不會錯。

語言模型會編出看起來很像、但實際上不存在的法規條號。使用者本來就不熟公文,根本沒辦法判斷 AI 講的對不對。這種情況下,可靠比聰明重要。

放棄一項手冊明文檢查

「第線上」用中文、「第 1 優先」用阿拉伯,可是字面長得一樣。

程式看不出哪個是描述性用語,硬做一定會誤判。改成可以查的對照表。做不準的檢查,比不做還糟。

11 種文別不收錄

報告、聘書、契約書這些,手冊只寫什麼時候用,沒寫格式長怎樣。

硬要做只能自己編一套,然後說它是標準。這跟「每條規則都查得到出處」的原則衝突。所以在介面上直接寫明為什麼沒有,而不是假裝沒這回事。

挪抬不列為錯誤

網路上都說稱謂語前面要空一格,但手冊翻遍了沒這條。

查不到就說查不到。工具不會為了看起來完整,就自己生一條規定出來。

138測試項目
11手冊官方範例
0誤報

拿《文書處理手冊》附錄 6 的 11 份官方範例當測資。手冊自己的例子一定符合手冊規定,所以引擎只要對它報錯,那就是誤報。

第一次跑測試,引擎就誤判了手冊自己的範例三次。這個測試的價值就在這裡。

單元測試75
冒煙測試27
加密測試14
離線驗證13
字型驗證9

三種驗證方式,各有不可取代的涵蓋範圍

開發中修正 15 項缺陷,依發現方式分類:

  • 單元測試:期望語比對順序、稱謂語誤判成語
  • 截圖檢視:輸入時表單被重建、一進頁面滿畫面紅字
  • 使用者實測:視窗關不掉、PDF 像螢幕截圖

測試全綠不等於軟體可用

beforeunload + preventDefault() 在瀏覽器會跳確認框, 在 Electron 中只會取消關閉且不顯示任何提示——使用者完全關不掉視窗

這需要真的去按那個 X 才會發現。

06 — Reference

參考資料

  • 行政院《文書處理手冊》 104 年 7 月版。本工具全部格式規則之依據,每則提示均標註條次。
  • 手冊附錄 2 · 法律統一用字表 立法院第 51、78 會期認可。用於統一用字檢查。
  • 手冊附錄 5 · 公文書橫式書寫數字使用原則 實作為查詢對照表,不做自動檢查(理由見「目前成果」)。
  • 手冊附錄 6 · 公文作法舉例 11 份官方公文範例,作為零誤報測試的測資。
  • Noto Serif TC / Noto Sans TC SIL Open Font License 1.1,允許嵌入與散布。