Latex - 对字符串中的每个字符应用操作

时间:2010-03-16 20:16:27

标签: latex

我正在使用LaTeX,我遇到了有关字符串操作的问题。 我希望将一个操作应用于字符串的每个字符,特别是 我想用“\ discretionary {} {} {} x”替换每个字符“x”。我想要做 这是因为我有一个长串(DNA),我希望能够分开 没有连字符的任何一点。

因此,我希望有一个名为“myDNA”的命令,而不是为我做这个 在每个角色后面手动插入\ discretionary {} {} {}。

这可能吗?我环顾网络,并没有多大帮助 关于这个主题的信息(至少不是我能理解的),我希望如此 你可以帮忙。

- 编辑 澄清: 我想在完成的文档中看到的是这样的:


    the dna sequence is CTAAAGAAAACAGGACGATTAGATGAGCTTGAGAAAGCCATCACCACTCA
    AATACTAAATGTGTTACCATACCAAGCACTTGCTCTGAAATTTGGGGACTGAGTACACCAAATACGATAG
    ATCAGTGGGATACAACAGGCCTTTACAGCTTCTCTGAACAAACCAGGTCTCTTGATGGTCGTCTCCAGGT
    ATCCCATCGAAAAGGATTGCCACATGTTATATATTGCCGATTATGGCGCTGGCCTGATCTTCACAGTCAT
    CATGAACTCAAGGCAATTGAAAACTGCGAATATGCTTTTAATCTTAAAAAGGATGAAGTATGTGTAAACC
    CTTACCACTATCAGAGAGTTGAGACACCAGTTTTGCCTCCAGTATTAGTGCCCCGACACACCGAGATCCT
    AACAGAACTTCCGCCTCTGGATGACTATACTCACTCCATTCCAGAAAACACTAACTTCCCAGCAGGAATT

只是简单的换行符,没有任何连字符。 DNA序列将是一个 没有任何空格或任何东西的长字符串,但它可以在任何点断开。 这就是为什么我的想法是在每次之后“酌情{} {} {}” 字符,以便它可以在任何点断开而不插入任何连字符。

4 个答案:

答案 0 :(得分:6)

这会将字符串作为参数,并在每个字符后调用\discretionary{}{}{}。输入字符串在第一个美元符号处停止,因此您不应该使用它。

\def\hyphenateWholeString #1{\xHyphenate#1$\wholeString}

\def\xHyphenate#1#2\wholeString {\if#1$%
\else\say{#1}\discretionary{}{}{}%
\takeTheRest#2\ofTheString
\fi}

\def\takeTheRest#1\ofTheString\fi
{\fi \xHyphenate#1\wholeString}

\def\say#1{#1}

你称之为\ hyphenateWholeString {CTAAAGAAAACAGGACG}。

而不是\ discretionary {} {} {}你可以尝试\ hspace {0pt},如果你更喜欢(并且在乳胶环境中)。为了调整正确的边距,我认为你需要做一些更精细的调整(但见下文)。当然,使用固定宽度的字体可以最小化效果。

<强>修订:

\def\hyphenateWholeString #1{\xHyphenate#1$\wholeString\unskip}

\def\xHyphenate#1#2\wholeString {\if#1$%
\else\transform{#1}%
\takeTheRest#2\ofTheString\fi}

\def\takeTheRest#1\ofTheString\fi
{\fi \xHyphenate#1\wholeString}

\def\transform#1{#1\hskip 0pt plus 1pt}

史蒂夫建议使用\hskip听起来对我来说是个好主意,所以我做了一些修改。请注意,我已重命名\say宏并使其更有用,因为它现在实际上进行了转换。 (但是,如果您从\hskip移除\transform,则还需要删除主宏定义中的\unskip


修改

还有seqsplit包似乎用于打印DNA数据或长数字。它们还带来了一些更好的输出选项,所以也许这就是你正在寻找的......

答案 1 :(得分:3)

尽管\say没有必要,但Debilski的帖子绝对是一种可行的方式。这是使用一些LaTeX内部快捷方式(\@gobble\@ifnextchar)的简短方法:

\makeatletter
\def\hyphenatestring#1{\xHyphen@te#1$\unskip}
\def\xHyphen@te{\@ifnextchar${\@gobble}{\sw@p{\hskip 0pt plus 1pt\xHyphen@te}}}
\def\sw@p#1#2{#2#1}
\makeatother

请注意使用\hskip 0pt plus 1pt代替\discretionary - 当我尝试您的示例时,我最终得到了一个粗糙的边距,因为没有可拉伸性。 \hskip在每个字符之间添加一些可伸缩的粘合剂(\unskip之后取消我们添加的额外的一个)。另请注意LaTeX样式约定“最终用户”宏都是小写的,而内部宏在其中有一个@,以便用户不会意外地调用它们。

如果你想弄清楚它是如何工作的,\@gobble只是吃它前面的任何东西(在这种情况下是$,因为那个分支只在$\sw@p时运行下一个字符)。重点是$只在“else”分支中给出一个参数,因此它将该参数与下一个char(不是\def\hyphenate#next#1{#1\hskip...\xHyphen@te})交换。我们也可以编写\sw@p并在“else”分支中没有args,但是(在我看来){{1}}更通用(我很惊讶它不在标准的LaTeX中的话)。

答案 2 :(得分:0)

contrib package on CTAN处理排版DNA序列。它不仅仅是断行,例如,它还支持着色。我不确定是否有可能得到你想要的输出,我没有DNA序列排版领域的经验,但是一个长字符串是最可读的表示?

答案 3 :(得分:-2)

  1. 假设您的字符串相同,请在序言中使用\newcommand{}{}。像这样: \newcommand{\myDNA}{blah blah blah}
  2. 如果不满足您的要求,我建议: 2.将字符串分解为最小部分,然后使用\newcommand然后按顺序调用新命令:\myDNA1 \myDNA2

    如果仍然无效,您可能需要编写一个perl脚本来满足您的字符串替换需求。