TeX - LaTeX Asked on January 12, 2021
I have this command
newcommand{lines}[1]{multido{}{#1}{vskip 5mm makebox[linewidth]{dotfill}} vskip 8mmsetlength{rightmargin}{5em}}
It allows me to create dotted lines with ease.
For example:
When I write lines{3} it will produce:
.........................................
.........................................
.........................................
How can I tell LaTeX to treat lines{} as lines{0}
Thank you.
Just put a leading zero so the number of loops is 0#1
. When #1
is empty you have zero, otherwise you have #1
.
documentclass{article}
usepackage{xparse}
ExplSyntaxOn
NewDocumentCommand lines { m }
{
int_step_inline:nn { 0#1 }
{ vskip 5mm~noindent makebox[linewidth]{dotfill} }
vskip 8mm~setlength{rightmargin}{5em}%
}
ExplSyntaxOff
begin{document}
alines{}
blines{3}
end{document}
Here's a very slightly more elaborate version that accepts count
registers and a few more edge cases (definitely not fool-proof)?
documentclass{article}
usepackage{xparse}
ExplSyntaxOn
NewDocumentCommand lines { m }
{
int_step_inline:nn { tl_if_blank:eT {#1} { 0 } #1 }
{ vskip 5mm~noindent makebox[linewidth]{dotfill} }
vskip 8mm~setlength{rightmargin}{5em}%
}
ExplSyntaxOff
begin{document}
alines{}
blines{3}
clines{ 3 }
count178=3
dlines{count178}
newcountxx=3
elines{x}
chardefx=3
flines{x}
glines{numexpr 1+1+1}
hlines{dimexpr 0.00005pt}
defempty{}
ilines{empty}
defempty{}
jlines{ empty}
% Still fails in this case, but then you're asking for it ;-)
protecteddefempty{}
% klines{empty}
end{document}
Correct answer by Phelype Oleinik on January 12, 2021
I would do this slightly differently and make the argument to lines
an optional argument, which defaults to zero. This way lines
prints zero dotted lines and lines[3]
prints lines etc.
Here's the modified code:
documentclass{article}
usepackage{multido}
newcommand{lines}[1][0]{%
multido{}{#1}{vskip 5mm makebox[linewidth]{dotfill}}%
vskip 8mmsetlength{rightmargin}{5em}%
}
begin{document}
lines
lines[3]
lines[6]
end{document}
Btw, rather than posting code snippets it is always better to post a full minimal working example as this makes it easier for people to play with and modify your code.
Edit
If in your use-case you need line{}
to be the same as line{0}
then you can use detokenize
:
documentclass{article}
usepackage{multido}
usepackage{xparse}
newcommand{lines}[1]{%
multido{}{ifrelaxdetokenize{#1}relax0else#1fi}{vskip 5mm makebox[linewidth]{dotfill}}%
vskip 8mmsetlength{rightmargin}{5em}%
}
begin{document}
lines{}
lines{3}
lines{6}
end{document}
The detokenize{#1}
"neutralises" all of the category codes that appear in #1
so that no surprises can arise. After the the "content" of #1
is compared with relax
. If #1
is empty then detokenize{#1}
is nothing so the if
statement expands to ifrelaxrelax0else#1fi
. In other words, if #1
is blank then if
-statement expands to 0
and otherwise it expands to #1
.
Answered by user30471 on January 12, 2021
This also will works:
documentclass{book}
usepackage{multido}
begin{document}
newcommand{lines}[1]{%
if!#1!relaxelse
multido{}{#1}{vskip 5mm makebox[linewidth]{dotfill}}%
fi
vskip 8mmsetlength{rightmargin}{5em}%
}
lines{}
lines{3}
end{document}
Answered by MadyYuvi on January 12, 2021
Usage of the multido
-command is:
multido{⟨variables⟩}{⟨repetitions⟩}{⟨stuff⟩}
Seems ⟨repetitions⟩ can by anything that yields a TeX-⟨number⟩-quantity.
If ⟨repetitions⟩ is negative, ⟨variables⟩ will be counted backwards.
Thus with your code-example lines{3}
and lines{-3}
yield the same.
If ⟨repetitions⟩ is provided in terms of something that, e.g., denotes a count
-register or a countdef
-token, just prepending 0
to the ⟨repetitions⟩-argument causes some ! Missing number, treated as zero.
-error. If ⟨repetitions⟩ is provided in terms of an alphabetic constant , just prepending 0
to the ⟨repetitions⟩-argument also does not lead to the desired result.
Therefore I suggest something like applying the multido
-thing only in case both
romannumeralnumbernumber⟨number⟩␣0
and
romannumeral-numbernumber⟨number⟩␣0
yields emptiness.
(romannumeral
does silently not return any token in case the number to convert is not positive. So let's multiply both the number to convert and the negative number to convert by 10 by appending 0
via numbernumber⟨number⟩␣0
-trickery for ensuring that the thing works out with things like count20
(whereafter a space is needed for separating the 20, which is the number of the count
-register) also. In case the argument holding the ⟨number⟩
consists of something that yields ⟨optional signs⟩ only—the case of the argument holding the ⟨number⟩
being empty or blank/yielding emptiness or blankness falls into this category—, the appendend 0
will turn the expression into a valid ⟨number⟩
-quantity whose value is 0
.)
documentclass[a4paper]{article}
% Vertically adjust the page layout so that the example creates exactly one page:
csname@ifundefinedendcsname{pdfpagewidth}{}{pdfpagewidth=paperwidthrelax}%
csname@ifundefinedendcsname{pdfpageheight}{}{pdfpageheight=paperheightrelax}%
csname@ifundefinedendcsname{pagewidth}{}{pagewidth=paperwidthrelax}%
csname@ifundefinedendcsname{pageheight}{}{pageheight=paperheightrelax}%
pagestyle{plain}%
headheight=0exrelax
headsep=0exrelax
topmargin=1cmrelax
footskip=.5topmarginrelax
begingroupnormalfont
expandafterendgroupexpandafteradvanceexpandafter
footskipthedimexpr.5htstrutboxrelaxrelax
textheight=paperheightrelax
advancetextheight-2topmarginrelax
advancetopmargin-1inrelax
%%%%%%%%%%%%% Page layout adjustments done. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
usepackage{multido}
makeatletter
newcommandexchange[2]{#2#1}%
newcommand{lines}[1]{%
if Yexpandafterexchangeexpandafter{romannumeralnumbernumber#1 0}%
{expandafter@firstofoneexpandafter{romannumeral-numbernumber#1 0}}Y%
expandafter@gobbleelseexpandafter@firstofonefi
{multido{}{#1}{vskip 5mm makebox[linewidth]{dotfill}}}%
vskip8mm setlength{rightmargin}{5em}%
}%
makeatother
begin{document}
verb*|somecount=3|:
verb*|lines{somecount}|:
newcountsomecount
somecount=3
lines{somecount}
hrulekerndpstrutbox
verb*|lines{thesomecount}|:
lines{thesomecount}
{
hrulekerndpstrutbox
verb*|count90=3|
verb*|lines{count90}|:
count90=3
lines{count90}
hrulekerndpstrutbox
verb*|lines{count90 }|:
lines{count90 }
}
hrulekerndpstrutbox
verb*|lines{3}|:
lines{3}
hrulekerndpstrutbox
verb*|lines{-000003}|:
lines{-000003}
hrulekerndpstrutbox
verb*|lines{}|:
lines{}
hrulekerndpstrutbox
verb*|lines{0}|:
lines{0}
hrulekerndpstrutbox
end{document}
But there are still problems/issues:
line
-command provided in your example and with the variant of the line
-command provided in the example above you get a lot of overfull hbox
-warnings because the dot-filled lines via makebox
get the with linewidth
while not taking the insertion of the horizontal parindent
-glue into account.vskip
you may wish to ensure vertical mode.parindent
-glue and vertical parskip
-glue by not letting TeX enter unrestricted horizontal mode while typesetting the lines.baselineskip
. This can be rectified by applying offinterlineskip
.setlength{rightmargin}{5em}
.I suppose you wish a command where you can specify
lines
,Distance between lines=...
-key of the optional argument of lines
(default is dimexpr5mm+baselineskiprelax
),vskip
increasing the distance between the bottom of the box forming the previous line of text and the first dotted line—in the example below this is the Distance at top=...
-key of the optional argument of lines
(default is 8mm) ,vskip
increasing the distance between the last dotted line and the top of the box forming the next line of text—in the example below this is the Distance at bottom=...
-key of the optional argument of lines
(default is 8mm),vskip
increasing the the distance between the bottom of the box forming the previous line of text and the top of the box forming the next line of text in case no dotted line is typeset at all—in the example below this is the Gap if no dotted lines=...
-key of the optional argument of lines
(default is 8mm),Indent from the right=...
-key of the optional argument of lines
(default is 0em),Indent from the left=...
-key of the optional argument of lines
(default is 0em).
documentclass{article}
usepackage{keyval}
usepackage{multido}
makeatletter
newcommandexchange[2]{#2#1}%
@ifdefinablelines@DistanceBetweenLines{edeflines@DistanceBetweenLines{thedimexpr5mm+baselineskiprelax}}%
define@key{dottedlines}{Distance between lines}{edeflines@DistanceBetweenLines{thedimexpr#1relax}}%
@ifdefinablelines@DistanceAtTop{edeflines@DistanceAtTop{thedimexpr8mmrelax}}%
define@key{dottedlines}{Distance at top}{edeflines@DistanceAtTop{thedimexpr#1relax}}%
@ifdefinablelines@DistanceAtBottom{edeflines@DistanceAtBottom{thedimexpr8mmrelax}}%
define@key{dottedlines}{Distance at bottom}{edeflines@DistanceAtBottom{thedimexpr#1relax}}%
@ifdefinablelines@GapIfNoLines{edeflines@GapIfNoLines{thedimexpr8mmrelax}}%
define@key{dottedlines}{Gap if no dotted lines}{edeflines@GapIfNoLines{thedimexpr#1relax}}%
@ifdefinablelines@IndentFromTheRight{edeflines@IndentFromTheRight{thedimexpr0emrelax}}%
define@key{dottedlines}{Indent from the right}{edeflines@IndentFromTheRight{thedimexpr#1relax}}%
@ifdefinablelines@IndentFromTheLeft{edeflines@IndentFromTheLeft{thedimexpr0mmrelax}}%
define@key{dottedlines}{Indent from the left}{edeflines@IndentFromTheLeft{thedimexpr#1relax}}%
newcommand{lines}[2][]{%
begingroup
ifvmodeelseparfi
setkeys{dottedlines}{#1}%
offinterlineskip
if Yexpandafterexchangeexpandafter{romannumeralnumbernumber#2 0}%
{expandafter@firstofoneexpandafter{romannumeral-numbernumber#2 0}}Y%
expandafter@secondoftwoelseexpandafter@firstoftwofi
{%
vskipdimexprlines@DistanceAtTop-lines@DistanceBetweenLinesrelax
multido{}{#2}{%
vskiplines@DistanceBetweenLines
hbox tohsize{kernlines@IndentFromTheLeftrelaxdotfillkernlines@IndentFromTheRightrelaxnull}%
}%
vskiplines@DistanceAtBottomrelax
}%
{vskiplines@GapIfNoLinesrelax}%
par
endgroup
}%
makeatother
begin{document}
hrulekerndpstrutbox
verb*|somecount=3|:
verb*|lines{somecount}|:
newcountsomecount
somecount=3
lines{somecount}
hrulekerndpstrutbox
verb*|lines{thesomecount}|:
lines{thesomecount}
{
hrulekerndpstrutbox
verb*|count90=3|
verb*|lines{count90}|:
count90=3
lines{count90}
hrulekerndpstrutbox
kern-topsep
begin{verbatim*}
lines[Distance between lines=5mm,
Distance at top=1cm,
Distance at bottom=1cm,
Gap if no dotted lines=0cm,
Indent from the left=2cm,
Indent from the right=4cm]{count90 }:
end{verbatim*}
kern-topsepkern-partopsep
lines[Distance between lines=5mm,
Distance at top=1cm,
Distance at bottom=1cm,
Gap if no dotted lines=0cm,
Indent from the left=2cm,
Indent from the right=4cm]{count90 }
hrulekerndpstrutbox
}
newpage
hrulekerndpstrutbox
verb*|lines{3}|:
lines{3}
hrulekerndpstrutbox
verb*|lines{ 3 }|:
lines{ 3 }
hrulekerndpstrutbox
verb*|lines{-000003}|:
lines{-000003}
hrulekerndpstrutbox
verb*|lines{}|:
lines{}
hrulekerndpstrutbox
verb*|lines{ }|:
lines{ }
hrulekerndpstrutbox
verb*|lines{0}|:
lines{0}
hrulekerndpstrutbox
end{document}
(Any sequence yielding lines{⟨optional signs⟩}
is treated as lines{0}
.)
Answered by Ulrich Diez on January 12, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP