TransWikia.com

How can I test the first character on each line of a listing?

TeX - LaTeX Asked by jub0bs on April 17, 2021

The listings package defines a hook called EveryLine to allow users to execute TeX code at the beginning of each line of a listing; the following is taken directly from the listings source code (listings.dtx):

hookname{EveryLine}

Executed at the beginning of each emph{output} line, i.e.~more than
once for broken lines. This hook must not change the horizontal or
vertical position.

The code below is my attempt at using this hook to test whether the first character of each line is f and insert YES before it in that case. However, as you can see below, I’m not getting the expected output.

At first, I thought if might be a grouping problem: the code inserted at the EveryLine might be buried inside a group and, as a result, my test could not access the first token on the line, because that token lies outside the group in question. However, a quick test (consisting in locally incrementing a TeX register) shows that it’s not the case.

Any idea what I’m doing wrong?

enter image description here

documentclass{article}

usepackage{listings}

usepackage{filecontents}
begin{filecontents*}{sample.c}
foo
bar
frivolous
thing
discourse
fragile
end{filecontents*}

makeatletter
lst@AddToHook{EveryLine}{@ddedToEveryline}
defdetectF#1{ifx f#1 YES#1fi}
newcountmycount
defadvandprintCount{advancemycount by @nethemycount}
makeatother

begin{document}

makeatletter

let@ddedToEverylinedetectF
lstinputlisting[basicstyle=ttfamily]{sample.c}

let@ddedToEverylineadvandprintCount
lstinputlisting[basicstyle=ttfamily]{sample.c}

makeatother

end{document}

One Answer

Here's my try:

documentclass{article}
usepackage{pdftexcmds}
usepackage{listings}

usepackage{filecontents}
begin{filecontents*}{sample.c}
foo
bar
frivolous
thing
discourse
fragile
end{filecontents*}

makeatletter
lst@AddToHook{EveryLine}{@ddedToEveryline}

def@splitfirstchar#1#2@nil{gdef@detectF{#1}}
defsplitfirstchar#1{@splitfirstchar#1@nil} 
def@detectF{%
%  -thelst@token-
  expandaftersplitfirstcharexpandafter{thelst@token}%
  def@tempa{f}%
%  -@detectF-
  ifnumpdf@strcmp{@detectF}{@tempa}=z@
     YES
  else
     NO
  fi%
}
newcountmycount
defadvandprintCount{advancemycount by @nethemycount}
makeatother
begin{document}

makeatletter

let@ddedToEveryline@detectF
lstinputlisting[basicstyle=ttfamily]{sample.c}

let@ddedToEverylineadvandprintCount
lstinputlisting[basicstyle=ttfamily]{sample.c}

makeatother

end{document}

enter image description here

Correct answer by Marco Daniel on April 17, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP