从“数据库文本”文件中检索文本

从“数据库文本”文件中检索文本

我参考了我的问题和解决方案\ifthenelse 中的字符串比较我希望我能把我的问题说清楚,我不是技术人员。

我使用一种数据库文件(简单文本文件),其中包含翻译的根节,我可以从中检索到不同出版物中的单个节。在上面链接的问题中,有两种解决方案可以解析数据库并检索节。一种(A)基于 LaTeX2,另一种(B)基于 LaTeX3(xparse)。两者都在一定程度上完成了工作,并且两者都有不同的限制,我将尝试解释。也许您可以帮助修复其中一种以满足我的需求。

请查看 MWE。在我的“数据库”中,每个条目由一行文本组成。当找到某个键​​时,命令“mystanza”会格式化并打印值(节)以及两个§§之间的字符,请查看输出。

我遇到的问题是,在解决方案 A 中,数据库文本不能包含任何 LaTeX 命令。这意味着我无法格式化文本(例如,强调或在其中放置段落命令)。

(一)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}

(二)LaTeX3(xparser)

解决方案 B 针对我的数据库文件密钥的另一种格式编写:§2§~{text}现在是+1§2§||{}。使用更改后的密钥,它会产生错误(一个是由于我在密钥中更改为~||。不过,它对数据库文本中的 LaTeX 代码没有任何问题。

\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

这采用了不同的方法,使用readarray包。但是,它确实要求您的文件在节标识符和括号括起来的节之间stanzas.dat使用空格分隔符,而不是分隔符。||

\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}

在此处输入图片描述

相关内容