可獨立使用的函式庫
全部採用 Apache-2.0 授權,都在 Publira 中實際使用,使用其中任何一個都不必引入整個平台。
@publira/comic-viewer
Publira 章節閱讀畫面所用的 React 漫畫閱讀器,已獨立出來,UI 和資料管線完全由你掌控。
- Headless UI 架構:組合彼此獨立、支援 tree-shaking 的元件,樣式全部由你自己定義。
- 響應式跨頁,依容器寬度在單頁和雙頁之間切換。
- 採用虛擬化,即使載入大量高解析度頁面,行動瀏覽器也不會崩潰。
- 可插拔的資料管線:透過 definePlugin() 注入擷取、解密或分析處理。
- 日式漫畫預設由右向左閱讀,歐美漫畫可設為由左向右,內建滑動、點擊和鍵盤翻頁。
- 透過 resolvePage() 延遲載入頁面中繼資料,適用於長文件和會過期的簽章 URL。
尚未發布 1.0:在 0.x 系列中,修補版本會盡量保持相容,次要版本則可能變更公開 API。升級前請閱讀變更記錄。
閱讀文件npm install @publira/comic-viewer
import * as ComicViewer from "@publira/comic-viewer";
import "@publira/comic-viewer/core.css";
export function Reader({ pages }: ReaderProps) {
return (
<ComicViewer.Root
initialReadingDirection="rtl"
pages={pages}
>
<ComicViewer.Viewport />
<ComicViewer.Toolbar />
<ComicViewer.PageNavigation />
</ComicViewer.Root>
);
}
publira/epub
用於解碼、編碼與驗證 EPUB 3 的 Go 函式庫,專為不在磁碟上讀寫檔案的伺服器設計。
- 不依賴檔案系統:Decode 只需要一個 io.ReaderAt 和封存檔大小。
- 快速失敗:遇到結構錯誤時立即傳回 DecodeError。
- 記憶體使用效率高,可透過 Asset.Open 依需求以串流方式讀取。
- 嚴格驗證 EBPAJ 和 KADOKAWA 風格的命名與目錄規則。
- 固定版面的圖片頁面以 SVG 包裹,在任何閱讀系統中都能讓頁面維持符合畫面的大小。
- 為封面、目錄、正文、索引和詞彙表等 landmark 賦予結構語意。
產生的出版品可以透過儲存庫附帶的指令碼,以 W3C 官方的 EPUBCheck 檢查,該工具會快取在 .tools/ 下。
閱讀文件go get github.com/publira/epub
f, err := os.Open("book.epub")
if err != nil {
log.Fatal(err)
}
defer f.Close()
st, err := f.Stat()
if err != nil {
log.Fatal(err)
}
opt := epub.WithCompliance(epub.LevelEBPAJ)
doc, err := epub.Decode(f, st.Size(), opt)
if err != nil {
log.Fatal(err)
}
if err := epub.Encode(out, doc); err != nil {
log.Fatal(err)
}
publira/messageformat-dart
符合 LDML 48.2 的 Unicode MessageFormat 2.0 純 Dart 實作,用於格式化行動用戶端的訊息。
- 純 Dart 實作,不依賴 Flutter,在伺服器、命令列和 Flutter 應用程式中都能執行。
- 通過 MessageFormat 工作小組一致性測試套件 (LDML48.2) 的全部 461 個案例,沒有略過任何一個,並在 CI 中隨每次變更執行。
- 支援規範中標為 Stable 的所有函式 (:string, :number, :integer, :offset, :currency, :percent),可依所有 CLDR 地區設定格式化數字。
- 處於 Draft 階段的日期和時間函式放在 messageformat_datetime 中,不格式化日期的應用程式不必打包其 CLDR 資料。
- formatToParts 傳回 sealed 類別階層的片段,可用於產生帶樣式的文字等輸出。
- 格式化出錯時不會擲出例外,而是將錯誤回報給回呼並使用備用值;除了預設函式,也可以註冊自訂函式。
尚未發布 1.0。遵循 LDML 48.2 (UTS #35 Part 9, tr35-78) 與 Unicode CLDR 48.2 資料,升級到更新版本的規範時會作為單獨的版本發布。
閱讀文件dart pub add messageformat
import 'package:messageformat/messageformat.dart';
final mf = MessageFormat(
'en',
r'''
.input {$count :number}
.match $count
0 {{No episodes}}
one {{{$count} episode}}
* {{{$count} episodes}}
''',
options: const MessageFormatOptions(
bidiIsolation: BidiIsolation.none,
),
);
mf.format({'count': 0});
mf.format({'count': 1});
mf.format({'count': 1000});