Latex 應該也算是一種程式語言 吧
前言
Latex 是一個有趣的程式語言,透過它能夠產生對應的 pdf 文件,這對於文件撰寫有很大幫助 (例如可以輕易被版本控制)。然而實際在使用時會遇到不少問題,其編譯錯誤的訊息也很難去直接聯想到錯誤位置,比方說某些字元 (_
, &
) 不能直接寫不然會出錯 (要改用 \_
, \&
),但是又很難找,只能找跟上個版本的差異。latex 也提供許多功能,甚至不用 draw.io 也能用 latex 畫出流程圖,但是這些太過進階可能有 80% 的功能是平常用不到。因此本篇主要記錄目前會固定使用的模板以及特殊技巧 (基於我個人對於美感的堅持),也減少之後錯誤發生,更希望對後來需要使用 latex 的人 (包括未來的我) 有幫助。
Basic
文章構成
內容包含在 \begin{document}
、\end{document}
中間,\begin{document}
之前的是設定。
\documentclass[12pt, a4paper]{article}
\title{01 Basic}
\author{Po-Hsuan Huang\\
\texttt{aben20807@gmail.com}
}
\begin{document}
\maketitle
Contents.
\end{document}
Section, label, ref
一般論文最高層級是 Section 可用 \section{}
產生,依此類推 Subsection、Paragraphy 也是如此。在 \section{xxx}
後方加上 \label{aaa}
讓之後可以用 \ref{aaa}
提及,對應的數字會自動產生。(Note: Dummy text generated by https://www.lipsum.com/)
|
|
hyperref
加上 \usepackage{hyperref}
可以自動為 ref 產生連結,這樣就可以用滑鼠點擊後切換到 ref 所指的地方。如果不喜歡預設值樣式,可以自行定義如下 (若是投稿論文不要自行定義):
\hypersetup{
colorlinks,
linkcolor=[RGB]{120, 29, 125},
citecolor=[RGB]{120, 29, 125},
urlcolor=[RGB]{0, 85, 150}
}
Font family 字型
不喜歡預設字型所以改成 Linux Libertine。但是如果是一般寫投稿論文的話,此時第一行應該會是 \documentclass[acmsmall]{acmart}
(以 ACM 提供的模板為例),使用預設提供的字型即可,應該說只能使用預設。
\RequirePackage[T1]{fontenc}
\RequirePackage[tt=false, type1=true]{libertine}
\RequirePackage[varqu]{zi4}
\RequirePackage[libertine]{newtxmath}
itemize, enumerate
一個是項目符號,一個是編號,在後面會順便作範例。
Font size 字體大小
字型大小可以根據情況使用,例如在表格中或是圖片說明。寫論文時通常會用 samll
~ tiny
的字,讓表格寬度不超出邊界。
\begin{itemize}
\item {\Huge Huge}
\item {\huge huge}
\item {\LARGE LARGE}
\item {\Large Large}
\item {\large large}
\item {\normalsize normalsize}
\item {\small small}
\item {\footnotesize footnotesize}
\item {\scriptsize scriptsize}
\item {\tiny tiny}
\end{itemize}
Text highlight 強調文字
在寫論文時幾乎不使用 textit
(與 emph
相同) 和 underline
(可用於強調縮寫)。textbf
用於表格第一列、texttt
用於內文的程式碼、emph
大多用於強調名詞 (例如第一次提到別人的 work) 少部分強調動詞 (特殊作法需要讓讀者知道)。
\begin{enumerate}
\item {\textbf{textbf}}
\item {\texttt{texttt}}
\item {\textit{textit}}
\item {\emph{emph}}
\item {\underline{underline}}
\end{enumerate}
接下來的程式碼會以
#文章構成 為外部框架,只提供 Contents
。
Math
Latex 的強項是提供一個較為標準的格式寫數學式,不像 word 都要利用 GUI 介面 (好像也可以在 word 用 latex 但就超出本篇範圍)。數學很多符號都有對應的 latex 程式,通常是常用的才會記住,之前有發現可以用手寫辨識找出符號對應的 latex (Weekly Collection#latex-符號手寫辨識) 再次推薦。
注意在用數學式 (或演算法) 表達時會跟程式碼不同,例如賦值不能寫成 =
而是用 \gets
,但也不是強制規定,有在文章中定義好即可。特殊字型 (例如 \mathbb{Z}
) 需要使用 \usepackage{amsfonts}
。
行內數學式使用 $
,而 $$
會獨立並至中,但還是一行。
Inline latex: $x \in_R \mathbb{Z}_{2^\ell}$, use \$ to wrap.
$$
(y_1, ..., y_n) \gets \mathcal{F}(x_1, ..., x_n)
$$
多行的數學式就需要使用 equation 或 align,同時需要使用對應的 package (\usepackage{amsmath}
),使用範例可以參考其提供的手冊 ( User’s Guide for the amsmath Package)。下方是我目前用過最複雜的數學式之一。
Test reference~\ref{eq:mt1}.
\begin{align}
\langle c\rangle^A & = \langle a\rangle^A \times \langle b \rangle^A \label{eq:mt1} \\
& = (\langle a\rangle^A_0 + \langle a\rangle^A_1) \times (\langle b\rangle^A_0 + \langle b\rangle^A_1) \label{eq:mt2} \\
\begin{split}
& = \langle a\rangle^A_0 \times \langle b\rangle^A_0 + \langle a\rangle^A_1 \times \langle b\rangle^A_1 \\
& \qquad + \underbrace{\langle a\rangle^A_0 \times \langle b\rangle^A_1}_{\langle u\rangle^A} + \underbrace{\langle a\rangle^A_1 \times \langle b\rangle^A_0}_{\langle v\rangle^A}
\end{split} \label{eq:mt3} \\
\begin{split}
& = \langle a\rangle^A_0 \times \langle b\rangle^A_0 + \langle u\rangle^A_0 + \langle v\rangle^A_0\\
& \qquad + \langle a\rangle^A_1 \times \langle b\rangle^A_1 + \langle u\rangle^A_1 + \langle v\rangle^A_1\\
\end{split} \label{eq:mt4} \\
& = \langle c\rangle^A_0 + \langle c\rangle^A_1 \label{eq:mt5}
\end{align}
Figure
流程圖建議用 draw.io 繪製後輸出 pdf,也就是先匡選要輸出的部分或是 ctrl-a (要輸出全部的話),接著選 File > Export as > PDF…> 勾選 Selection Only 及 Crop > Export。除了是向量格式外還有一個優點就是編譯出來的圖片是可以選取上面的字也可以搜尋,不過我有遇過在投稿最後一步 pdf proof 時會破圖,這時候就要改輸出成 png (Zoom 調成 400% 確保解析度,勾選 Selection Only)。
實驗畫折線圖或長條圖的話建議使用 matplotlib 繪製學術風格的成果圖,可以參考之前的文章: Use Matplotlib to Plot Academic Figures。
figure
一般插入圖片的方式是使用 figure
(需要 \usepackage{graphicx}
) 環境如下,方括號的參數用來指定顯示的位置 (b 目前頁面的底部;h 目前位置;p 下頁頂部;t 此頁頂部。多個參數時越左邊的優先度越高),不過應該只是建議有時候不一定會按照指定的產生。\includegraphics
是主要指向要插入的圖片 (例如下方範例是把圖片放在 figures/paper-example.pdf
),同時可以用方括號設定寬度等參數,縮放比例會盡量讓圖中的文字比內文略小。\caption
是圖片的說明文字 (注意要有句點),編號會自動產生。如果有 \label
(之後可以被 \ref
) 需要放在 \caption
後方。
\begin{figure}[ht]
\centering
\includegraphics[width=.48\linewidth]{figures/paper-example.pdf}
\caption{Caption for example.}\label{fig:example}
\end{figure}
subfigure
一張圖有多個子圖時會用到 subfigure (需要 \usepackage{caption}
、\usepackage{subcaption}
),這會自動產生 (a), (b),需要對齊的話可以參考 Alignment of horizontal subfigures 更換 subfigure 的方括號參數。
\begin{figure}[hbt]
\centering
\begin{subfigure}[b]{0.48\textwidth}
\centering
\includegraphics[width=\linewidth]{figures/paper-example.pdf}
\captionsetup{width=.9\linewidth}
\caption{Caption for example.}\label{fig:example2}
\end{subfigure}
\begin{subfigure}[b]{0.44\textwidth}
\centering
\includegraphics[width=\linewidth]{figures/cat.png}
\captionsetup{width=.9\linewidth}
\caption{\tiny Cat.}\label{fig:cat}
\end{subfigure}
\caption{Two subfigures.} \label{fig:all}
\end{figure}
03_1 Figure IEEEtran 完整程式碼
若是使用 IEEE 的模板 (例如 \documentclass[conference,10pt]{IEEEtran}
),建議絕對不要使用 subfigure (相信我,我跟它硬碰硬半天,結果我輸了) 而是改用 subfig,以避免格式設定被 subfigure 覆蓋。注意不可以使用 \usepackage{caption}
、\usepackage{subcaption}
。
% before \begin{document}
\ifCLASSOPTIONcompsoc
\usepackage[caption=false, font=normalsize, labelfont=sf, textfont=sf]{subfig}
\else
\usepackage[caption=false, font=footnotesize]{subfig}
\fi
\captionsetup[subfigure]{width=0.48\textwidth} % 讓 caption 最大寬度一致
% after \begin{document}
\begin{figure}[htb!]
\centering
\subfloat[Caption for example.]{\label{fig:example}\includegraphics[width=0.33\textwidth]{figures/paper-example.pdf}}\hfill%
\subfloat[\tiny Cat.]{\label{fig:cat}\includegraphics[width=0.48\textwidth]{figures/cat.png}}%
\caption{Two subfigures.}
\label{fig:all}
\end{figure}
minipage
多張圖橫放則是使用 table + minipage,此時的 caption 比較特別需要改用 \captionof
。請注意編號的產生結果。
\begin{table}[ht]
\centering
\begin{minipage}[t]{.48\linewidth}
\includegraphics[width=\linewidth]{figures/paper-example.pdf}
\captionof{figure}{First figure.}
\label{fig:A}
\end{minipage}
\qquad
\begin{minipage}[t]{.44\linewidth}
\includegraphics[width=\linewidth]{figures/cat.png}
\captionof{figure}{Second figure.}
\label{fig:B}
\end{minipage}
\end{table}
Table
用一般手寫建立表格的方式頗為複雜且傷神 (一堆 &
一堆 \\
),我會建議直接用線上的表格產生器 ( Tables Generator) 先建立想要的大小,不過要小心這類免費線上服務可能會將資料外流,我通常只會填入標題列,內容的部分在產生完後於自己的 .tex 檔案中完成。
表格建立好後可以再用一些指令 (\toprule
, \midrule
, \bottomrule
) 加上分隔線 (需要 \usepackage{booktabs}
),表格說明文字也是利用 \caption
,標題列會使用粗體 (\textbf
)。\begin{tabular}{lll}
後方的 lll 是儲存格的對齊方式 (l 向左對齊: c 置中;r 向右對齊),一般文字向左對齊而數字向右或置中。
\begin{table}[ht]
\centering
\caption{Caption of the table.}\label{tab:example}
\begin{tabular}{lll}
\toprule
\textbf{Category} & \textbf{Work} & \textbf{Tags} \\
\midrule
Open & Title A & A, B, C \\
Open & Title B & B, D \\
Close & Title C & A, B, D \\
Close & Title D & E \\
\bottomrule
\end{tabular}
\end{table}
要做到儲存格合併的話也可以利用產生工具,它會自動利用 multirow (需要 \usepackage{multirow}
) 合併。寫起來頗眼花撩亂要記得填對位置。順帶一提,有數字的話要小數點長度要統一,就算是整數也要補 .0 上去。
\begin{table}[ht]
\centering
\caption{Caption of the table 2.}\label{tab:example2}
\begin{tabular}{llrr}
\toprule
\multirow{2}{*}{\textbf{Category}} & \multirow{2}{*}{\textbf{Work}} & \multicolumn{2}{c}{\textbf{Time}} \\ \cline{3-4}
& & \textbf{First} & \textbf{Second} \\ \hline
\multirow{2}{*}{Open} & Title A & 1.1 & 3.0 \\
& Title B & 2.0 & 2.3 \\ \hline
\multirow{2}{*}{Close} & Title C & 3.8 & 5.6 \\
& Title D & 4.6 & 8.8 \\ \bottomrule
\end{tabular}
\end{table}
Algorithm
演算法部份跟數學式類似,不過通常涉及更抽象的概念。寫法上可以貼近程式碼語法,講求易懂為原則。符號使用上我看網路上建議先參考演算法權威 Introduction to Algorithms,撰寫時要注意是否有沒定義的符號否則容易讓讀者看不懂。我這邊也有參考 CrypTFlow2 論文的寫法 (下面版本),在不用定義函式 (function) 的情況下讓讀者很清楚演算法的輸入輸出。
在版面安排上可以和 figure 一樣利用 minipage 做左右分割,也可以排列組合,例如左圖片右演算法 (左青龍右白虎)。
使用套件以及設定演算法風格:
\usepackage{xcolor}
\usepackage[linesnumbered,algoruled,boxed,lined]{algorithm2e}
\SetKwInOut{KwIn}{Input} % align input, output
\SetKwInOut{KwOut}{Output} % align input, output
\SetKw{Continue}{continue} % new keyword
\SetKw{Or}{or} % new keyword
\SetArgSty{textnormal}
\SetAlCapNameFnt{\small}
\SetAlCapFnt{\small}
\newcommand\mycommfont[1]{\rmfamily\itshape\textcolor{gray}{#1}} % comment style
\SetCommentSty{mycommfont} % comment style
\usepackage[T1]{fontenc} % for '<'
演算法部分:
\begin{algorithm}[ht]
\SetKwProg{Function}{Function}{ :}{end}
\caption{Vector \texttt{add} function.} \label{algo:example}
\Function{add($v_a, v_b$)}{
$v_{ret} \gets $ empty vector with the same length with $v_a$ \;
\For{$i$=0; $i$ < $\vert v_a \vert$; $i$++}{
$v_{ret}[i] \gets v_a[i] + v_b[i]$ \;
}
\KwRet{$v_{ret}$} \;
}
\end{algorithm}
\begin{algorithm}[ht]
\caption{Vector \texttt{add}.} \label{algo:example2}
\KwIn{$v_a$, an input vector. \newline
$v_b$, an input vector.
}
\KwOut{$v_{ret}$, a vector for output.
}
$v_{ret} \gets $ empty vector with the same length with $v_a$ \tcp*[l]{Initialization.}
\For{$i$=0; $i$ < $\vert v_a \vert$; $i$++}{
$v_{ret}[i] \gets v_a[i] + v_b[i]$ \;
}
\end{algorithm}
Code
在論文中加入程式碼的機會蠻少的,一來是演算法 (不用編譯不容易出錯) 就可以說明,且太過細節不利於說明,還有可能有商業考量。但還是有部分論文會放,或是在做筆記、報告時會使用到。
這裡比較特殊的技巧是用到 escapechar=|
讓 |
後方可以插入 \label
。註解部分可以使用 \tcp
產生單行,多行則用 \tcc
,可另外參考 jdhao’s digital space - How to Write Algorithm Pseudo Code in LaTeX。使用 xcolor 有錯誤的話參考 Package xcolor Error: Undefined color `Darkgreen’ 解決。
使用套件以及設定程式碼風格:
\usepackage[dvipsnames]{xcolor} % color
\usepackage{listings} % code
% Default fixed font does not support bold face
\DeclareFixedFont{\ttb}{T1}{txtt}{bx}{n}{10} % for bold
\DeclareFixedFont{\ttm}{T1}{txtt}{m}{n}{10} % for normal
% Python style for highlighting
\newcommand\pythonstyle{\lstset{
language=Python,
basicstyle=\ttm,
morekeywords={self,with}, % Add keywords here
keywordstyle=\ttb\color{BlueViolet},
emph={MyClass,__init__}, % Custom highlighting
emphstyle=\ttb\color{BrickRed}, % Custom highlighting style
stringstyle=\color{ForestGreen},
frame=single, % Any extra options here
showstringspaces=false,
morecomment=[l][\itshape\color{Gray}]{\#},
numbers=left,
stepnumber=1,
}}
% Python for inline
\newcommand\pythoninline[1]{%
{\pythonstyle\lstinline!#1!}%
}
% Python environment
\lstnewenvironment{python}[1][]{%
\pythonstyle\footnotesize\lstset{#1}}{}
程式碼部分:
\begin{python}[
float,floatplacement=ht,
caption={Simple python code.},
label=list:python,
escapechar=|]
def func(num1, num2):
# This function adds two numbers
s = num1 + num2 |\label{line:do-add}|
return s
if __name__ == "__main__":
x = func(3, 5)
print(f"Answer: {x}")
\end{python}
Bibliography
顧名思義就是自己的參考書目。在論文中需要 cite (使用 \cite
指令) 別人 (或自己) 的論文時需要用到。\bibliographystyle
可設定風格,但一般投稿論文的模板會有提供,例如 ACM 就會直接使用 \bibliographystyle{ACM-Reference-Format}
。\bibliography
是指定你的參考書目的檔案位置,如果是放在 example.bib
那就要使用 \bibliography{example}
。這個區塊其實相當重要,我老闆特別重視,所以都要非常仔細檢查同類型的論文是否有相同格式,多個句號少個逗號都頗嚴重。
其中 .bib 的內容通常會需要自己收集,可以到各大會議期刊的官網上獲得,也可以到 google scholar、dblp 找,但是可能會跟官網有出入。arXiv 或是一些 eprint 的 bibtex 格式比較特殊 (每個人都寫不一樣) 建議可以到官網找自動輸出的內容,例如 arXiv 右下方有提供,IACR 也有提供官方格式 ( How to Cite a Paper in the Cryptology ePrint Archive)。此外,我個人會提供一個 XXX
讓一起改論文的人可以當作還沒找到 bibtex 的論文,要注意在投稿出去前要消除所有 XXX
。
一般常用的類別 ( 完整列表):
- inproceedings: 會議
- article: 期刊
- book: 書本、教科書
- misc: 線上資源
Test cite: \cite{XXX, huang2021tonic, huang2022pops, huang2023securetvm}.
\bibliographystyle{unsrt}
\bibliography{example}
@misc{XXX,
author = {TBD},
booktitle = {TBD},
title = {TBD}
}
@inproceedings{huang2021tonic,
author = {Huang, Po-Hsuan and Tu, Chia-Heng and Chung, Shen-Ming},
booktitle = {Proceedings of the 36th Annual ACM Symposium on Applied Computing},
pages = {491--500},
title = {TONIC: Towards Oblivious Neural Inference Compiler},
year = {2021},
isbn = {9781450381048},
publisher = {Association for Computing Machinery},
doi = {10.1145/3412841.3441929},
location = {Virtual Event, Republic of Korea}
}
@article{huang2022pops,
title = {POPS: an off-peak precomputing scheme for privacy-preserving computing},
author = {Huang, Po-Hsuan and Chang, Ting-Wei and Tu, Chia-Heng and Chung, Shen-Ming},
journal = {The Journal of Supercomputing},
pages = {16841--16860},
year = {2022},
publisher = {Springer},
doi = {10.1007/s11227-022-04552-x},
issn = {1573-0484},
volume = {78},
issue = {15}
}
@article{huang2023securetvm,
author = {Po-Hsuan Huang and Chia-Heng Tu and Shen-Ming Chung and Pei-Yuan Wu and Tung-Lin Tsai and Yi-An Lin and Chun-Yi Dai and Tzu-Yi Liao},
journal = {ACM Transactions on Design Automation of Electronic Systems},
comment-number = {1},
title = {SecureTVM: A TVM-Based Compiler Framework for Selective Privacy-Preserving Neural Inference},
comment-volume = {1},
year = {2023},
month = {1},
doi = {10.1145/3579049},
issn = {1084-4309}
}
Back reference
07_1 Bibliography Back Reference 完整程式碼
有些論文 (例如 CVPR) 有看到在後面的參考書目會有列出哪幾頁有 cite 這篇。
這可能是他們的模板有改進,不過我們也是可以利用現有的工具達到此功能。可以看到下方的程式碼範例會比之前的版本多不少程式碼,但是可以客製化的部份比較多。\FloatBarrier
的作用是可以確定圖片可以先輸出最後才是參考書目。\DefineBibliographyStrings
可以設定 “cit. on p. " 的格式。不過原則上是不會刻意使用這種,比較適合自己的報告或筆記。
使用套件以及設定參考書目風格:
\usepackage{placeins} % FloatBarrier
\usepackage[%
backref=true,
backend=bibtex,
maxbibnames=99,
sorting=none,
block=space]{biblatex} % back link for ref in Reference
% \DefineBibliographyStrings{english}{
% backrefpage = {page},
% backrefpages = {pages},
% }
\renewcommand{\cite}{\autocite}
\addbibresource{example.bib}
內文部份:
Test cite: \cite{XXX, huang2021tonic, huang2022pops, huang2023securetvm}.
\FloatBarrier
\printbibliography[%
heading=bibintoc,
title={References}
]
Misc
最後剩下一些特殊技巧。
vspace
有時候會需要微調版面為了塞進限制的頁數 (一般是在所有內容都寫好後才調整),這時候可以利用 \vspace
去增減空間。以下示範調整圖片的標題位置。
\begin{table}[!h]
\centering
\begin{minipage}[t]{.48\linewidth}
\includegraphics[width=\linewidth]{figures/paper-example.pdf}
\vspace{-10pt}
\captionof{figure}{First figure (-10pt).}
\label{fig:A}
\end{minipage}
\qquad
\begin{minipage}[t]{.44\linewidth}
\includegraphics[width=\linewidth]{figures/cat.png}
\vspace{10pt}
\captionof{figure}{Second figure (+10pt).}
\label{fig:B}
\end{minipage}
\end{table}
email with mbox
在 latex 中寫電子郵件的話會自動轉成 mailto 的連結,也就是在 pdf 中點擊時可以開啟郵件系統直接寄信,之前有遇到直接寫會導致換行時會被加入連字號 (_
) 導致郵件系統開啟的網址不一樣,所以建議在除了作者區塊的 email 要加上 \mbox
它會保證中間不會有連字號。也可以使用中間的版本不過就會被當作連結,所以我個人還是喜歡使用 mbox。
\begin{itemize}
\item xxxXxxx@example.com
\item \href{mailto:xxxXxxx@example.com}{xxx-xxx@example.com}
\item \mbox{xxxXxxx@example.com}
\end{itemize}
newcommand
可以自訂指令方便減少程式碼使用量,例如剛剛中間的 email。\newcommand
後第一個大括號內是指令名稱,接著方括號是參數個數 (之後可以用 #N 代表第 N 個參數),最後一個大括號是指令對應的本體。整體寫起來像是 C 的 macro。
% before \begin{document}
\newcommand{\email}[1]{\href{mailto:#1}{#1}}
% after \begin{document}
\email{xxxXxxx@example.com}
在寫投稿論文時因為會有修改跟討論,所以也會利用新增指令。\cmt
用作討論,可以指定顏色來分辨類型。\revised
用作標記修改的部份,在期刊答辯時可以當作附件讓審查人員清楚知道有修改的部份,切換註解可以快速換成不標記的版本。
% before \begin{document}
\usepackage{xcolor}
\newcommand{\cmt}[2][red]{ {\color{#1} XXX: #2} }
\definecolor{darkpastelgreen}{rgb}{0.01, 0.75, 0.24}
\newcommand{\revised}[2][darkpastelgreen]{{\color{#1}#2}}
% \newcommand{\revised}[1]{#1}
% after \begin{document}
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Maecenas xnsl \email{xxxXxxx@example.com} auctor, nulla
vitae fringilla convallis, tellus ex laoreet ipsum, convallis
blandit lorem dolor ut nisl. \cmt{need to add references.}
\cmt[green]{OK}. This is \revised{an} apple.
circled numbers
預設的 \textcircled
在數字上會有偏移,所以需要微調,或是使用 tikz (太進階先不提)。同樣利用 \newcommand
來簡化。
% before \begin{document}
\newcommand{\Circle}[1]{\raisebox{.5pt}{\textcircled{\raisebox{-0.9pt} {#1}}}}
% after \begin{document}
\begin{itemize}
\item \textcircled{0}, \textcircled{1}, \textcircled{2}, \textcircled{3}, \textcircled{4}, \textcircled{5}, \textcircled{6}, \textcircled{7}, \textcircled{8}, \textcircled{9}
\item \Circle{0}, \Circle{1}, \Circle{2}, \Circle{3}, \Circle{4}, \Circle{5}, \Circle{6}, \Circle{7}, \Circle{8}, \Circle{9}
\end{itemize}
build time
適合放在文件或是履歷上來標註最後編輯時間。要注意 xelatex 沒有此功能,所以若是要有中文並且有時間的話需要改用 lualatex,pdflatex 是有此功能所以放心。
% before \begin{document}
\usepackage[calc,useregional]{datetime2} % currenttime
% Timezone https://tex.stackexchange.com/a/634977
\newcommand{\DTMtznow}[2]{%
\DTMsavenow{now}%
\DTMtozulu{now}{currzulu}%
\DTMsaveaszulutime{currtaipei}{\DTMfetchyear{currzulu}}{\DTMfetchmonth{currzulu}}{\DTMfetchday{currzulu}}{\DTMfetchhour{currzulu}}{\DTMfetchminute{currzulu}}{\DTMfetchsecond{currzulu}}{#2}{00}%
\DTMdisplay{\DTMfetchyear{currtaipei}}{\DTMfetchmonth{currtaipei}}{\DTMfetchday{currtaipei}}{}{\DTMfetchhour{currtaipei}}{\DTMfetchminute{currtaipei}}{\DTMfetchsecond{currtaipei}}{#1}{00}%
}
\newcommand{\DTMtaipeinow}{\DTMtznow{+08}{-08}}
% after \begin{document}
\hfill{\color{gray}\footnotesize Last modified: \DTMtaipeinow}