Is there an easy way to repeat a simple piece of text? For example, I want to write $\downarrow$ & $\downarrow$ & $\downarrow$ & ...
(for a table). I tried *{8}{$\downarrow$ &}
, but it doesn't work…
[Tex/LaTex] Repeating Simple Text
macros
Related Solutions
I don't think that marking code this way adds to its readability. Nevertheless, you can change the behavior of "
in math mode with the following TeX magic:
\documentclass{article}
\usepackage{amsmath}
\begingroup\lccode`~=`"
\lowercase{\endgroup\def~}#1"{\text{#1}}
\mathcode`"="8000
\begin{document}
"Abc" $f_"abc"$
\end{document}
However, keep in mind that "
is not the “right” way to type a double quote, and it's preferable to use the combinations ``
and ''
.
If the quotes your text editor inserts are “
and ”
, then the following should work:
\begingroup\lccode`~=`“
\lowercase{\endgroup\def~}#1”{\text{#1}}
\mathcode`“="8000
But definitely not when using pdflatex
and UTF-8 encoding. XeLaTeX and LuaLaTeX are OK. Again, I don't recommend such a type of markup, which is prone to errors and less readable than an explicit \text{...}
markup.
Let's see how it works; the trick
\begingroup\lccode`~=`“
\lowercase{\endgroup\def~}#1”{\text{#1}}
is very common (it's in the TeXbook) in order to give a meaning to the active version of a character (in this case “
) as \lowercase
does its job and puts the converted token list back in the input stream, so that TeX will see the lowercase version of ~
(still active as is ~
in the default setting). Thus TeX will swallow
\def“#1”{\text{#1}}
The macro “
is defined to look for the following ”
and consider anything in between as its argument, which is passed to \text
.
With \mathcode`“="8000
we are telling (Xe)TeX that “
in math mode must be converted to its active version. In text mode the nature of “
is not changed.
Why does the first version, with "
, work? Because "
is not active, its category code is still 12 and the definition tells TeX to look for the next category 12 "
that follow (it's converted to a mathcode only if it need to be, that is, if TeX is looking for mathcodes, which it doesn't when collecting the parameter text of a called macro).
Why doesn't the version with “
work with pdflatex
? Because this is not a seven bit character, so pdftex
sees it as two characters (it's even wrong to say \lccode`~=`“
, in pdftex
, as a stray character will remain). With XeTeX or LuaTeX, instead, multibyte characters are converted to a single entity before the engine starts the tokenization process.
This is a simple replacement tool at a Lua level. Everything written in \parseme
is a target for replacements, but the TeX commands are not expanded and we can hide a portion of text from replacement procedure. The replacements are stored in a simple Lua table, the first column contains the searched terms and the second column contains their replacements. Testing goes from top to bottom. For instance A
is replaced quite soon and never again. On the other hand, X
is going to be Y
, then Y
goes to Z
and that goes to A
. The name of commands will be replaced, e.g. \colorme
would become \cojuicerme
. I used the \clrme
command to illustrate a fast workaround, if needed.
If you need even more advanced tool for string manipulations than the string
library can offer, I can recommend you LPeg
library, that's a tool which is already installed in LuaTeX. Some examples are mentioned in Programming in LuaTeX article.
If you run my example you will see 1 2 3 4 5 6
three times in the terminal. It means there were 6 replacement tests called three times by the \parseme
command during typesetting.
%! lualatex mal-text-parser.tex
\documentclass[a4paper]{article}
\pagestyle{empty}
\parindent=0pt
% It fixes beginnings and endings of I/O lines, among other things...
\usepackage{luatextra}
\pagestyle{empty}
\usepackage{luacode}
\usepackage{xcolor}
\begin{document}
\def\parseme#1{% TeX definition...
\directlua{parseme("\unexpanded{#1}")}%
% This is working: "\unexpanded{#1}" but one must write \\ instead of backslash in the \parseme command.
}% End of \parseme command...
\begin{luacode*}
-- A conversion table, from -> to
local maltable={
{"la", "beer"},
{"lo", "juice"},
{"A", "Hello World! I was here! Phantom-as!"},
{"X","Y"},
{"Y","Z"},
{"Z","A"},
}
function parseme(text) -- Lua function
-- Read an argument sent by TeX...
content=text -- Backup of original text...
-- Do all the necessary replacements...
for i=1,#maltable do
tex.sprint("\\message{"..i.."}")
content=string.gsub(content,maltable[i][1],maltable[i][2])
end
-- Typeset the result at the terminal and to the document...
print(content)
tex.print(content)
end
\end{luacode*}
\def\formated{\textbf{lalo}} % This part is not replaced.
\def\clrme#1{{\color{red}#1}} % Definition of the command.
% We use \clrme instead of \colorme because we would get -> \cojuicerme as lo is being replaced...
% lalo in \formated is protected from expansion and replacement...
Text of the paragraph. \parseme{My long \\formated{} sentence. \\clrme{To la red!} \\textbf{Hey!} Ending. lalala lo lo lo A}\par
End of the paragraph. \parseme{My \\clrme{next} try.} The end.\par
Input is X, result is: \parseme{X}; X goes to Y to Z to A, but A is not replaced anymore.
\end{document}
Best Answer
You could define a command, say
\rpt
that repeats some command a number of times. Here I've defined\rpt[<repeat>]{<stuff>}
that repeats<stuff>
<repeat>
number of times.<repeat>
is an optional parameter, that defaults to1
if not used:It is a very elementary example, but shows how you can shorten your code to repeat something over and over. Looping is provided by
forloop
which implements a "nested iteration", and is easy to use for small repetitive stuff.