1

I have a latex file in which I would like to replace the content inside a \caption environment.

In particular, I want to use bold text and change the size. As an example:

%ORIGINAL
\caption{ Some text }
%...
\env2{ \caption{ Other text } }

to something like this

%NEW FILE
\caption{ \scriptsize\textbf{ Some text } }
%...
\env2 { \caption {\scriptsize\textbf{ Other text } } }

I am able to use sed to extract the text between the two patterns "\caption{" and the closing "}" as shown in this question: How to use sed/grep to extract text between two words?

And I am as well able to replace the inner text with a known string, as shown here : replace a unknown string between two known strings with sed

My question is: how do I keep the unknown strings inside the newly added environment, just using a single sed command and replacing only the surrounding strings ? Maybe something like:

START-PATTERN [new-environments] [Inner-text] [closing-brackets] END-PATTERN

Thank you.

Community
  • 1
  • 1
theleos
  • 123
  • 7
  • This has the potential to go horribly wrong if the caption contains an escaped `}` or goes onto multiple lines... – Tom Fenech Jan 08 '16 at 16:07
  • You are right, indeed I am having problems especially in the case of complex multiline text. I don't know if a simple solution may be found. – theleos Jan 08 '16 at 16:17
  • 1
    A better solution would be to change the style of your `\caption` environment. I'd recommend looking at how to do that. There's an example of something related here: http://tex.stackexchange.com/q/822/50142 – Tom Fenech Jan 08 '16 at 16:45

2 Answers2

1

Here goes the sed for your example.

sed 's/\\caption\s*{\([^}]*\)}/ \\caption {\\scriptsize\\textbf{ \1 } }/g'

Change it according to your need.

Explanation:

\\caption\s*{\([^}]*\)}

  • \\ matches the character \ literally
  • caption matches the characters caption literally
  • \s* match any white space character between zero and unlimited times
  • { matches the character { literally
  • ([^}]*) get everything until find } ,obs: capturing group
  • } matches the character } literally

\\caption {\\scriptsize\\textbf{ \1 } }

Replace the matched text by the text above, and put inside \textbf() the first group information matched (for example: some text or other text)

Felipe
  • 213
  • 1
  • 2
  • 12
1

Sed

This is a sed oneliner that works for monoline blocks handling escaped curly brackets (\{ or \}) correctly:

 sed -r 's/\\caption[ \t]*\{(([^\{}]|\\.)*)\}/\\caption\{\\scriptsize\\textbf\{\1\}\}/g' input.file

The per-line edit nature of sed does not allow this to work on multiline blocks.

Perl

To avoid this limitation you can use the same regex with perl (enabling slurp mode in the BEGIN block):

# Note double backslash \\ inside [...], not required in sed
perl -pe 'BEGIN{undef $/;} s/\\caption[ \t]*\{(([^\\{}]|\\.)*)\}/\\caption\{\\scriptsize\\textbf\{\1\}\}/g' input.file

Regex101 Demo

Input

%ORIGINAL
\caption{ \{Some text\}
    some other \{text\}
}
%...
\env2{ \caption{ Other text } }

Output

%ORIGINAL
\caption{\scriptsize\textbf{ \{Some text\}
    some other \{text\}
}}
%...
\env2{ \caption{\scriptsize\textbf{ Other text }} }
Giuseppe Ricupero
  • 6,134
  • 3
  • 23
  • 32