# 如何自行建構 Python 的官方文件,並將其內文字體大小調大 紀錄如何於 Docker 容器環境自行建構 Python 的官方文件以滿足文字大小客製需求 ![演示教學結果的畫面截圖,左半邊視窗顯示原版的文件右半邊視窗顯示客製過的文件,可以明顯看出客製過的文件的文字大小比較大可讀性較高](https://hackmd.io/_uploads/BJUoe-0RT.png "演示教學結果的畫面截圖,左半邊視窗顯示原版的文件右半邊視窗顯示客製過的文件") [TOC] ## <ruby>問題<rp>(</rp><rt>Problem</rt><rp>)</rp></ruby> * Python 官方文件的 PDF 版本在 reMarkable 電子紙平板電腦上呈現出來的內文字元大小偏小 * reMarkable 的 EPUB 支援有限,無法正常開啟/呈現部份電子書 ## <ruby>解決方案<rp>(</rp><rt>Solution</rt><rp>)</rp></ruby> 手動建構一個字型與版型客製過的 Python 說明文件,改進 Python 文件在 reMarkable 電子紙平板電腦上的閱覽體驗 ## <ruby>前備條件<rp>(</rp><rt>Prerequisites</rt><rp>)</rp></ruby> 以下說明完成本流程所需的前備條件: * 您須已安裝近期版本的 [Docker Engine](https://docs.docker.com/engine/) {容器執行環境|container runtime}以創建建構文件用的作業系統容器 * 您須可以訪問{網際網路|internet}以獲取建構文件所需要的軟體 * 您須有基本的 GNU+Linux 作業系統操作經驗,包含但不限於: + {絕對路徑|absolute path}與{相對路徑|relative path}的理解 + GNU Bash {殼層|shell}操作界面的使用 ## <ruby>重現環境<rp>(</rp><rt>Reproducing environment</rt><rp>)</rp></ruby> 以下說明確認可以重現本教學內容的具體環境細節: ### <ruby>主端<rp>(</rp><rt>host</rt><rp>)</rp></ruby>作業系統 Ubuntu 23.10 ### Docker Engine 24.0.5 ### 建構文件所使用的 Python 軟體來源碼 3.12.2 ## 取得 Python 來源程式碼<ruby>封存檔<rp>(</rp><rt>archive</rt><rp>)</rp></ruby> 1. 至 [Python 官方網站軟體下載頁](https://www.python.org/downloads/)選擇要下載的 Python 版本: ![於 Python 官方網站軟體下載頁選擇下載當前最新版本的操作示意畫面截圖](https://hackmd.io/_uploads/ByJDzbCAT.png "於 Python 官方網站軟體下載頁選擇下載當前最新版本") 1. 然後於頁面下方的 Files 區塊選擇任一作業系統欄位為「Source release」的軟體來源碼封存檔下載連結下載 Python 的軟體來源碼封存檔: ![Python 特定版本下載頁的軟體來源碼封存檔下載連結示意畫面截圖,紅框處的二個連結就是來源封存檔的下載連結](https://hackmd.io/_uploads/BJpPXWR0p.png "紅框處的二個連結就是來源封存檔的下載連結") 於本教學中我們選擇 XZ 壓縮方式的軟體來源碼封存檔進行下載,因為 XZ 壓縮演算法的壓縮率較好故下載檔案的所需時間較少。 ## <ruby>解開<rp>(</rp><rt>extract</rt><rp>)</rp></ruby> Python 來源程式碼封存檔 使用偏好的封存檔操作應用軟體將下載的軟體來源碼封存檔解開 :::info **備註:** 您另可使用 [GNU Tar](https://www.gnu.org/software/tar/) 這個{命令列界面|command-line interface}的封存檔操作工具進行封存檔的解開操作: ```bash cd /path/to/extraction/destination/dir tar_opts=( --extract --file=/path/to/python-3.12.2.tar.xz ) tar "${tar_opts[@]}" ``` ::: :::info **附註:** * `array=(...)` 為 Bash 的{索引式陣列|indexed array}語法,如上範例命令為例使用此語法可以以 Bash 註解的形式為命令參數新增說明文字 * `"${array[@]}"` 為 Bash 陣列的其中一種{參數展開|parameter expansion}語法,會將陣列中的元素以空白字元為分隔插入於展開處,您可以在展開命令前面加上 echo 命令(如 `echo "${array[@]}"`)以預覽展開結果 ::: ## 創建並啟動一建構文件用的 Docker <ruby>容器<rp>(</rp><rt>container</rt><rp>)</rp></ruby> 為了確保重現環境的{一致性|consistency},我們使用 Docker 創建一個{作業系統容器|operating system container}並在其內進行文件建構作業 1. [啟動一<ruby>文字終端機<rp>(</rp><rt>text terminal</rt><rp>)</rp></ruby>模擬器應用軟體](https://hackmd.io/@elrm-tw/how-to-launch-a-text-terminal-emulator-application) 1. _以 root 身份_ 執行下列命令創建並啟動一<ruby>拋棄式<rp>(</rp><rt>ephemeral</rt><rp>)</rp></ruby>的 Ubuntu 22.04 容器: ```bash python_source_dir=/path/to/Python-X.Y.Z docker_run_opts=( # 離開容器的作業階段時自動摧毀容器,節省磁碟空間使用 --rm # 啟用標準輸入裝置(stdin)支援(使 bash shell 得以互動式模式運行) --interactive # 啟用偽 Teletype(TTY) 終端機模擬功能(使 bash shell 得以互動式模式正常運行) --tty # 創建一 bind-mount 式儲存空間(volume),將主端的 Python 軟體來源碼封存檔解開目錄 # 掛載到容器中的 /project 目錄下 --mount "type=bind,source=${python_source_dir},destination=/project" ) docker run "${docker_run_opts[@]}" ubuntu:22.04 ``` :::info **附註:** * 如您的使用者為 `docker` 使用者群組的成員則可以以一般使用者身份運行前述 `docker run` 命令(允許使用者直接訪問 Docker 服務[有潛在的安全風險](https://docs.docker.com/engine/security/#docker-daemon-attack-surface),應**僅開放給完全信任的使用者**使用) * 如您位於僅能透過一 HTTP(S) 正向代理服務器才能連到網際網路的網路環境(如企業內部網路或是使用 [TetherFi](https://github.com/pyamsoft/tetherfi) 應用分享手機的行動網路給電腦),您可以在執行 `docker run` 命令前額外執行下列命令將本地的 HTTP(S) 正向代理服務設定(須已設定相關環境變數)繼承給 Docker 容器使用: + `docker_run_opts+=(--env http_proxy)` + `docker_run_opts+=(--env https_proxy)` + `docker_run_opts+=(--env no_proxy)` ::: ## 切換<ruby>作業目錄<rp>(</rp><rt>working directory</rt><rp>)</rp></ruby>至 Python 來源程式碼目錄樹中的說明文件目錄 執行下列命令切換作業目錄至 Python 來源程式碼目錄樹中的說明文件目錄 ```bash cd /project/Doc ``` ## 改用本地的 Ubuntu <ruby>軟體庫鏡像服務<rp>(</rp><rt>software repository mirror</rt><rp>)</rp></ruby> 操作方式參閱《[如何改用本地的軟體庫鏡像服務 | 大家的 Linux 團圓飯](https://hackmd.io/@elrm-tw/how-to-switch-to-use-local-software-repository-mirror)》教學文件 ## 更新<ruby>軟體包管理系統<rp>(</rp><rt>software package management system</rt><rp>)</rp></ruby>的本地<ruby>快取<rp>(</rp><rt>cache</rt><rp>)</rp></ruby>資料 操作方式參閱《[如何更新軟體包管理系統的本地快取資料 | 大家的 Linux 團圓飯](https://hackmd.io/@elrm-tw/how-to-refresh-package-manager-local-cache)》教學文件 ## 安裝創建 Python <ruby>虛擬環境<rp>(</rp><rt>virtual environment</rt><rp>)</rp></ruby>的<ruby>依賴軟體<rp>(</rp><rt>software dependencies</rt><rp>)</rp></ruby> 因為 [Python 官方文件的 README 說明文件(Python-X.Y.Z/Doc/README)](https://github.com/python/cpython/tree/v3.12.2/Doc) 建議使用 Python 虛擬環境進行文件建構,所以我們要先安裝其依賴軟體: * GNU Make {軟體建構自動化|build automation}工具 用於載入並執行建構 Python 說明文件用的 Makefile * Python 第三版執行環境 提供 Python 虛擬環境的執行環境 * Python `venv` 模組 提供虛擬環境建構支援 於 Ubuntu 22.04 作業系統中可以 _以 root 身份_ 執行下列命令進行安裝: ```bash pyvenv_dependency_pkgs=( make python3 python3-venv ) apt install "${pyvenv_dependency_pkgs[@]}" ``` ## 創建建構 Python 說明文件用的 Python 虛擬環境 執行下列命令以創建建構 Python 說明文件用的 Python 虛擬環境: ```bash make venv ``` ## 套用 Sphinx 配置修正:改用 US-Letter 紙張大小 Python 官方文件的 PDF 版本預設使用 A4 的紙張大小進行輸出,因 reMarkable 電子紙平板的螢幕解析度為 1872 x 1404,為 4:3 長寬比的螢幕,改用較接近 4:3 長寬比的 US-Letter 紙張大小較能夠避免頁面縮放貼合螢幕邊緣造成文字大小變小 編輯 conf.py Sphinx 配置檔,於「Options for LaTeX output」區域 `latex_elements` 字典的 `papersize` 鍵的值自 `a4` 修改為 `letter` ## 套用 Sphinx 配置修正:增加內文字體大小 編輯 conf.py Sphinx 配置檔,於「Options for LaTeX output」區域 `latex_elements` 字典的 `pointsize` 鍵的值自 `10pt` 修改為 `12pt` :::info **附註:** 這個設定似乎只支援以下三個數值: * 10pt * 11pt * 12pt ::: ## 建構 LaTeX 版本文件 執行下列命令建構 LaTeX 格式的文件: ```bash make latex ``` ## 安裝建構 PDF 文件的依賴軟體 ```bash pdf_build_dependency_pkgs=( # 提供 GNU Freefont 這個建構 PDF 文件需要的字型 fonts-freefont-otf latexmk texlive-xetex texlive-fonts-recommended xindy ) apt_install_opts=( # 不要安裝推薦安裝軟體包,避免非必要地下載太多實際上沒用到的軟體 --no-install-recommends ) apt install "${apt_install_opts[@]}" "${pdf_build_dependency_pkgs[@]}" ``` ## 自 LaTeX 版本文件建構 PDF 版本文件 切換作業目錄至 LaTeX 格式文件輸出目錄: ```bash cd build/latex ``` 然後執行下列命令建構 PDF 版本文件: ```bash make all-pdf ``` 順利的話建構好的 PDF 版本文件會存放於 build/latex 目錄中 ## <ruby>參考資料<rp>(</rp><rt>References</rt><rp>)</rp></ruby> 以下列舉撰寫文文件期間所參考的第三方資源: * [Download — Python 3.12.2 documentation](https://docs.python.org/3.12/download.html) Python 官方提供的說明文件下載頁 * [Volumes | Docker Docs](https://docs.docker.com/storage/volumes/) 說明 `docker run` 命令的 `--volume` 參數值的格式與用法 * [Make - GNU Project - Free Software Foundation](https://www.gnu.org/software/make/) 說明 GNU Make 軟體的軟體分類為何 * [Second-generation CANVAS display](https://support.remarkable.com/s/article/Second-generation-CANVAS-display) 說明 reMarkable 2 電子紙平板的螢幕特性 * [Compare A4 with US Letter | Compare Paper Sizes | Paper Sizes](https://papersizes.io/compare?c1=a&p1=a4&c2=us&p2=letter) 以圖形化方式呈現 A4 跟 US Letter 紙張大小規格的差異 * [Letter Paper Size](https://papersizes.net/us/letter) 說明 US Letter 紙張大小規格的由來與應用 * [LaTeX font error: I can't find file `pzdr` - TeX - LaTeX Stack Exchange](https://tex.stackexchange.com/questions/50596/latex-font-error-i-cant-find-file-pzdr) 說明建構 PDF 版本文件時報錯找不到 pzdr 檔案時的解決方法 * [GNU FreeFont](https://www.gnu.org/software/freefont/) 說明 GNU FreeFont 這個建構 PDF 版本文件時會用到的字型家族的基本資訊 <style> /* 調大旁註文字的字元大小 */ rt{ font-size: 10pt; } </style>