我不太喜欢 Microsoft Word,但我很怀念在与朋友一起编辑的论文上发表评论的功能,评论以小气泡的形式显示在页边。我设法创建了一些与我想要的非常接近的东西,但有一些错误我无法解决。
这是一个使用我创建的代码的(希望是)最小的工作示例文档:
\documentclass[draft]{article}
% For conditional control flow in draft mode
\usepackage{ifdraft}
% For larger margins when in draft mode
\ifdraft{\usepackage[rmargin=3in,marginparwidth=2.75in]{geometry}}{}
% For todo notes in the margins
\usepackage{todonotes}
% For highlighting in MS Word-like comments
\usepackage{soul,color}
% This is needed to ensure the line spacing of the margin notes is correct.
\usepackage{setspace}
% For conditional use of the \comment command based on the options provided.
\usepackage{ifthen}
% BEGIN HIGHLIGHTING: The following code provides a highlighting command, which is
% used in my custom commenting system below. If you want more information about
% this code, see the following URL:
% https://tex.stackexchange.com/questions/5959/cool-text-highlighting-in-latex
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{decorations.pathmorphing}
\makeatletter
\newcommand{\defhighlighter}[3][]{%
\tikzset{every highlighter/.style={color=#2, fill opacity=#3, #1}}%
}
\defhighlighter{yellow}{.5}
\newcommand{\highlight@DoHighlight}{
\fill [ decoration = {random steps, amplitude=1pt, segment length=15pt}
, outer sep = -15pt, inner sep = 0pt, decorate
, every highlighter, this highlighter ]
($(begin highlight)+(0,8pt)$) rectangle ($(end highlight)+(0,-3pt)$) ;
}
\newcommand{\highlight@BeginHighlight}{
\coordinate (begin highlight) at (0,0) ;
}
\newcommand{\highlight@EndHighlight}{
\coordinate (end highlight) at (0,0) ;
}
\newdimen\highlight@previous
\newdimen\highlight@current
\DeclareRobustCommand*\highlight[1][]{%
\tikzset{this highlighter/.style={#1}}%
\SOUL@setup
%
\def\SOUL@preamble{%
\begin{tikzpicture}[overlay, remember picture]
\highlight@BeginHighlight
\highlight@EndHighlight
\end{tikzpicture}%
}%
%
\def\SOUL@postamble{%
\begin{tikzpicture}[overlay, remember picture]
\highlight@EndHighlight
\highlight@DoHighlight
\end{tikzpicture}%
}%
%
\def\SOUL@everyhyphen{%
\discretionary{%
\SOUL@setkern\SOUL@hyphkern
\SOUL@sethyphenchar
\tikz[overlay, remember picture] \highlight@EndHighlight ;%
}{%
}{%
\SOUL@setkern\SOUL@charkern
}%
}%
%
\def\SOUL@everyexhyphen##1{%
\SOUL@setkern\SOUL@hyphkern
\hbox{##1}%
\discretionary{%
\tikz[overlay, remember picture] \highlight@EndHighlight ;%
}{%
}{%
\SOUL@setkern\SOUL@charkern
}%
}%
%
\def\SOUL@everysyllable{%
\begin{tikzpicture}[overlay, remember picture]
\path let \p0 = (begin highlight), \p1 = (0,0) in \pgfextra
\global\highlight@previous=\y0
\global\highlight@current =\y1
\endpgfextra (0,0) ;
\ifdim\highlight@current < \highlight@previous
\highlight@DoHighlight
\highlight@BeginHighlight
\fi
\end{tikzpicture}%
\the\SOUL@syllable
\tikz[overlay, remember picture] \highlight@EndHighlight ;%
}%
\SOUL@
}
\makeatother
% END HIGHLIGHTING
% BEGIN MS WORD-STYLE COMMENTS
% This is the main function for providing MS Word-style comments. There are two
% ways to use it. First, you can do the following:
%
% \comment[akm]{This is comment text that will appear in the margin.}{This is
% body text that will appear in the main output.}
%
% Second, you can do the following, which will appear only as a note in the margin:
%
% \comment[akm]{Here's a comment that won't highlight any text. However, it
% should still point to the place in the text where it appears.}
%
% Third, if you're Aaron, then you can leave out the initials. Obviously, anyone
% else reading this should consider altering the command for their own default
% initials.
%
% \comment{Here's a margin note using the default initials.}
\newcounter{akmctr}
\newcommand{\comment}[3][akm]{%
% initials of the author (optional) + note in the margin
\ifdraft{\refstepcounter{akmctr}%
{%
\setstretch{1.0}% line spacing
\todo[color={red!100!green!33},size=\small,fancyline]{%
\textbf{Comment [\uppercase{#1} \arabic{akmctr}]:}~#2}
\ifthenelse{\equal{#3}{}}{}{\highlight[red!100!green!33]{#3}}%
}%
}{}%
}
% END MS WORD-STYLE COMMENTS
\begin{document}
\section{Introduction} % (fold)
\label{sec:introduction}
Let's start testing the comments. Here's a comment with the default initials and no highlighted text.
Alice was beginning to get very \comment{These sample paragraphs are from the first chapter of Lewis Carroll's \emph{Alice in Wonderland}. Please note that the original text shouldn't have weird spacing at the place where the comment was inserted, but it does.}tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it, `and what is the use of a book,' thought Alice `without pictures or conversation?'
here's a comment that uses non-default initials and still doesn't highlight text.
So she was \comment[pno]{This comment should have a different counter. Is it possible to setup counters based on the initials passed?}considering in her own mind (as well as she could, for the hot day made her feel very sleepy and stupid), whether the pleasure of making a daisy-chain would be worth the trouble of getting up and picking the daisies, when suddenly a White Rabbit with pink eyes ran close by her.
Here's a comment that uses the default initials and highlights some text.
There was nothing so VERY remarkable in that; nor did Alice think it so VERY much out of the way to hear the Rabbit say to itself, `Oh dear! Oh dear! I shall be late!' (when she thought it over afterwards, \comment{This should also have no strange artifacts at the place where it was inserted. It should also have a fancyline pointing to the highlighted portion of the text.}{it occurred to her that she ought to have wondered at this}, but at the time it all seemed quite natural); but when the Rabbit actually TOOK A WATCH OUT OF ITS WAISTCOAT-POCKET, and looked at it, and then hurried on, Alice started to her feet, for it flashed across her mind that she had never before seen a rabbit with either a waistcoat-pocket, or a watch to take out of it, and burning with curiosity, she ran across the field after it, and fortunately was just in time to see it pop down a large rabbit-hole under the hedge.
In another moment down went Alice after it, \comment[pno]{Basically, this is the same as before, but it should be for a different author, preferably with a different counter and a different color text.}{never once considering how in the world she was to get out again}.
It's probably also a good idea to test these things in lists. Let's try making a few comments in a list environment.
\begin{enumerate}
\item This is the first item in the list.
\item This is the second item in the list.
\item This is the \comment{This should be the third item in the list!}{fourth} item in the list.
\item This is the fourth item in the list.
\item This is the \comment{Here's a comment in a list with no highlighting.}final item in the list.
\end{enumerate}
% section introduction (end)
Obviously, there are many other environments that we should test these things in, but this is already going to be a huge post. I'll stop here.
\end{document}
具体来说,创建新的注释命令的代码部分是这样的:
% BEGIN MS WORD-STYLE COMMENTS
% This is the main function for providing MS Word-style comments. There are two
% ways to use it. First, you can do the following:
%
% \comment[akm]{This is comment text that will appear in the margin.}{This is
% body text that will appear in the main output.}
%
% Second, you can do the following, which will appear only as a note in the margin:
%
% \comment[akm]{Here's a comment that won't highlight any text. However, it
% should still point to the place in the text where it appears.}
%
% Third, if you're Aaron, then you can leave out the initials. Obviously, anyone
% else reading this should consider altering the command for their own default
% initials.
%
% \comment{Here's a margin note using the default initials.}
\newcounter{akmctr}
\newcommand{\comment}[3][akm]{%
% initials of the author (optional) + note in the margin
\ifdraft{\refstepcounter{akmctr}%
{%
\setstretch{1.0}% line spacing
\todo[color={red!100!green!33},size=\small,fancyline]{%
\textbf{Comment [\uppercase{#1} \arabic{akmctr}]:}~#2}
\ifthenelse{\equal{#3}{}}{}{\highlight[red!100!green!33]{#3}}%
}%
}{}%
}
% END MS WORD-STYLE COMMENTS
有几个大问题和几个小问题。以下是我无法解决的问题列表:
- [已回答 -参见 Yiannis 的回答] 为什么添加评论时正文中会出现多余的空格?
- 为什么一些未使用文本突出显示的评论会创建一个小的突出显示三角形?
- 有没有办法为每位作者获取单独的计数器?
- 有没有办法让评论气泡和每个作者的突出显示都使用不同的颜色?
对我来说,前两个问题比后两个问题重要得多。
我还应该补充一点,我其实并不需要 MS Word 中的其他更改跟踪功能。我使用源代码控制系统 (git)满足了我的所有需求。此外,我还阅读了一些关于与非 LaTeX 用户协作的非常有用的帖子,包括从非 LaTeX 使用合作者那里获取 LaTeX 文档的评论的良好策略是什么?和审阅 TeX 生成的 PDF 的工作流程。两者都很棒,但我需要注释气泡出现在 PDF 中,因为我的研究小组经常阅读纸质早期草稿,需要一些额外的解释。
答案1
我认为最好将您的 MWE 和您的问题放在单独的问题中,以便您和回答者都能提供重点评论。
第一个问题的答案是您需要添加(%)以确保没有出现多余的空格。
这解决了第一个问题。
\newcommand{\comment}[3][akm]{%
% initials of the author (optional) + note in the margin
\ifdraft{\refstepcounter{akmctr}%
{%
\setstretch{1.0}% line spacing
\todo[color={red!100!green!33},size=\small,fancyline]{%
\textbf{Comment [\uppercase{#1} \arabic{akmctr}]:}~#2}
\ifthenelse{\equal{#3}{}}{}{\highlight[red!100!green!33]{#3}}%
}%
}{}%
}
另请参阅https://tex.stackexchange.com/a/19927/963。
我还必须祝贺你,你完成了一组看起来非常漂亮的待办事项笔记。我会回来添加其余的答案,除非你想按照我的建议拆分它们,请将你的最低要求减少 80%。
我们如何为更多用户添加计数器?首先,我们需要定义一个方法来添加用户,并决定保存用户名的数据结构类型。
逗号分隔列表是一种合适的数据结构,我们可以通过 LaTeX 内核命令或 etoolbox 包对其进行操作,甚至可以编写自己的命令来执行此操作。此列表在宏中定义如下:
\def\users{yiannis,egreg,martin}
要添加更多用户,我们可以手动输入另一个名称或为其创建另一个命令,选择后者,我们使用 LaTeX 内核\g@addto@macro
命令来执行此操作。
\def\adduser#1{\g@addto@macro{\users}{,#1}}
要添加用户使用\adduser{Mary}
,如果您想打印用户列表,只需通过键入展开列表\users
。
下一步是自动创建计数器,因为我们有一个列表,所以我们将使用 for 循环,在我们调用的宏中\counterfactory
。
\def\counterfactory#1{\@for\next:=#1\do{%
\ifcsname c@\next\endcsname%
\else
\newcounter{\next}%
\setcounter\next{0}
\fi
}}
\AtBeginDocument{\counterfactory\users}
例如,当 LaTeX 分配一个计数器时,foo
它创建的计数器是c@counter
。for\ifcsname
循环中的代码部分只是检查计数器是否之前已创建,如果没有,则继续创建计数器并将其设置为零。
将上述代码片段包含在您的序言中,并调整\comment
宏的相关部分(例如,\ifdraft{\refstepcounter{akmctr}
调整为\ifdraft{\refstepcounter{#1}
等)即可达到目的。下面是最简单的示例,可以看到计数器部分自行运行。
\documentclass{article}
\makeatletter
\def\users{egreg,martin}
\def\adduser#1{\g@addto@macro{\users}{,#1}}
\def\counterfactory#1{\@for\next:=#1\do{%
\ifcsname c@\next\endcsname%
\else
\newcounter{\next}%
\setcounter\next{0}
\fi
}}
% activate at beginning of document
\AtBeginDocument{\counterfactory\users}
% add a few users
\adduser{aaron}
\adduser{yiannis}
\adduser{george}
\begin{document}
This documented commented by \users. \\
\stepcounter{yiannis}
\theyiannis\\% 1
\theaaron\\ %0
\setcounter{aaron}{100}\\ %100
\theaaron\\
\end{document}
可以使用类似的技术来添加特定的用户颜色。我们可以修改宏\adduser
以接受两个参数,第一个参数是用户名,第二个参数是颜色。
\def\adduser#1#2{%
\g@addto@macro{\users}{,#1}%
\expandafter\def\csname #1@color\endcsname{#2}
}
这是另一个 MWE 来测试更改。
\documentclass{article}
\usepackage{xcolor}
\makeatletter
\def\users{egreg,martin}
\def\adduser#1#2{%
\g@addto@macro{\users}{,#1}%adds user to list
\expandafter\def\csname #1@color\endcsname{#2} %holds the color name in `\name@color`
}
\def\counterfactory#1{\@for\next:=#1\do{%
\ifcsname c@\next\endcsname%
\else
\newcounter\next%
\setcounter\next{0}
\fi
}}
\AtBeginDocument{\counterfactory\users}
\adduser{aaron}{red}
\adduser{yiannis}{blue}
\adduser{george}{orange}
\begin{document}
This documented commented by \users. \\
\stepcounter{yiannis}
\theyiannis\\% 1
\theaaron\\ %0
\setcounter{aaron}{100}\\ %100
\theaaron\\
\color{\yiannis@color} This text is printed in blue,
whereas Aaron's color is printed in \color{\aaron@color} red.
\end{document}
因此\highlight[red!100!green!33]
,您可以用用户的颜色命令替换您说的位置。这有望帮助您迭代代码并获得所需的内容,并更好地了解出了什么问题。
答案2
这待办事项包听起来就像是你想要的。
\usepackage{todonotes}
This is some text.\todo{This is a margin note with a line}
Here's more text.\todo[noline]{Here's a note in the margin without a line pointing to the text}