2

I refer to my question and the solutions in String comparison in \ifthenelse I hope I can make my question clear enough, I am not a technician.

I use a kind of database file (simple text file) with root stanzas of a translation from which I can retrieve individual stanzes into different publications. In the above linked question there are two solutions to parse the database and retrieve the stanzas. One (A) is based on LaTeX2 and one (B) on LaTeX3 (xparse). Both do the job to a certain extend and with both I have different limitations, as I will try to explain. Maybe you could help to fix one of the two to fit my needs.

Please look at the MWE. In my "database", each entry consists of one line of text. When a certain key is found, the command 'mystanza' formats and prints the value (the stanza) and also the characters between the two §§, just look at the output please.

The problem that I have is that in solution A the database text must not contain any LaTeX-command. That means I cannot format the text (emphasize, for example, or put a paragraph command in it).

(A) LaTeX2

\documentclass[a4paper,12pt]{article}

\usepackage{filecontents}
\begin{filecontents*}{stanzas.dat}

+1§1§||{This is stanza one from chapter one.}

+2§2§||{This is stanza two from chapter two.}

+3§3§||{This is stanza three from chapter three.}

+4§4§||{This is stanza four from chapter four. But there is problem with \emph{formatting} text.}

\end{filecontents*}

\usepackage{fontspec}
\defaultfontfeatures{Mapping=tex-text} % 
\usepackage{polyglossia} 
\setdefaultlanguage[spelling=new, babelshorthands=true]{german}

\usepackage{xstring}
\usepackage{xifthen}
\usepackage{stringstrings}

\newcommand*{\isinxp}[2]{\expandafter\isinxpp\expandafter{#2}{#1}}
\newcommand*{\isinxpp}[2]{\isin {#2}{#1}}

\newread\dbroot

\newcommand{\mystanza}[1]{%
\openin\dbroot=stanzas.dat
{\loop
   \endlinechar=-1
    \read\dbroot to \dbline
    \unless\ifeof\dbroot
    \ifthenelse{\isinxp{#1}{\dbline}}
    {\StrCut{\dbline}{||}{\colA}{\colB}%
    (\StrBetween[1,2]{\colA}{§}{§})~{\colB}}%
    {}%
\repeat}%
\closein\dbroot
}

\begin{document}

\mystanza{+1§1§} 

\mystanza{+2§2§}

\mystanza{+3§3§}

% \mystanza{+4§4§} % <-- problematic

\end{document}

(B) LaTeX3 (xparse)

Solution B was written for another format of the key of my database file: §2§~{text} is now +1§2§||{}. With the altered key, it generates errors (one is due to my changeing ~ to || in the key). It does have no problems with LaTeX-code in the database text, though.

\documentclass[a4paper,12pt]{article}

\usepackage{filecontents}
\begin{filecontents*}{morestanzas.dat}

§1§~{This is stanza one from \emph{chapter} one.}

§2§||{This is stanza two from chapter two.}

+3§3§||{This is stanza three from \emph{chapter} three.}

\end{filecontents*}


\usepackage{xparse}

\ExplSyntaxOn
% generic command
\NewDocumentCommand{\printdata}{ mm }
 {% #1 is the file name, #2 is the key to test
  \christof_printdata:nn { #1 } { #2 }
 }
% with fixed file name
\NewDocumentCommand{\mystanza}{ m }
 {
  \printdata{morestanzas.dat} { #1 } % <---  file name
 }

\ior_new:N \g_christof_data_stream
\seq_new:N \l__christof_entry_seq

\cs_new_protected:Npn \christof_printdata:nn #1 #2
 {
  \ior_open:Nn \g_christof_data_stream { #1 }
  \ior_map_inline:Nn \g_christof_data_stream
   {
    \tl_if_in:nnT { ##1 } { #2 }
     {
      \__christof_process_line:ww ##1 \q_stop
     }
   }
 }

\group_begin:
\char_set_catcode_active:N \^^A
\char_set_lccode:nn { `\^^A } { `\~ }
\tl_to_lowercase:n 
 {
  \group_end:
  \cs_new_protected:Npn \__christof_process_line:ww §#1§ ^^A #2 \q_stop
 }
 {% #1 is the key, #2 is the value
  (#1) \nobreakspace \tl_trim_spaces:n { #2 }
 }
\ExplSyntaxOff


\begin{document}

\mystanza{§1§} 

% \mystanza{§2§} <--- problem 1

% \mystanza{§3§} <--- problem 2

\end{document}
1

This takes a different approach, using the readarray package. It does, however, require your stanzas.dat file to use a space separator, rather than a || separator, between the stanza identifier and the brace-enclosed stanza.

\documentclass[a4paper,12pt]{article}
\usepackage[T1]{fontenc}
\usepackage{readarray,ifthen}
\usepackage{filecontents}
\begin{filecontents*}{stanzas.dat}
+1§1§ {This is stanza one from chapter one.}
+2§2§ {This is stanza two from chapter two.}
+3§3§ {This is stanza three from chapter three.}
+4§4§ {This is stanza four from chapter four. And there is no longer a problem with \emph{formatting} text.}
\end{filecontents*}

\readdef{stanzas.dat}{\stanzas}
\readArrayij{\stanzas}{stz}{2}
\newcounter{sindex}
\newcommand\mystanza[1]{%
  \setcounter{sindex}{0}%
  \whiledo{\thesindex < \stzROWS\relax}{%
    \stepcounter{sindex}%
    \ifthenelse{\equal{\arrayij{stz}{\thesindex}{1}}{#1}}%
    {\arrayij{stz}{\thesindex}{2}}{}%
  }%
}

%\usepackage{fontspec}
%\defaultfontfeatures{Mapping=tex-text} % 
%\usepackage{polyglossia} 
%\setdefaultlanguage[spelling=new, babelshorthands=true]{german}
\begin{document}
This shows how the data is stored:

Element(3,1): \arrayij{stz}{3}{1} 

Element(3,2): \arrayij{stz}{3}{2}

Number of rows: \stzROWS

Here is what you want

\mystanza{+1§1§}

\mystanza{+3§3§}

\mystanza{+4§4§}

\mystanza{+2§2§}
\end{document}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.