在 LaTeX 中,人們經常使用元數據,最常見的是:
- \標題
- \作者
- \日期
- \地址
其中大多數在沒有有效性檢查的情況下使用。
是否有一個套件允許定義其他元資料條目並使用文件中的值,並可能定義測試並檢查條目的值?
看起來這樣的套件對於擴展元資料的使用非常有用,允許定義資料的層次結構,並且最重要的是允許測試。
答案1
正如評論中提到的,這個問題相當不明確。然而,為元資料編寫某種「測試套件」相對容易。命令\title
等\author
將它們的參數寫入內部巨集等\@title
。\@author
雖然這絕不是執行此類檢查的最佳或最簡單的方法,但它可以作為概念證明。
但請注意,在一般情況下,這些欄位中應該允許大多數輸入。對於下面的玩具範例,我定義了一些規則,但他們每個人都很容易想像打破規則是合理的情況。我認為這不是我的玩具規則的限制,因為你可以想出的任何規則都有例外。
現在來看程式碼。首先,它定義了\address
與 類似的命令\title
(即,將參數儲存在 中\@address
),因為該命令在類別中預設未定義article
。
然後它設定一些在檢查期間顯示的訊息。然後,內部巨集被複製到標記清單中並用作正規表示式的輸入。
程式碼的其餘部分是一般管理內容:由於某種原因\regex_match
不接受令牌列表多變的但直接只是一個 token 列表,所以需要建立一個變體。我嘗試將包代碼和用戶命令分開,並將所有內容都放在一個.sty
文件中。
文件metadatacheck.sty
:
\ProvidesPackage{metadatacheck}[2024/01/07 v0.1 Regex Check on Metadata]
\newcommand{\address}[1]{\gdef\@address{#1}}
\ExplSyntaxOn
\prg_generate_conditional_variant:Nnn \regex_match:nn {nV} {T,F,TF}
\msg_new:nnnn{metadatacheck}{titleok}{Title~check~OK}{}
\msg_new:nnnn{metadatacheck}{authorok}{Author~check~OK}{}
\msg_new:nnnn{metadatacheck}{dateok}{Date~check~OK}{}
\msg_new:nnnn{metadatacheck}{addressok}{Address~check~OK}{}
\msg_new:nnnn{metadatacheck}{titleerr}{Title~does~not~start~with~upper~case}{}
\msg_new:nnnn{metadatacheck}{authorerr}{Author~cannot~have~numbers}{}
\msg_new:nnnn{metadatacheck}{dateerr}{Date~does~not~include~4-digit~year}{}
\msg_new:nnnn{metadatacheck}{addresserr}{Address~too~short~(5~characters~minimum)}{}
\cs_new:Nn \check_meta_data: {
\tl_set:Nx \l_title_tl {\@title}
\tl_set:Nx \l_author_tl {\@author}
\tl_set:Nx \l_date_tl {\@date}
\tl_set:Nx \l_address_tl {\@address}
\regex_match:nVTF{\A[A-Z]}{\l_title_tl}{\msg_note:nn{metadatacheck}{titleok}}{\msg_warning:nn{metadatacheck}{titleerr}}
\regex_match:nVTF{\A[^0-9]+\Z}{\l_author_tl}{\msg_note:nn{metadatacheck}{authorok}}{\msg_warning:nn{metadatacheck}{authorerr}}
\regex_match:nVTF{\d{4}}{\l_date_tl}{\msg_note:nn{metadatacheck}{dateok}}{\msg_warning:nn{metadatacheck}{dateerr}}
\regex_match:nVTF{.{5}}{\l_address_tl}{\msg_note:nn{metadatacheck}{addressok}}{\msg_warning:nn{metadatacheck}{addresserr}}
}
\NewDocumentCommand{\CheckMetaData}{ }
{
\check_meta_data:
}
\ExplSyntaxOff
使用者文件:
\documentclass{article}
\usepackage{metadatacheck}
\title{my Title}
\author{Alic3 Sm1th}
\date{Christmas '23}
\address{23 Mulholland Drive}
\CheckMetaData
\begin{document}
\maketitle
\end{document}
結果(在終端機和日誌檔案中):
Package metadatacheck Warning: Title does not start with upper case
Package metadatacheck Warning: Author cannot have numbers
Package metadatacheck Warning: Date does not include 4-digit year
Package metadatacheck Info: Address check OK
當然,這可以透過允許使用者透過文件命令或設定檔提供正規表示式和訊息來進一步擴展。
答案2
目前 ctan 上至少有一個由 Scott Pakin 開發的軟體包https://ctan.org/pkg/hyperxmp?lang=en 超XMP可以按照OP的要求進行操作,如果需要擴展它,這將是一個很好的起點。
評論中建議在完成任何開發工作之前先編寫規格。我還提供了 adobe 規範的鏈接,我認為這是一個很好的例子。在許多情況下,只需使用枚舉清單和表格即可。我認為最重要的部分是該計劃的範圍。在這個問題的背景下,它必須回答,考慮到元資料是不同程式之間交換資訊的接口,預計什麼軟體可以讀取這些資訊。一旦編寫了規範,就可以開發驗證功能。如有必要,應注意涵蓋不同的書寫系統和編碼。
符合 LaTeX 套件要求的日期資料驗證範例可以在使用 l3 程式層編寫的 l3doc 清單中找到。 l3 程式設計雜技的奇蹟!
需要注意的是,網頁開發經歷了類似的發展階段,但是隨著搜尋變得更好,這樣的本體論並沒有真正流行起來,現在有了法學碩士,它們可能會一起消失,但這只是我的觀點,並不意味著讓你洩氣。
答案3
這並不完全是答案,而是 Ulrike Fischer 在上面的評論中詢問的規格。它仍處於雛形,我們將對其進行相應的編輯。
包元資料將定義並允許元資料條目的使用和驗證。
若要定義新的條目,請使用:
\definemetadataentry[type=
format=yyyy-mm-dd,
lower_range=0001-01-01,
upper_range=9999-12-31,
finite_range=,
default_value=,
optional/required,
validation_routine=,
hierarchy=
]{name_of_metadata_entry}
在哪裡:
(資料)類型:
可:
- 數字(整數或小數)
- 字串
- 約會時間
格式:
提供剛剛定義的資料類型的格式。
lower_range=0001-01-01:
upper_range=9999-12-31:
定義連續或太長而無法完整列出的資料的下限和上限範圍。
日期集範圍範例:0001-01-01 到 9999-12-31
有限範圍:
定義可以輕鬆完整列出的資料範圍。
預設值:
元資料條目預設的值(如果未定義)。
可選/必需:
定義特定元資料條目在定義它的領域內是必需的還是可選的。
驗證例程(外部):
呼叫驗證條目的外部例程。
等級制度:
根據另一個先前定義的元資料條目遞歸定義的元素。
定義和使用範例
資料類型:
有 3 種類型的數據需要考慮:
- 數字(整數或小數)
- 字串
- 約會時間
日期格式:
日期: 格式:YYYY-MM-DD 日期時間: 格式:YYYY-MM-DD HH:MI:SS
日期格式可以是不同類型,例如:「dd-mm-yyyy」、「yyyy-mm-dd」、「mm-dd-yyyy」。
提及 10 種最常用的格式,包括短世紀 (yy) 和長世紀 (yyyy)。
- 美國:月/日/年及月/日/年
- ANSI:年.月.日 & yyyy.月.日
- 英國/法國:dd/mm/yy 和 dd/mm/yyyy
- 德語:dd.mm.yy 和 dd.mm.yyyy
- 日本:年/月/日及年/月/日
- ISO:年月日、年月日
- 歐洲預設值 + 毫秒:dd mon yyyy hh:mi:ss:mmm (24h)
- 回曆:日/月/年 時:分:秒:mmmAM
RequirePackage{metadata}
\definemetadataentry[type=DATETIME,
format=yyyy-mm-dd,
lower_range=0001-01-01,
upper_range=9999-12-31
default_value=2000-12-31,
optional,
validation_routine=/usr/local/texlive2024/bin/abc.lua,
]{date_of_publication}
\definemetadataentry[type=DECIMAL,
fomat=(8,6),
]{latitude}
\definemetadataentry[type=DECIMAL,
format=(9,6),
]{llongitude}
\definemetadataentry[type=CHARACTERSTRING]{email}
\definemetadataentry[type=CHARACTERSTRING]{url}
\definemetadataentry[type=NUMERIC,
format=integer,
lower-range=1,
upper-range=9999,
]{volume_number}
\definemetadataentry[type=CHARACTERSTRING(2),
range={US,MX,CA,GT,HT,CU,HN,...},
]{north_american_country}
元資料的層次結構。
\definemetadataentry[type=CHARACTERSTRING(2),
required,
]{country}
\definemetadataentry[type=CHARACTERSTRING(10),
hierarchy=country,
]{zipcode}
使用範例:
\zipcode[BR]{22430-085}
\zipcode[US]{91106-3840}
\zipcode[CA]{K1A 0T6}
\zipcode[DE]{13057}
\zipcode[IR]{81599-95950}
\definemetadataentry[type=CHARACTERSTRING(2),
required,
]{decade}
\definemetadataentry[type=CHARACTERSTRING(10),
hierarchy=decade,
]{msc}
使用範例:
\msc[2010]{76B75}
\msc[2020]{76D55}
\definemetadataentry[type=CHARACTERSTRING(100),
required,
]{full_name}
\definemetadataentry[type=CHARACTERSTRING(30),
hierarchy=full_name,
]{last_name}
使用範例:
\full_name{John Ewing}
\last_name{Ewing}