內容

名稱

Pod::Man - 將 POD 資料轉換為格式化的 *roff 輸入

語法

use Pod::Man;
my $parser = Pod::Man->new (release => $VERSION, section => 8);

# Read POD from STDIN and write to STDOUT.
$parser->parse_file (\*STDIN);

# Read POD from file.pod and write to file.1.
$parser->parse_from_file ('file.pod', 'file.1');

說明

Pod::Man 是個模組,用於將 POD 格式的文件(用於記錄 Perl 的首選語言)轉換為使用 man 巨集集的 *roff 輸入。產生的 *roff 程式碼適合使用 nroff(1)(通常透過 man(1))在終端機上顯示,或使用 troff(1) 列印。通常使用驅動程式腳本 pod2man 呼叫它,但也可以直接使用。

預設情況下(在非 EBCDIC 系統上),Pod::Man 會輸出 UTF-8。其輸出應該可以在使用 groff(大多數 Linux 發行版)或 mandoc(大多數 BSD 變體)的系統上與 man 程式搭配使用,但可能會在較舊的 UNIX 系統上產生混亂的輸出。若要在這些系統上選擇不同且可能更向後相容的輸出混亂,請將 encoding 選項設定為 roff(Pod::Man 早期版本中的預設值)。請參閱 encoding 選項和 "ENCODING" 以取得更多詳細資訊。

請參閱 "COMPATIBILTY" 以取得 Pod::Man 版本的重大向後不相容變更(建構函式選項除外,其版本已在下方說明),以及包含這些版本的 Perl 版本。

類別方法

new(ARGS)

建立新的 Pod::Man 物件。ARGS 應為一組鍵值對,其中鍵選自下列項目。每個選項都註解了 Pod::Man 加入該選項並具有其目前意義的版本。

center

[1.00] 設定 .TH 巨集的置中頁面標題。如果未指定此選項,預設值為 User Contributed Perl Documentation

date

[4.00] 設定 .TH 巨集的左腳註。如果未設定此選項,將會使用環境變數 POD_MAN_DATE 的內容(如果已設定)。如果失敗,將會使用 SOURCE_DATE_EPOCH 的值、輸入檔案的修改日期,或 stat() 無法找到該檔案時的目前時間(如果輸入來自 STDIN,就會發生這種情況)。如果從 POD_MAN_DATE 以外的任何來源取得(會逐字使用),日期將會以 YYYY-MM-DD 格式設定,並以 UTC 為基礎(因此輸出會在不論當地時區為何的情況下都能重製)。

encoding

[5.00] 指定輸出的編碼。值必須是 Encode 模組識別的編碼(請參閱 Encode::Supported),或特殊值 roffgroff。非 EBCDIC 系統上的預設值為 UTF-8。

如果輸出包含無法在此編碼中表示的字元,則會回報一個錯誤,而這個錯誤會依據 errors 選項的設定進行回報。如果錯誤處理方式不是 die,則無法表示的字元會被取代為編碼取代字元(通常是 ?)。

如果 encoding 選項設為特殊值 groff(EBCDIC 系統上的預設值),或者如果 Encode 模組不可用,而且編碼設為除了 roff 以外的任何值,Pod::Man 會將所有非 ASCII 字元轉換為 \[uNNNN] Unicode 逸出字元。這些逸出字元傳統上不屬於 *roff 語言的一部分,但受到 groffmandoc 支援,因此也受到當今大多數手冊頁處理器支援。

如果 encoding 選項設為特殊值 roff,Pod::Man 會執行其歷史轉換,將(部分)ISO 8859-1 字元轉換為 *roff 逸出字元,這些逸出字元在 troff 中可能足夠,而且在 nroff 中可能可讀(雖然很醜)。這是 5.00 之前的 Pod::Man 版本的預設行為。使用此編碼時,所有其他非 ASCII 字元都會被取代為 X。對於不支援 UTF-8 的非常舊的 troff 和 nroff 實作來說,這可能是必要的,但它對任何非 ASCII 字元的表示都很差,而且通常特定於歐洲語言。

如果輸出檔案控制代碼設定了 PerlIO 編碼層,則將 encoding 設為除了 groffroff 以外的任何值都會被忽略,而且 Pod::Man 也不會執行任何編碼。它會改為依賴編碼層來執行任何想要的輸出編碼轉換。

警告:POD 來源的輸入編碼與輸出編碼無關,而且設定此選項不會影響 POD 輸入的詮釋。除非您的 POD 來源是 US-ASCII,否則應該在來源中使用 =encoding 指令宣告其編碼。如果沒有這樣做,Pod::Simple 會嘗試猜測編碼,而且如果它是 Latin-1 或 UTF-8,則可能會成功,但它會產生警告。請參閱 perlpod(1) 以取得更多資訊。

errors

[2.27] 如何回報錯誤。die 表示對任何 POD 格式化錯誤擲回例外。stderr 表示在標準錯誤上回報錯誤,但不要擲回例外。pod 表示在產生的文件檔中包含一個 POD ERRORS 區段,摘要說明錯誤。none 盡可能完全忽略 POD 錯誤。

預設值是 pod

fixed

[1.00] 用於逐字文字和程式碼的等寬字型。預設值是 CW。有些系統偏好使用 CR。只會影響 troff 輸出。

fixedbold

[1.00] 固定寬度字型的粗體版本。預設為 CB。僅適用於 troff 輸出。

fixeditalic

[1.00] 固定寬度字型的斜體版本(有點名不符實,因為大多數固定寬度字型只有斜體版本,沒有斜斜體版本)。預設為 CI。僅適用於 troff 輸出。

fixedbolditalic

[1.00] 固定寬度字型的粗斜體(理論上,實際上可能是斜體)版本。Pod::Man 不假設您有這個,並預設為 CB。有些系統(例如 Solaris)將此字型設為 CX。僅適用於 troff 輸出。

guesswork

[5.00] 預設情況下,Pod::Man 根據猜測和正規表示式套用一些預設格式化規則,目的是讓撰寫 Perl 文件更容易,並需要較少的明確標記。這些規則可能並不總是適當的,特別是對於與 Perl 無關的文件。此選項允許關閉全部或部分規則。

特殊值 all 啟用所有猜測。出於向後相容性的原因,這也是預設值。特殊值 none 停用所有猜測。否則,此選項的值應為以下一個或多個關鍵字的逗號分隔清單

functions

將函式參照(例如 foo())轉換為粗體,即使它們沒有標記。函式名稱接受函式名稱的有效 Perl 字元(包括 :),並且尾隨括號必須存在且為空。

manref

將手冊頁面參照(例如 foo(1))的第一部分(括號之前)設為粗體,即使它們沒有標記。章節必須是一個數字,後面可以選擇性地加上小寫字母。

quoting

如果未啟用任何猜測,則 nroff(終端機)輸出中用 C<> 括起來的任何文字都會被雙引號包圍,除非內容已加引號。當啟用此猜測時,Perl 變數、函式名稱、函式呼叫、數字和十六進位常數的引號也會被抑制。

variables

將 Perl 變數名稱轉換為固定寬度字型,即使它們沒有標記。此轉換僅會在 troff 輸出或其他輸出格式(與 nroff 終端機輸出不同)中顯現,這些格式支援固定寬度字型。

任何未知的猜測名稱都會被靜默忽略(為了潛在的未來相容性),因此請小心拼寫。

language

[5.00] 加入命令告知 groff 輸入檔案使用指定的語言。此設定的值必須是語言縮寫,而 groff 會提供補充設定,例如 ja(日文)或 zh(中文)。

具體來說,這會加入

.mso <language>.tmac
.hla <language>

至檔案開頭,為指定的語言設定正確的斷行。如果沒有這些命令,如果手冊頁面安裝在一般的目錄中,例如 /usr/share/man,groff 可能不知道如何為中文和日文加入適當的斷行。

在許多系統上,如果手冊頁面安裝在特定語言的手冊頁面目錄中,例如 /usr/share/man/zh_CN,就會自動執行此動作。這種情況下,不需要此選項。

很不幸地,使用此選項加入的命令是特定於 groff,無法與其他 troffnroff 實作搭配使用。

lquote
rquote

[4.08] 設定用於包圍 C<> 文字的引號。lquote 設定左引號,rquote 設定右引號。兩者都可以設定為特殊值 none,這種情況下,不會在 C<> 文字的該側加入引號(但字型仍會變更為 troff 輸出)。

另請參閱 quotes 選項,可用於一次設定兩個引號。如果設定 quotes 和其中一個選項,lquoterquote 會覆寫 quotes

name

[4.08] 為 .TH 巨集設定手冊頁面的名稱。沒有此選項,手冊名稱會設定為轉換檔案的基本名稱的大寫,除非手冊章節為 3,這種情況下,會解析路徑,查看是否為 Perl 模組路徑。如果是,類似 .../lib/Pod/Man.pm 的路徑會轉換為類似 Pod::Man 的名稱。如果提供此選項,會覆寫任何自動確定的名稱。

如果從標準輸入產生手冊頁面,如果未提供此選項,名稱會設定為 STDIN。這種情況下,強烈建議提供此選項,以設定有意義的手冊頁面名稱。

nourls

[2.27] 一般來說,L<> 格式化代碼會使用 URL 但錨定文字會格式化為同時顯示錨定文字和 URL。換句話說

L<foo|http://example.com/>

會格式化為

foo <http://example.com/>

如果將此選項設定為 true 值,則會在提供錨定文字時隱藏 URL,因此此範例只會格式化為 foo。在 URL 不特別重要的情況下,這樣可以產生較不雜亂的輸出。

quotes

[4.00] 設定用於包圍 C<> 文字的引號。如果值為單一字元,則會用於左引號和右引號。否則,會將其一分為二,字串的前半部用於左引號,後半部用於右引號。

也可以將其設定為特殊值 none,這樣 C<> 文字周圍就不會加上引號(但字型仍會變更為 troff 輸出)。

另請參閱 lquoterquote 選項,可用於分別設定左引號和右引號。如果 quotes 和其他選項之一都已設定,則 lquoterquote 會覆寫 quotes

release

[1.00] 設定 .TH 巨集的置中頁尾。預設情況下,會設定為您在 Pod::Man 下執行 Perl 的版本。將其設定為空字串,會導致某些 *roff 實作使用系統預設值。

請注意,某些系統 an 巨集設定會假設置中頁尾會是修改日期,並會加上類似 上次修改: 的字串。如果是目標系統的情況,您可能想要將 release 設定為上次修改日期,並將 date 設定為版本號碼。

section

[1.00] 設定 .TH 巨集的章節。標準章節編號慣例是使用 1 表示使用者指令,2 表示系統呼叫,3 表示函式,4 表示裝置,5 表示檔案格式,6 表示遊戲,7 表示其他資訊,8 表示管理員指令。不過,這裡有許多變化;有些系統(例如 Solaris)會使用 4 表示檔案格式,5 表示其他資訊,7 表示裝置。其他系統則會使用 1m 取代 8,或兩者混合使用。唯一可靠一致的章節號碼大約是 1、2 和 3。

預設情況下,會使用章節 1,除非檔案以 .pm 結尾,否則會選取章節 3。

stderr

[2.19] 如果設定為 true 值,會將有關無效 POD 的錯誤訊息傳送至標準錯誤,而不是將 POD ERRORS 章節附加到產生的 *roff 輸出。如果尚未設定 errors,這等於將 errors 設定為 stderr

此選項適用於與不支援 errors 的 Pod::Man 版本的向後相容性。通常,應該改用 errors 選項。

utf8

[2.21] 此選項用於將輸出編碼設定為 UTF-8。由於這現在是預設值,因此會被忽略且不執行任何動作。

實體方法

作為 Pod::Simple 的衍生類別,Pod::Man 支援相同的方法和介面。有關所有詳細資料,請參閱 Pod::Simple。本節摘要最常使用的方法和 Pod::Man 新增的方法。

output_fh(FH)

將 parse_file()、parse_lines() 或 parse_string_document() 的輸出導向檔案處理常式 FH,而不是 STDOUT

output_string(REF)

將 parse_file()、parse_lines() 或 parse_string_document() 的輸出導向 REF 指向的純量變數,而不是 STDOUT。例如

my $man = Pod::Man->new();
my $output;
$man->output_string(\$output);
$man->parse_file('/some/input/file');

請注意,該變數中的輸出將已編碼為 UTF-8。

parse_file(PATH)

從 PATH 讀取 POD 來源並格式化。預設情況下,輸出會傳送至 STDOUT,但這可以使用 output_fh() 或 output_string() 方法變更。

parse_from_file(INPUT, OUTPUT)
parse_from_filehandle(FH, OUTPUT)

從 INPUT 讀取 POD 來源、格式化,並將結果輸出至 OUTPUT。

提供 parse_from_filehandle() 是為了與舊版 Pod::Man 相容。應改用 parse_from_file()。

parse_lines(LINES[, ...[, undef]])

將提供的行解析為 POD 來源,將輸出寫入 STDOUT 或使用 output_fh() 或 output_string() 方法設定的檔案處理常式。可以重複呼叫此方法以提供更多輸入行。應傳遞明確的 undef 以表示輸入結束。

此方法預期原始位元組,而不是已解碼字元。

parse_string_document(INPUT)

將提供的純量變數解析為 POD 來源,將輸出寫入 STDOUT 或使用 output_fh() 或 output_string() 方法設定的檔案處理常式。

此方法預期原始位元組,而不是已解碼字元。

編碼

自 Pod::Man 5.00 起,Pod::Man 的預設輸出編碼為 UTF-8。這應可在任何使用 groff(大多數 Linux 發行版)或 mandoc(Alpine Linux 和大多數 BSD 變體,包括 macOS)的現代系統上正確運作。

使用者可能必須使用 UTF-8 區域設定才能看到正確的輸出。這可能是預設的;如果不是,請將 LANG 或 LC_CTYPE 環境變數設定為適當的區域設定。如果想要在不變更其他區域設定影響的事項(例如排序)的情況下獲得正確的輸出,則大多數系統上都可用 C.UTF-8 區域設定。

Pod::Man 5.00 之前的版本中使用的向下相容輸出格式可透過將 encoding 選項設定為 roff 來取得。這可能會在不使用 groffmandoc 的舊版 UNIX 版本上產生稍微美觀的結果,但沒有任何可用的選項可以在這些系統上正確呈現 Unicode 字元。

以下是關於如何做出此選擇以及一些替代方案討論的額外詳細資訊。

歷史

Pod::Man 的預設輸出編碼一直是一個長期的問題。troffnroff 早於 Unicode 相當長一段時間,它們在許多 UNIX 系統上的實作反映了這項傳統。Unicode 通常不以任何形式獲得支援。

因此,Pod::Man 5.00 之前的版本維持了原始 pod2man 非常保守的輸出,該輸出會輸出純 ASCII,並使用複雜的巨集在使用 troff 處理時模擬常見的西歐重音字元。nroff 輸出很尷尬,有時不正確,且西歐文字中未使用的字元會被替換為 X。此選擇最大化了與 mannroff/troff 實作的向下相容性,但代價是許多 POD 文件的錯誤呈現,特別是包含人名的文件。

現代實作 groff(用於大多數 Linux 發行版)和 mandoc(用於大多數 BSD 變體)現在支援 Unicode。其他 UNIX 系統通常不支援,但它們現在是人們日常使用的系統中極少數。在 POD 文件中使用 Unicode 字元(而不是使用人名的 ASCII 轉換或避免非英文文字)變得越來越普遍(出於非常好的理由),這使得舊輸出格式中的限制更加明顯。

已提出四個選項來修正此問題

Pod::Man 5.00 及更新版本做出最後選擇。當手冊頁面以 troff 格式化為 PostScript 或 PDF 時,這可能會產生更差的輸出,但執行此操作的情況很少見,而且通常是手動的,因此可以在這些情況下變更編碼。舊的輸出編碼可透過將 encoding 設為 roff 來取得。

測試結果

以下是針對各種作業系統測試 encodingutf-8groff 的結果。測試方法是在目前目錄中建立 man/man1,將 encoding.utf8encoding.groff 從 podlators 5.00 發行版複製到 man/man1/encoding.1,然後執行

LANG=C.UTF-8 MANPATH=$(pwd)/man man 1 encoding

如果語言環境未明確設為包含 UTF-8 的語言環境,則 Unicode 字元通常會轉換為 ASCII(例如,刪除重音符號)或刪除,或在沒有轉換的情況下以 <?> 取代。

於 2022-09-25 進行測試。非常感謝 GCC 編譯農場專案提供存取測試主機。

OS                   UTF-8      groff
------------------   -------    -------
AIX 7.1              no [1]     no [2]
Alpine 3.15.0        yes        yes
CentOS 7.9           yes        yes
Debian 7             yes        yes
FreeBSD 13.0         yes        yes
NetBSD 9.2           yes        yes
OpenBSD 7.1          yes        yes
openSUSE Leap 15.4   yes        yes
Solaris 10           yes        no [2]
Solaris 11           no [3]     no [3]

我無法取得 macOS 系統進行測試,但由於它使用 mandoc,因此其行為可能與 BSD 主機相同。

備註

[1]

Unicode 字元會轉換為一或兩個與原始字元無關的隨機 ASCII 字元。

[2]

Unicode 字元顯示為 groff 逸出的主體,而非指示的字元(換句話說,類似 [u00EF] 的文字)。

[3]

Unicode 字元完全刪除,彷彿不存在。使用 nroff -man 代替 man 來格式化頁面會顯示與 Solaris 10 相同的結果。使用 groff -k -man -Tutf8 來格式化頁面會產生正確的輸出。

在 Debian 12 系統上使用 groff 的 PostScript 和 PDF 輸出不支援結合重音符號或 SMP 字元,因為預設輸出字型缺乏支援。

歡迎在其他平台上進行測試。如果您有其他結果,請告知作者。

診斷

roff 字型應為 1 或 2 個字元,而非 "%s"

(F) 您指定的 *roff 字型(使用 fixedfixedbold 等)不是一個或兩個字元。Pod::Man 不支援長度超過兩個字元的 *roff 字型,儘管某些 *roff 延伸模組支援(正規版本的 nrofftroff 也不支援)。

無效的錯誤設定 "%s"

(F) 建構函式的 errors 參數設定為未知值。

無效的引號規格 "%s"

(F) 給定的引號規格(建構函式的 quotes 選項)無效。引號規格必須是一個字元長或偶數(大於一個)字元長。

POD 文件有語法錯誤

(F) 要格式化的 POD 文件有語法錯誤,且 errors 選項設定為 die

環境

PERL_CORE

如果設定且 Encode 不可用,則靜默回退到 groff 編碼,而不會向標準錯誤抱怨。此環境變數會在 Perl 核心建置期間設定,Perl 核心建置會在 podlators 之後建置 Encode。預期在這種情況下 Encode(尚未)可用。

POD_MAN_DATE

如果設定,則會將其用作左腳註的值,除非明確設定 date 選項,覆寫輸入檔案的時間戳記或目前時間。這主要用於確保在給定相同來源和 Pod::Man 版本的情況下,即使檔案時間戳記可能不一致,也能產生相同輸出檔案的可複製建置。

SOURCE_DATE_EPOCH

如果設定,且未設定 POD_MAN_DATE 和 date 選項,這將用作原始檔案的修改時間,覆寫輸入檔案或當前時間的時間戳記。它應設定為自 UNIX 紀元以來的秒數。這主要用於確保在檔案時間戳記可能不一致的情況下,給定相同的原始碼和 Pod::Man 版本,可產生相同的輸出檔案。請參閱 https://reproducible-builds.org/specs/source-date-epoch/ 以取得完整規格。

(可以說,根據規格,此變數應僅在輸入檔案的時間戳記不可用且 Pod::Man 使用當前時間時才使用。然而,對於 Debian 中可重製的建置,如果此變數覆寫輸入檔案的時間戳記,結果會更可靠。)

相容性

Pod::Man 1.02(基於 Pod::Parser)是包含在 Perl 中的第一個版本,在 Perl 5.6.0 中。

基於 Pod::Simple 的當前 API 已新增至 Pod::Man 2.00。Pod::Man 2.04 包含在 Perl 5.9.3 中,這是第一個納入這些變更的 Perl 版本。這是第一個正確支援所有現代 POD 語法的版本。parse_from_filehandle() 方法已在 Pod::Man 2.09 中重新新增,以維持向後相容性,並包含在 Perl 5.9.4 中。

對 URL 類型的 L<> 連結中的錨定文字支援已新增至 Pod::Man 2.23,並包含在 Perl 5.11.5 中。

parse_lines()、parse_string_document() 和 parse_file() 設定預設輸出檔案處理為 STDOUT,如果尚未設定為 Pod::Man 2.28,則包含在 Perl 5.19.5 中。

對 SOURCE_DATE_EPOCH 和 POD_MAN_DATE 的支援已新增至 Pod::Man 4.00,並包含在 Perl 5.23.7 中,且已將產生的日期變更為使用 UTC,而非當地時區。這也是第一個將模組版本和 podlators 配布版本對齊的版本。從此點開始,podlators 中包含的所有模組,以及 podlators 配布本身,都共用相同的版本號碼。

Pod::Man 4.10 包含在 Perl 5.27.8 中,已將手冊頁面參考和函數名稱的格式變更為粗體,而非斜體,遵循目前的 Linux 手冊頁面標準。

Pod::Man 5.00 已將預設輸出編碼變更為 UTF-8,可使用新的 encoding 選項覆寫。它也修正了與 C<> 逸出字元一起使用時,粗體或斜體延伸太遠的問題,並開始將 Unicode 零寬度空白 (U+200B) 轉換為 \: *roff 逸出字元。它也放棄了在輸出中加入細微格式修正的嘗試,這些修正只有在使用 troff 排版時才可見,這以前一直是錯誤的主要來源。

BUGS

roff 編碼中,nroff 回退中存在許多錯誤和特定語言假設,用於重音字元。由於此編碼的重點是與 Pod::Man 較早版本輸出的向後相容性,而且除了支援舊系統時,否則已被棄用,因此這些錯誤不太可能被修復。

Pod::Man 無法處理長度超過兩個字元的字型名稱。大多數 troff 實作也無法處理,但 groff 可以作為擴充功能處理。對於想要使用此功能的人來說,支援此功能將會很好。

CAVEATS

句子間距

Pod::Man 會將輸入間距逐字複製到輸出 *roff 文件。這表示您的輸出將受到 nroff 一般處理句子間距的方式影響。

nroff 來自於一般在句子後使用兩個空格的時代,而且在重新整理文字時,總會在行尾句點(或類似標點符號)後加上兩個空格。例如,下列輸入

=pod

One sentence.
Another sentence.

在重新整理文字時,會在句點後產生兩個空格。如果您在句子後使用兩個空格,這將會一致,儘管您必須小心不要以縮寫字結尾,例如 e.g.Ms.。如果您使用 *roff 風格指南(以及 XKCD 1285)建議在每個句子後換行,輸出也會一致,儘管這會在每個句子後持續產生兩個空格,這可能不是您想要的。

如果您偏好句子後只有一個空格(這是較現代的風格),很遺憾,您需要確保段落中間沒有任何一行以句點或類似的句子結尾標點符號結尾。否則,nroff 在重新整理時會在該句子後加上兩個空格,而且您的輸出文件間距會不一致。

連字號

連字號與破折號的處理有些脆弱,而且在某些情況下可能會得到錯誤的結果。這通常只會影響換行,而且可能影響 troff 輸出。

作者

由 Russ Allbery <rra@cpan.org> 編寫,根據 Tom Christiansen <tchrist@mox.perl.com> 的原始 pod2man 編寫。

Sean Burke <sburke@cpan.org> 貢獻了使用 Pod::Simple 而非 Pod::Parser 的修改,但從那之後我已將它們修改得面目全非,所有錯誤都是我的。

版權和授權

版權所有 1999-2010、2012-2020、2022 Russ Allbery <rra@cpan.org>

Sean Burke <sburke@cpan.org> 做出了重大貢獻。

此程式為免費軟體;您可以在與 Perl 相同的條款下重新散布或修改它。

另請參閱

Encode::SupportedPod::Simpleperlpod(1)pod2man(1)nroff(1)troff(1)man(1)man(7)

Ossanna, Joseph F. 和 Brian W. Kernighan。「Troff 使用者手冊」,電腦科學技術報告第 54 號,AT&T 貝爾實驗室。這是標準 nrofftroff 的最佳文件。在撰寫本文時,它可以在 http://www.troff.org/54.pdf 取得。

文件頁面記錄 man 巨集集可能在您的系統上是 man(5) 而不是 man(7)

如果您以前沒有寫過 POD 手冊頁面,也不熟悉慣例,請參閱 perlpodstyle(1) 以取得相關文件。

此模組的目前版本隨時可在其網站 https://www.eyrie.org/~eagle/software/podlators/ 取得。它也是 Perl 核心分發的一部分,從 5.6.0 開始。