我想知道是否存在一个包,可以接受所谓的互联网风格引用电子邮件的纯文本,并根据 PDF 输出对其进行相应的格式化。互联网风格的引用在维基百科页面中进行了讨论发帖风格;因此假设我从那里取一个例子,并且我有以下内容作为email.eml
文件的内容:
At 10.01am Wednesday, Danny wrote:
> At 9.40am Wednesday, Jim wrote:
>> I'm going to suspend the mail service for approx. thirty
>> minutes tonight, starting at 5pm, to install some updates
>> and important fixes.
> Whoa! Hold on. I have a job scheduled at 5:30 which mails out
> a report to key tech staff. Could you push it back an hour?
>
> By the way, which systems will be updated? I had some network
> problems after last week's update. Will I have to reboot?
No problems. 6pm it is then.
Basically, I will update our WWW server and firewall.
No, you won't have to reboot.
然后,我想象可以准备类似的东西email.tex
,我可以使用它来获取格式化的 PDF:
\documentclass{article}
\usepackage{???}
\begin{document}
\begin{QUOTEDEMAIL}
\input{email.eml}
\end{QUOTEDEMAIL}
\end{document}
我希望至少能够控制选择不同级别引用回复(以 ' >
' 为前缀的行)的颜色(灰度)...但是,如果我还可以控制字体 - 或者渲染行而不是 ' >
'(就像 Thunderbird 所做的那样),那就太棒了!:)
那么,存在类似的事情吗?
答案1
这只是一个部分解决方案,但它将是可行的方法 - 使用listings
:
\documentclass{article}
\usepackage{listings}% http://ctan.org/pkg/listings
\usepackage{xcolor}% http://ctan.org/pkg/xcolor
\begin{document}
Here is the message:
\lstset{
basicstyle=\ttfamily\small,
morecomment=[l][\color{red!50}]{>>\ },
morecomment=[l][\color{green!80}]{>\ },
}
\lstinputlisting{email.eml}
\end{document}
各个回复级别的格式化是通过 完成的morecomments
,实际上指定该行“代码”为“注释”。listings
无法在上述示例中拾取空行,但如果您不介意使用特定级别的格式,则可以正确解释
\lstset{
basicstyle=\ttfamily\small,
morecomment=[l][\color{red!50}]{>},
}
说。请注意,>
在电子邮件的其他地方使用可能会导致问题。
答案2
我刚刚找到了另一种方法 - 使用delimiter
lstlisting 选项,tikz
在引号字符处插入节点。麻烦的是,您必须先决定并指定嵌套级别的数量(及其颜色);但好处是您可以完全隐藏已处理的引号字符 - 而其他此类字符则不受影响(因此原始文本源中不需要转义或干预);并且您还可以根据需要绘制带有装饰的线条(哦,是的,由于 tikz 覆盖,您必须使用 tex 两次):
代码并不是很简单,需要对 listings.sty 内容进行一些重载 - 请参阅以下代码中的注释:
\documentclass{article}
\usepackage{listings}%
\usepackage{xcolor}%
% \usepackage{unravel}
\usepackage{tikz}
\usetikzlibrary{decorations.pathmorphing}
% \usepackage{trace}
% \pagecolor{yellow!15}
\begin{document}
\newcounter{testa} % just to see how newcounter works with resetting:
% \unravel{
\newcounter{testb}[testa]
% \@cons \cl@testa {{testb}} -> \xdef \cl@testa {\@elt {testb}}
% }
\makeatletter
\def\lnm{\the\lst@lineno}
\def\lnc{\the\lst@column}
\def\lnp{\the\lst@pos} % character column, but as -1, -34..
% \lst@lineno is newcount; "let" it to
% a macro named accordingly so can link to it in newcounter
\let\c@lst@lineno\lst@lineno
\let\cl@lst@lineno\relax
\newcounter{unm}[lst@lineno]
% \@cons\cl@lst@lineno{{unm}} % ! TeX capacity exceeded, sorry
% \xdef\cl@lst@lineno{\@elt{unm}} %cannot: unm needs to be added to list of lst@lineno, which is reset upon addtocounter, which lst@lineno doesn't use
% hack in lst@MProcessListing (listings.sty), to call \extralstlinecall before change of line number
\gdef\extralstlinecall{\typeout{EXTRA LINE \lnm}}
\def\lst@MProcessListing{%
\lst@XPrintToken \lst@EOLUpdate \lsthk@InitVarsBOL
\extralstlinecall
\global\advance\lst@lineno\@ne
\ifnum \lst@lineno>\lst@lastline
\lst@ifdropinput \lst@LeaveMode \fi
\ifx\lst@linerange\@empty
\expandafter\expandafter\expandafter\lst@EndProcessListing
\else
\lst@interrange
\lst@GetLineInterval
\expandafter\expandafter\expandafter\lst@SkipToFirst
\fi
\else
\expandafter\lst@BOLGobble
\fi}
\makeatother
\tikzstyle{every picture}+=[remember picture] % must have
\tikzstyle{nn} = [inner sep=0pt, outer sep=0pt, minimum size=0pt]
\tikzstyle{qln} = [line width=2pt]
% quote colors:
\colorlet{qcol0}{blue!50}
\colorlet{qcol1}{orange!50}
\colorlet{qcol2}{cyan!50}
\gdef\lastqcol{2} % declare how many levels/colors we expect (last index)
\colorlet{defaultcol}{.} % current color
% percolumn node lists - same ammount as qcols
\gdef\setpcol#1#2{%
\global\expandafter\edef\csname pcoll-#1\endcsname{#2}%
}
\gdef\addpcol#1#2{%
\expandafter\ifx\csname pcoll-#1\endcsname\empty%
\global\expandafter\edef\csname pcoll-#1\endcsname{#2}%
\else%
\global\expandafter\edef\csname pcoll-#1\endcsname{\csname pcoll-#1\endcsname,#2}%
\fi%
}
\setpcol{0}{}
\setpcol{1}{}
\setpcol{2}{}
% we know nodes are NXX-YY here, so
\global\let\e\relax
\gdef\getnameXY N#1-#2\e#3#4{%
%\typeout{getname \string#1, \string#2, \string#3, \string#4}%
\xdef#3{#1}%
\xdef#4{#2}%
}
% \getnameXY NXX-YY\e\tmpa\tmpb
% \typeout{tmpa \tmpa, tmpb \tmpb}
% {\uccode`A=10
% \uppercase{\xdef\lf{A}}}
\xdef\qnodelist{}
\xdef\qnodelistx{}
\xdef\qnodelisty{}
\xdef\lastlnm{0}
\def\repl{%
\tikzstyle{every picture}+=[remember picture] % must have
\pgfmathtruncatemacro{\clnp}{-1*\lnp}%
\ifnum\lnm=\lastlnm%
\stepcounter{unm}%
\else%
\setcounter{unm}{0}%
\fi%
\xdef\lastlnm{\lnm}%
\ifnum\clnp>\lastqcol%
\setcounter{unm}{\lastqcol}%
> % output verbatim character; cannot insert LF (\n): ^^J; also give space betw. char and % sign!
\else%
\edef\tnnd{N\lnm-\theunm}%
\tikz[baseline=(\tnnd.base)]{%
\node[nn] (\tnnd) {\phantom{>}};%
\draw[qln,draw=qcol\theunm] (current bounding box.north) -- (\tnnd.south);%
}%
\ifx\qnodelist\empty%
\xdef\qnodelist{\tnnd}%
\xdef\qnodelistx{\lnm}%
\xdef\qnodelisty{\clnp}%
\else%
\xdef\qnodelist{\qnodelist,\tnnd}%
\xdef\qnodelistx{\qnodelistx,\lnm}%
\xdef\qnodelisty{\qnodelisty,\clnp}%
\fi%
\addpcol{\clnp}{\tnnd}
\color{qcol\theunm}% this spills color; to stop it, use a reset in \extralstlinecall!
\fi%
%\typeout{ln \lnm, col \lnc, pos \clnp, unm \theunm}%
}
\gdef\extralstlinecall{%
\color{defaultcol}%
\typeout{EXTRA LINE \lnm}%
}
\lstset{
basicstyle=\ttfamily\small,
% {\^^M}{{\^^M}}1 % matches, but cannot insert, end of line (actually, para!)
literate={>}{{\repl}}1 ,% kills the >,>> morecomments!
morecomment=[l][\color{red!50}]{>>\ },
morecomment=[l][\color{green!80}]{>\ },
%morecomment=[f][\color{green!80}][0]{\^^M}, % locks
}
\begin{lstlisting}
At 10.01am Wednesday, Danny wrote:
> At 9.40am Wednesday, Jim wrote: >>check here<<
>> I'm going to suspend the mail service for approx. thirty
>> minutes tonight, starting at 5pm, to install some updates
>> and important fixes.
>
> Whoa! Hold on. I have a job scheduled at 5:30 which mails out
> a report to key tech staff. Could you push it back an hour?
>
>> I'm going to suspend the mail service for approx. thirty
>> minutes tonight, starting at 5pm, to install some updates
>> and important fixes.
>
> By the way, which systems will be updated? I had some network
> problems after last week's update. Will I have to reboot?
No problems. 6pm it is then.
Basically, I will update our WWW server and firewall.
No, you won't have to reboot.
> By the way, which systems will be updated? I had some network
> problems after last week's update. Will I have to reboot?
> Will I have to reboot?
No, you won't have to reboot.
\end{lstlisting}
\qnodelist
\tikzstyle{bnl} = [line width=1pt,decoration=snake,decorate]
% \begin{tikzpicture}[overlay]
\foreach \ix in {0,...,\lastqcol}{
\xdef\strt{}\xdef\endr{}
\expandafter\edef\expandafter\ptmp{\csname pcoll-\ix\endcsname}
\typeout{ptmp: '\ptmp'}
% will not loop if \ptmp empty; that's why all pcoll-\ix must be initialized to empty
\ifx\ptmp\empty\else
\foreach \inn in \ptmp {
\expandafter\getnameXY\inn\e\trow\tcol % get
\typeout{\inn, \trow, \tcol, '\strt', '\endr'}
\ifx\strt\empty
\xdef\strt{\trow}
\xdef\endr{\trow}
\else
\pgfmathtruncatemacro{\isNeighbor}{\trow-\endr == 1}
\typeout{isNeigh \isNeighbor: \trow, \strt, \endr}
\ifnum\isNeighbor=1{}\else
\tikz[overlay]\draw[bnl,qcol\tcol!60] (N\strt-\tcol) -- (N\endr-\tcol);
\xdef\strt{\trow}
\fi
\xdef\endr{\trow}
\fi
} % foreach
\tikz[overlay]\draw[bnl,qcol\tcol!60] (N\strt-\tcol) -- (N\endr-\tcol);
\fi
}
% \end{tikzpicture}
\end{document}