sedを使用したLatex段落の書式設定

sedを使用したLatex段落の書式設定

私はsedLaTeXを使ってコンパイルするために複数のプレーンテキストファイルのフォーマットを再指定することをしています。ファイルには、範囲を提供するキーワードを含むセクションが含まれています。私が取り組んでいる部分の1つは賛美歌です。賛美歌はキーワードで始まり、Hymn単語で終わります。Amen. 賛美歌の本文は、「節」の文脈に従って形式を取る必要があります。

以下はサンプル入力ファイルです。

Hymn I
Conditor alme siderum,
Aeterna lux credentium,
Christe, redemptor omnium,
Exaudi preces supplicum.

Qui condolens interitu
Mortis perire saeculum,
Salvasti mundum languidum,
Donans reis remedium.

Vergente mundi vespere,
Uti sponsus de thalamo,
Egressus honestissima
Virginis matris clausula. Amen.

Hymn II
...
... Amen.

ファイルが次のようになります。

\small{\uppercase{Hymn I}}\normalsize
\begin{verse}
Conditor alme siderum,\\
Aeterna lux credentium,\\
Christe, redemptor omnium,\\
Exaudi preces supplicum.\\!

Qui condolens interitu\\
Mortis perire saeculum,\\
Salvasti mundum languidum,\\
Donans reis remedium.\\!

Vergente mundi vespere,\\
Uti sponsus de thalamo,\\
Egressus honestissima\\
Virginis matris clausula. Amen.\\!
\end{verse}
\small{\uppercase{Hymn II}}\normalsize
\begin{verse}
...\\
... Amen.\\!
\end{verse}

私はそのほとんどを見つけることができました。しかし、sed複数行を使用して段落の書式を正しく指定する方法を知りたいです。

sed '/Hymn/,/Amen/ { /Hymn\|Amen/ !{...' 私はAndHまたはアプローチを試しましたが、N決して正しく動作しないようです。

答え1

このような:

sed '/Hymn/,/Amen/{                                 # in this range
/Hymn/{                                             # if line matches Hymn
s/.*/\\small\{\\uppercase\{&\}\}\\normalsize/       # replace as required
h                                                   # copy over the hold space
s/.*/\\begin\{verse\}/                              # replace with \begin{verse}
H                                                   # append to hold space
d                                                   # delete the line
}
/Amen/!{                                            # if line doesn't match Amen 
/^$/!{                                              # and if line is not empty
s/$/\\\\/                                           # add trailing \\
}
H                                                   # append to hold space
d                                                   # then delete line
}
//{                                                 # if line matches Amen
s/$/\\\\!/                                          # add trailing \\!
H                                                   # append to hold space
s/.*/\\end\{verse\}/                                # replace with \end{verse}
H                                                   # append to hold space
s/.*//                                              # empty pattern space
x                                                   # exchange buffers
s/\n\n/!&/g                                         # add ! at end of each para
}
}
' infile

または2行を好む場合gnu sed

sed '/Hymn/,/Amen/{/Hymn/{s/.*/\\small\{\\uppercase\{\&\}\}\\normalsize/;h;s/.*/\\begin\{verse\}/;H;d}
/Amen/!{/^$/!{s/$/\\\\/};H;d};//{s/$/\\\\!/;H;s/.*/\\end\{verse\}/;H;s/.*//;x;s/\n\n/!&/g}}' infile

出力例:

\small{\uppercase{Hymn I}}\normalsize
\begin{verse}
Conditor alme siderum,\\
Aeterna lux credentium,\\
Christe, redemptor omnium,\\
Exaudi preces supplicum.\\!

Qui condolens interitu\\
Mortis perire saeculum,\\
Salvasti mundum languidum,\\
Donans reis remedium.\\!

Vergente mundi vespere,\\
Uti sponsus de thalamo,\\
Egressus honestissima\\
Virginis matris clausula. Amen.\\!
\end{verse}

\small{\uppercase{Hymn II}}\normalsize
\begin{verse}
...\\
... Amen.\\!
\end{verse}

答え2

perl短絡モードで使用します。

#!/usr/bin/env perl
# Usage: thisprogram < inputfile > outputfile
use strict;
use warnings;
use feature qw(say);

$/ = "\n\n";    # paragraph mode

while (<>) {
  # nuke last \n of paragraph due to
  s/[\n]+\z//;
  # the need to replace the mid-verse newlines with \\
  s/\n/\\\\\n/g;
  # and now actually undo that while working on the first line
  s/(Hymn \w+)[\\]+/\\small{\\uppercase{$1}}\\normalsize\n\\begin{verse}/;
  # and at the newline-free end of the paragraph, tack on the \\! bit
  s/\z/\\\\!/;
  # emit
  say;
  if (m/Amen\./) {
    say "\\end{verse}\n";
  } else {
    print "\n";
  }
}

関連情報