I'd like to embed tokens inside a HERE DOCUMENT and then use (s)printf
on the final string to replace these tokens with actual values. The reason is: This makes it much easier to build a HERE DOCUMENT with some parts of it that are varying.
To explain, here is how I would do this in Python. From the small example below it will be more clear what I am trying to do. In Python r"""
is similar to Perl <<EOT
, i.e. it builds multi-line raw string. The string has to end with """
similar to Perl ending with EOT
.
s=r"""
\documentclass[12pt,titlepage]{article}
\begin{document}
\title{%(title)s}
\date{%(date)s}
some text
\end{document}"""
print s % {"title": "My report","date": "1/1/2016"}
The above prints
\documentclass[12pt,titlepage]{article}
\begin{document}
\title{My report}
\date{1/1/2016}
some text
\end{document}
Notice that the %(title)
and %(date)
were replaced at the end by values given. This is very similar to doing sprintf('%s',some_string)
, but here it is applied to the raw string itself. This is very handy and makes building raw string very easy.
Here is an MWE in Perl, but I am stuck on the last part, and I also do not know how to do the whole thing:
#!/usr/bin/perl -w
use strict;
use warnings;
my $title = "My report";
my $date = "1/1/2016";
my $s =<<'EOT';
\documentclass[12pt,titlepage]{article}
\begin{document}
\title{%(title)s}
\date{%(date)s}
some text
\end{document}
EOT
print($s); #how to format this in order to replace %title and %date
#emmbeded in $s with the values above? is it possible?
Make sure EOT
is leftmost and has no spaces after it.
I do not know if this is even possible in Perl. But I think if it is possible in Python, it should also be possible in Perl?
Please note that I can't use interpolation in HERE DOCUMENT, i.e. <<"EOT"
will not work for many reasons, and must use non interpolation HERE DOCUMENT. So something like this will not work for me:
my $s =<<"EOT";
\documentclass[12pt,titlepage]{article}
\begin{document}
\title{$title}
\date{$date}
some text
\end{document}
EOT
You may be over-complicating things. Yes Perl has sprintf
and yes you can specify the format string using a heredoc, but it would be much easier to just use variable interpolation:
#!/usr/bin/perl -w
use strict;
use warnings;
my $title = "My report";
my $date = "1/1/2016";
my $s =<<"EOT";
\documentclass[12pt,titlepage]{article}
\begin{document}
\title{$title}
\date{$date}
some text
\end{document}
EOT
print $s;
Note, I changed your single quotes around the EOT
to double quotes.
Normally you can just include a variable name in a double-quoted string, e.g.: "$title"
but if you need to follow that with a literal letter, number or underscore, then simply wrap curly braces around the variable name: "${title}_word"
.
To answer the question as asked, you could do:
#!/usr/bin/perl -w
use strict;
use warnings;
my $title = "My report";
my $date = "1/1/2016";
my $s =<<'EOT';
\documentclass[12pt,titlepage]{article}
\begin{document}
\title{%s}
\date{%s}
some text
\end{document}
EOT
printf($s, $title, $date);
Perl's sprintf
doesn't support named placeholders.
Edit: As @Nasser pointed out in a later comment my first example won't work as written, because changing from single to double quoting means that the backslashes need to be doubled up and any literal $
characters in the string would also need to be escaped.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With