因此,我想将文本文件逐个字符导入到 latex 中,并通过更改颜色来格式化各个字符。例如,“a”将是蓝色,“b”将是红色等。
我该如何导入文件?我应该创建数据库吗?
输入文件是从小说电子书中提取的简单文本文件。我不太在意原始格式,因为文本文件将从 pdf 或 epub 中提取。因此,除了日常英语中使用的字符(. , ! ?)外,没有方程式和特殊字符。
因此输入可能是这样的:
“举个例子来说明我的意思,我记得有一天早上我在邦德街遇见了蒙蒂·拜恩,他穿着灰色格子西装,看起来非常帅气,我觉得如果我没有一套这样的西装我永远不会快乐。”
答案1
对于每个使用的字母,比如“x”,可以有一个对应的宏\xxx
定义其颜色。这可以通过标点符号(例如感叹号)来实现\expandafter\def\csname!!!\endcsname{...}
。
文本通过宏的方式传递\colorize
。
已编辑,用于从文件获取数据。
编辑使用三重字母\lll
作为着色名称,以免\ll
混淆算法。
已编辑,因此未定义的着色宏以黑色显示。
添加了附录(参见此答案的底部)以允许转义字符在\colorize
宏参数中提供原始格式化能力。
该文件sample.tex
包含此数据
cba def abc!
Here is my next pair of graphs!!!
这是读取并解析该文件的文件。
\documentclass{article}
\usepackage{readarray}
\usepackage{xcolor}
\newcommand\colorize[1]{\expandafter\colorizepars#1\par\relax\relax}
\long\def\colorizepars#1\par#2\relax{%
\ifx#1\relax\else
\colorizewords#1 \relax\relax%
\fi%
\ifx\relax#2\else\par\colorizepars#2\relax\fi%
}
\def\colorizewords#1 #2\relax{%
\ifx#1\relax\else
\colorizeletters#1\relax\relax%
\fi%
\ifx\relax#2\else\ \colorizewords#2\relax\fi%
}
\makeatletter
\def\colorizeletters#1#2\relax{%
\@ifundefined{#1#1#1}{#1}{\csname#1#1#1\endcsname}%
\ifx\relax#2\else\colorizeletters#2\relax\fi}
\makeatother
\def\aaa{\textcolor{red}{a}}
\def\bbb{\textcolor{blue}{b}}
\def\ccc{\textcolor{green}{c}}
\def\ddd{\textcolor{cyan}{d}}
\def\eee{\textcolor{red!40}{e}}
\def\fff{\textcolor{blue!40}{f}}
\def\ggg{\textcolor{red!30!blue}{g}}
\def\hhh{\textcolor{green!40}{h}}
\def\nnn{\textcolor{yellow!40!green}{n}}
\def\ppp{\textcolor{orange}{p}}
\def\rrr{\textcolor{blue!30}{r}}
\def\ttt{\textcolor{green!40!blue}{t}}
\def\xxx{\textcolor{black!50}{x}}
\expandafter\def\csname!!!\endcsname{\textcolor{yellow}{!}}
\def\colorizeentry#1{\edef\tmp{\arrayij{mydata}{#1}{1}}\colorize{\tmp}}
\begin{document}
\colorize{%
abc def!
next paragraph Undefined letters are black.
}
Here is a way to get it from a file, if paragraphs are not needed
\readdef{sample.tex}{\x}
\colorize{\x}
If paragraphs are needed, you can place each paragraph in its own single row
of the input file and parse line by line.
\copyrecords{mydata}% USES DATA FROM MOST RECENT \readdef; ASSIGNS ROWS TO "mydata"
\colorizeentry{1}
\colorizeentry{2}
\colorizeentry{3}
\end{document}
放大
缩小
附录:
如果您需要彩色文本中的一些原始格式化功能,您可以构建转义字符(此处为[
),如下所示:
\makeatletter
\def\colorizeletters#1#2#3\relax{%
\ifx [#1\EscapeChar{#2}%
\ifx\relax#3\else\colorizeletters#3\relax\fi%
\else%
\@ifundefined{#1#1#1}{#1}{\csname#1#1#1\endcsname}%
\ifx\relax#2\else\colorizeletters#2#3\relax\relax\fi%
\fi%
}
\makeatother
\def\EscapeChar#1{%
\if 0#1\relax \textcolor{blue}{[}\else%
\if 1#1\relax \bfseries\else%
\if 2#1\relax \mdseries\else%
\if 3#1\relax \itshape\else%
\if 4#1\relax \upshape\else%
\fi\fi\fi\fi\fi%
}
然后,以下代码
\colorize{%
abc def!
next [1paragraph[2 [0Undefined] [3letters[4 are black.
}
将显示为
答案2
使用 lualatex 你可以做一些类似 chickenize 包的事情:
\documentclass{article}
\usepackage{fontspec,luacode}
\usepackage{luatexbase}
\begin{luacode}
-- stolen from chickenize
local nodenew = node.new
local nodecopy = node.copy
local nodetail = node.tail
local nodeinsertbefore = node.insert_before
local nodeinsertafter = node.insert_after
local noderemove = node.remove
local nodeid = node.id
local nodetraverseid = node.traverse_id
local nodeslide = node.slide
Hhead = nodeid("hhead")
RULE = nodeid("rule")
GLUE = nodeid("glue")
WHAT = nodeid("whatsit")
COL = node.subtype("pdf_colorstack")
GLYPH = nodeid("glyph")
color_push = nodenew(WHAT,COL)
color_pop = nodenew(WHAT,COL)
color_push.stack = 0
color_pop.stack = 0
color_push.command = 1
color_pop.command = 2
mycolors={}
mycolors[97]="1 0 0" --a
mycolors[98]="0 1 0" --b
mycolors[99]="0 0 1" --c
mycolors[100]="0 1 1" --d
colortext = function(head)
for line in nodetraverseid(0,head) do
for i in nodetraverseid(37,line.head) do
if mycolors[i.char] then
color_push.data = mycolors[i.char].." rg"
else
color_push.data = "0.5 0.5 0.5 rg" -- gray for undefined
end
line.head = nodeinsertbefore(line.head,i,nodecopy(color_push))
nodeinsertafter(line.head,i,nodecopy(color_pop))
end
end
return head
end
\end{luacode}
\def\colortext{
\directlua{luatexbase.add_to_callback("post_linebreak_filter",colortext,"colortext")}}
\def\uncolortext{
\directlua{luatexbase.remove_from_callback("post_linebreak_filter","colortext")}}
\newcommand\mytext{abcde}
\begin{document}
\colortext abcdefgabc \section{abcxse} \mytext
\uncolortext abcdefgabc
\end{document}
这给出了类似这样的结果。(我不知道为什么该部分的数字是黑色的)。
答案3
一个expl3
版本。输入(可以来自文件)被分成单词,每个单词被分成字母,这些字母根据可以轻松扩充的表格进行着色。
限制:只允许使用 ASCII 字符(除非您使用 XeLaTeX 或 LuaLaTeX 并根据您的意愿扩充表格)。
\begin{filecontents*}{filetocolorize.tex}
This file will be input.
Its words will be colorized.
\end{filecontents*}
\documentclass{article}
\usepackage{xparse}
\usepackage{xcolor}
\ExplSyntaxOn
\NewDocumentCommand{\colorize}{+m}
{
\codemonkey_colorize:n { #1 }
}
\NewDocumentCommand{\colorizeinput}{m}
{
\tl_set_from_file:Nnn \l_codemonkey_colorize_input_tl { } { #1 }
\codemonkey_colorize:V \l_codemonkey_colorize_input_tl
}
\tl_new:N \l_codemonkey_colorize_input_tl
\seq_new:N \l_codemonkey_colorize_words_seq
\cs_new_protected:Npn \codemonkey_colorize:n #1
{
\seq_set_split:Nnn \l_codemonkey_colorize_words_seq { ~ } { #1 }
\seq_map_inline:Nn \l_codemonkey_colorize_words_seq
{
\tl_map_inline:nn { ##1 } { \codemonkey_colorize_letter:n { ####1 } }
\c_space_tl
}
\unskip % remove the last added space
}
\cs_generate_variant:Nn \codemonkey_colorize:n { V }
\cs_new_protected:Npn \codemonkey_colorize_letter:n #1
{
\str_case:nnF { #1 }
{
{a}{\textcolor{red}{a}}
{b}{\textcolor{blue}{b}}
{c}{\textcolor{green}{c}}
{d}{\textcolor{cyan}{d}}
{e}{\textcolor{red!40}{e}}
{f}{\textcolor{blue!40}{f}}
{g}{\textcolor{red!30!blue}{g}}
{h}{\textcolor{green!40}{h}}
{n}{\textcolor{yellow!40!green}{n}}
{p}{\textcolor{orange}{p}}
{r}{\textcolor{blue!30}{r}}
{t}{\textcolor{green!40!blue}{t}}
{x}{\textcolor{black!50}{x}}
{!}{\textcolor{yellow}{!}}
}
{ % none of the above
#1
}
}
\ExplSyntaxOff
\begin{document}
\colorize{abc def!
next paragraph Undefined letters are black.}
Here is a way to get it from a file
\colorizeinput{filetocolorize}
\end{document}