TransWikia.com

Transform an imported list between brackets to a list between parentheses

TeX - LaTeX Asked by Bruno Stonek on May 8, 2021

I’m using Macaulay2 to make some computations and export a text.txt file which contains a list of numbers, in the form of, for example, {1,2,3}.

I further want to input that list into my tex file, but I need it to be between normal parentheses. It’s to be used by the "yng" command from the youngtab package.

So I want my tex file to do yng(1,2,3), but I don’t know how to do that because if I do input{text.txt} I’ll get {1,2,3}: I don’t want those brackets there.

How can I achieve this?

EDIT: It also seems that Steven saw further ahead than me what I will want to do in the future! As a further step, if I can input a text file which has one such list per line, and LaTeX makes the Young tableaux out of each line automatically, it’ll be great.

3 Answers

If the text.txt file has multiple entries, one per record, then this allows one to access them as array elements:

documentclass{article}
usepackage{youngtab,readarray}
newcommandyngalt[1]{%
  deftmpA{yng(}%
  edeftmpB{#1}%
  expandaftertmpAtmpB)%
}
begin{filecontents*}{text.txt}
{1,2,3}
{2,3,4}
{4,1,3,5}
end{filecontents*}
begin{document}
readrecordarray{text.txt}myyng
3rd entry: yngalt{myyng[3]}

2nd entry: yngalt{myyng[2]}
end{document}

enter image description here

If there will always be only one braced list in the text.txt file, here is an alternative:

documentclass{article}
usepackage{youngtab,readarray}
newcommandyngalt[1]{%
  readdef{text.txt}myyng
  expandafteryngaltauxmyyng }
defyngaltaux#1 {yng(#1)}
begin{filecontents*}{text.txt}
{4,1,3,5}
end{filecontents*}
begin{document}
THE entry: yngalt{text.txt}
end{document}

SUPPLEMENT

Handle it with a loop over all entries in the file:

documentclass{article}
usepackage{youngtab,readarray}
newcommandyngalt[1]{%
  deftmp{yng(}%
  expandafterexpandafterexpandaftertmp#1)}

begin{filecontents*}[overwrite]{text.txt}
{1,2,3}
{2,3,4}
{4,1,3,5}
end{filecontents*}
begin{document}
readarraysepchar{,}
readdef{text.txt}myyngdata
readlist*myyng{myyngdata}

Loop:
foreachitemzinmyyng[]{ifnumzcnt=1else
  thenumexprzcnt-1relax: 
  yngalt{myyng[zcnt-1]}[3pt]fi}

2nd entry: yngalt{myyng[2]}
end{document}

enter image description here

Correct answer by Steven B. Segletes on May 8, 2021

You can capture the contents of a file into a macro using catchfile (into temp, say), then trim the braces by using it as an argument to another macro and replace it with parentheses with the following

deftempa#1{deftemp{(#1)}}% Add parentheses around #1
expandaftertempatemp% Update temp

enter image description here

documentclass{article}

begin{filecontents*}[overwrite]{temp.txt}
{1,2,3}
end{filecontents*}

usepackage{catchfile,youngtab}

% CatchFileDef{<cmd>}{<file>}{<setup>}
CatchFileDef{temp}{temp.txt}{}
deftempa#1{deftemp{(#1)}}% Macro to add parentheses around #1
expandaftertempatemp% Update temp

begin{document}

expandafteryngtemp

end{document}

Since you're writing the source file temp.txt, you may as well include whatever LaTeX commands you need as part of the output. For example, outputting

something{1,2,3}
something{4,1,3,2}
something{1,3,5,7}
% ...and so on...

allows you to have a LaTeX "hook" (or macro) attached to each "table sequence". Now you can add

newcommand{something}[1]{yng(#1)}

in your preamble and just call

input{temp.txt}

within your document where you want all the tables within temp.txt to appear. That is, there's no need to cycle through each element one-by-one and print it, since input will just throw the entire file in the input stream.

If you need a vertical gap between tables, perhaps use

newcommand{something}[1]{paraddvspace{medskipamount}yng(#1)}

Answered by Werner on May 8, 2021

Using catchfile as suggested by Werner, but with a twist:

begin{filecontents*}{jobname-1.yt}
{1,2,3}
end{filecontents*}

documentclass{article}
usepackage{youngtab}
usepackage{catchfile}

newcommand{yngfile}[1]{%
  CatchFileDef{yngfiledef}{#1}{}%
  expandaftermakeyngfileyngfiledef
}
newcommand{makeyngfile}[1]{yng(#1)}

begin{document}

yngfile{jobname-1.yt}

end{document}

Thus you can have as many files as you want. However, this would read the disk any time you need the same tableau.

begin{filecontents*}{jobname-1.yt}
{1,2,3}
end{filecontents*}

documentclass{article}
usepackage{youngtab}
usepackage{catchfile}

newcommand{yngfile}[1]{%
  ifcsname yngfiledef@#1endcsname
    % the file has already been loaded
  else
  CatchFileDeftemporaryyngfile{#1}{}%
  globalexpandafterletcsname yngfiledef@#1endcsnametemporaryyngfile
  fi
  expandafterexpandafterexpandaftermakeyngfilecsname yngfiledef@#1endcsname
}
newcommand{makeyngfile}[1]{yng(#1)}

begin{document}

yngfile{jobname-1.yt}quadyngfile{jobname-1.yt}

end{document}

If I compile this with the -recorder option, I see that the file is loaded just once.

enter image description here

The expl3 version:

begin{filecontents*}{jobname-1.yt}
{1,2,3}
end{filecontents*}

documentclass{article}
usepackage{youngtab}

ExplSyntaxOn

NewDocumentCommand{yngfile}{m}
 {
  stonek_yngfile:n { #1 }
 }

prop_new:N g_stonek_yngfile_prop
tl_new:N l__stonek_yngfile_tmp_tl

cs_new_protected:Nn stonek_yngfile:n
 {
  prop_if_in:NnF g_stonek_yngfile_prop { #1 }
   {% the file has not yet been read in
    file_get:nnN { #1 } { } l__stonek_yngfile_tmp_tl
    prop_gput:Nnx g_stonek_yngfile_prop { #1 }
     {
      exp_last_unbraced:NV __stonek_yngfile_fix:n l__stonek_yngfile_tmp_tl
     }
   }
  prop_item:Nn g_stonek_yngfile_prop { #1 }
 }
cs_new:Nn __stonek_yngfile_fix:n { exp_not:N yng(#1) }

ExplSyntaxOff

begin{document}

yngfile{jobname-1.yt}quadyngfile{jobname-1.yt}

end{document}

Answered by egreg on May 8, 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