todonotes:自定义 listoftodos 条目排序

todonotes:自定义 listoftodos 条目排序

下列的我之前的问题,对于这个 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}

相关内容