下列的我之前的问题,对于这个 MWE,
\documentclass{article}
\usepackage[hidelinks,colorlinks=false]{hyperref}
\usepackage{lipsum}
\setlength\marginparwidth{0.8\dimexpr(\paperwidth - \textwidth)/2\relax}
\usepackage[textwidth=\marginparwidth]{todonotes}
\usepackage{etoolbox}
\makeatletter
\newcommand\@todonotes@owner{default}
\define@key{todonotes}%
{owner}{\def\@todonotes@owner{#1}}
\newtoggle{ownerdefault}
\newtoggle{ownerB}
\newcommand\stR[2]{% 1st reviewer comment
\todo[%
owner=default,
author=1st Reviewer,noline,caption={#1 Comment},color=blue!20%
]%
{#1 Comment}{\color{blue}{\bfseries#2}}}
\newcommand\ndR[2]{% 2nd reviewer comment
\todo[%
owner=B,
author=2nd Reviewer,noline,caption={#1 Comment},color=red!50!white%
]%
{#1 Comment}{\color{red}{\bfseries#2}}}
\renewcommand{\@todonotes@addElementToListOfTodos}{%
\if@todonotes@colorinlistoftodos%
\addtocontents{tdo}
{%
\protect\iftoggle{owner\@todonotes@owner}
{%
\protect\contentsline {todo}
{\protect\fcolorbox{\@todonotes@currentbordercolor}%
{\@todonotes@currentbackgroundcolor}%
{\protect\textcolor{\@todonotes@currentbackgroundcolor}{o}}%
\ \@todonotes@caption
}{\thepage}{\@currentHref}%
}{}%
}%
\else%
\addtocontents{tdo}
{%
\protect\iftoggle{owner\@todonotes@owner}
{%
\protect\contentsline {todo}
{\@todonotes@caption
}{\thepage}{\@currentHref}%
}{}%
}%
\fi}%
\makeatother
\begin{document}
\toggletrue{ownerdefault}
\section*{Reviewer \#1 Comments}
\InputIfFileExists{\jobname.tdo}{}
\toggletrue{ownerB}
\togglefalse{ownerdefault}
\section*{Reviewer \#2 Comments}
\InputIfFileExists{\jobname.tdo}{}
\togglefalse{ownerB}
\makeatletter \@starttoc{tdo}\makeatother % to trigger the creation of the list
\section{Section}
Text \stR{\#2}{2nd comment of the 1st reviewer} another text\vspace{\baselineskip}
\lipsum[1-2]\vspace{\baselineskip}
Text \ndR{\#3b}{3rd comment of the 2nd reviewer} another text.\vspace{\baselineskip}
\lipsum[1-2]\vspace{\baselineskip}
Some text \stR{\#1}{1st comment of the 1st reviewer} continue text.\vspace{\baselineskip}
\lipsum[1-2]\vspace{\baselineskip}
Text \ndR{\#3a}{1st comment of the 2nd reviewer} another text.\vspace{\baselineskip}
\end{document}
我需要知道如何字母数字listoftodos
根据自定义命令的第一个参数对条目进行排序todo
?
例如,我需要对第一个列表条目进行如下排序:
#1条评论
#2 评论
第二个列表条目按如下方式排序:
#3a 评论
#3b 评论
答案1
好吧,你需要一些工具来对 进行排序.tdo
。你真的不想在 latex 中这样做。例如,如果你要切换到 lualatex,你可以做这样的事情(你也可以激活 --shell-excape 并调用一些外部脚本):
\documentclass{article}
\usepackage[hidelinks,colorlinks=false]{hyperref}
\usepackage{lipsum}
\setlength\marginparwidth{0.8\dimexpr(\paperwidth - \textwidth)/2\relax}
\usepackage[textwidth=\marginparwidth]{todonotes}
\usepackage{etoolbox}
\makeatletter
\newcommand\@todonotes@owner{default}
\define@key{todonotes}%
{owner}{\def\@todonotes@owner{#1}}
\newtoggle{ownerdefault}
\newtoggle{ownerB}
\newcommand\stR[2]{% 1st reviewer comment
\todo[%
owner=default,
author=1st Reviewer,noline,caption={#1 Comment},color=blue!20%
]%
{#1 Comment}{\color{blue}{\bfseries#2}}}
\newcommand\ndR[2]{% 2nd reviewer comment
\todo[%
owner=B,
author=2nd Reviewer,noline,caption={#1 Comment},color=red!50!white%
]%
{#1 Comment}{\color{red}{\bfseries#2}}}
\renewcommand{\@todonotes@addElementToListOfTodos}{%
\if@todonotes@colorinlistoftodos%
\addtocontents{tdo}
{%
\protect\iftoggle{owner\@todonotes@owner}
{%
\protect\contentsline {todo}
{\protect\fcolorbox{\@todonotes@currentbordercolor}%
{\@todonotes@currentbackgroundcolor}%
{\protect\textcolor{\@todonotes@currentbackgroundcolor}{o}}%
\ \@todonotes@caption
}{\thepage}{\@currentHref}%
}{}%
}%
\else%
\addtocontents{tdo}
{%
\protect\iftoggle{owner\@todonotes@owner}
{%
\protect\contentsline {todo}
{\@todonotes@caption
}{\thepage}{\@currentHref}%
}{}%
}%
\fi}%
\makeatother
\usepackage{luacode}
\begin{luacode*}
function sort_tdo (jobname)
local lines = {}
-- read the lines in table 'lines'
for line in io.lines(jobname) do
table.insert(lines, line)
end
-- sort
table.sort(lines)
-- write all the lines
file=io.open(jobname.."sorted", "w")
io.output(file)
for i, l in ipairs(lines) do io.write(l, "\n")
end
io.close(file)
end
\end{luacode*}
\IfFileExists{\jobname.tdo}{\directlua{sort_tdo("\jobname.tdo")}}{}
\begin{document}
\toggletrue{ownerdefault}
\section*{Reviewer \#1 Comments}
\InputIfFileExists{\jobname.tdosorted}{}
\toggletrue{ownerB}
\togglefalse{ownerdefault}
\section*{Reviewer \#2 Comments}
\InputIfFileExists{\jobname.tdosorted}{}
\togglefalse{ownerB}
\makeatletter \@starttoc{tdo}\makeatother % to trigger the creation of the list
\section{Section}
Text \stR{\#2}{2nd comment of the 1st reviewer} another text\vspace{\baselineskip}
\lipsum[1-2]\vspace{\baselineskip}
Text \ndR{\#3b}{3rd comment of the 2nd reviewer} another text.\vspace{\baselineskip}
\lipsum[1-2]\vspace{\baselineskip}
Some text \stR{\#1}{1st comment of the 1st reviewer} continue text.\vspace{\baselineskip}
\lipsum[1-2]\vspace{\baselineskip}
Text \ndR{\#3a}{1st comment of the 2nd reviewer} another text.\vspace{\baselineskip}
\end{document}
答案2
以下内容基于 Ulrike 的回答,也需要 LuaTeX。它有三个改进:它不是逐行读取文件,而是一次性读取(这通常更快),如果可能的话,它使用本地变量而不是全局变量,并且对它唯一的全局变量使用非通用名称(避免使用此类变量的其他代码出现问题) 并且不会将排序后的行写入文件,而是将它们保存在 Lua 变量中。这样可以避免弄乱 Lua 的默认输出流,不会在工作目录中留下另一个文件,而且速度更快:
\documentclass{article}
\usepackage[hidelinks,colorlinks=false]{hyperref}
\usepackage{lipsum}
\setlength\marginparwidth{0.8\dimexpr(\paperwidth - \textwidth)/2\relax}
\usepackage[textwidth=\marginparwidth]{todonotes}
\usepackage{etoolbox}
\makeatletter
\newcommand\@todonotes@owner{default}
\define@key{todonotes}%
{owner}{\def\@todonotes@owner{#1}}
\newtoggle{ownerdefault}
\newtoggle{ownerB}
\newcommand\stR[2]{% 1st reviewer comment
\todo[%
owner=default,
author=1st Reviewer,noline,caption={#1 Comment},color=blue!20%
]%
{#1 Comment}{\color{blue}{\bfseries#2}}}
\newcommand\ndR[2]{% 2nd reviewer comment
\todo[%
owner=B,
author=2nd Reviewer,noline,caption={#1 Comment},color=red!50!white%
]%
{#1 Comment}{\color{red}{\bfseries#2}}}
\renewcommand{\@todonotes@addElementToListOfTodos}{%
\if@todonotes@colorinlistoftodos%
\addtocontents{tdo}
{%
\protect\iftoggle{owner\@todonotes@owner}
{%
\protect\contentsline {todo}
{\protect\fcolorbox{\@todonotes@currentbordercolor}%
{\@todonotes@currentbackgroundcolor}%
{\protect\textcolor{\@todonotes@currentbackgroundcolor}{o}}%
\ \@todonotes@caption
}{\thepage}{\@currentHref}%
}{}%
}%
\else%
\addtocontents{tdo}
{%
\protect\iftoggle{owner\@todonotes@owner}
{%
\protect\contentsline {todo}
{\@todonotes@caption
}{\thepage}{\@currentHref}%
}{}%
}%
\fi}%
\makeatother
\usepackage{luacode}
\begin{luacode*}
local split_lines = lpeg.Ct((lpeg.C((1-lpeg.P'\n')^0)*'\n')^0)*-1
function sorted_lines_from_filename (jobname)
local file = io.open(jobname)
local lines = split_lines:match(file:read'a')
file:close()
assert(lines, 'Files should end with a newline')
table.sort(lines)
return lines
end
\end{luacode*}
\IfFileExists{\jobname.tdo}{\directlua{sorted_tdo = sorted_lines_from_filename("\jobname.tdo")}}{}
\begin{document}
\toggletrue{ownerdefault}
\section*{Reviewer \#1 Comments}
\directlua{if sorted_tdo then tex.tprint(sorted_tdo) end}
\toggletrue{ownerB}
\togglefalse{ownerdefault}
\section*{Reviewer \#2 Comments}
\directlua{if sorted_tdo then tex.tprint(sorted_tdo) end}
\togglefalse{ownerB}
\directlua{sorted_tdo=nil} % We no longer need sorted_tdo, so clean up
\makeatletter \@starttoc{tdo}\makeatother % to trigger the creation of the list
\section{Section}
Text \stR{\#2}{2nd comment of the 1st reviewer} another text\vspace{\baselineskip}
\lipsum[1-2]\vspace{\baselineskip}
Text \ndR{\#3b}{3rd comment of the 2nd reviewer} another text.\vspace{\baselineskip}
\lipsum[1-2]\vspace{\baselineskip}
Some text \stR{\#1}{1st comment of the 1st reviewer} continue text.\vspace{\baselineskip}
\lipsum[1-2]\vspace{\baselineskip}
Text \ndR{\#3a}{1st comment of the 2nd reviewer} another text.\vspace{\baselineskip}
\end{document}