morelenmir has asked for the wisdom of the Perl Monks concerning the following question:

I am writing a very simple script to create template chapters for epub ebooks. Basically you run the script with a parameter that tells it how many chapters you want and it creates those, along with an appropriate series of entries to copy in to the OPF.

To do this I am using a 'heredoc' to hold the boilerplate template, which will be repeated for each chapter, using s///g to replace the various **** place holders as needed:

my $chapter_template=<<HERE; <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/T +R/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <meta http-equiv="Content-Type" content="application/xhtml+xml +; charset=utf-8" /> <link type="text/css" rel="stylesheet" href="..\css\style_shee +t.css" /> <title>*****ebook title goes here*****</title> <meta name="author" content="*****ebook author name(first, las +t) goes here*****" /> </head> <body> <h2 class="ebook" id="LinkID*****current link goes here*****"> +Chapter *****current chapter number goes here*****</h2> <p class="ebook">*****ebook content goes here onwards*****</p> </body> </html> HERE

As I understand it everything between '<<HERE;' and 'HERE' should be stored exactly as it appears in the script, ignoring any new lines or other formatting which might clash with native Perl statements. However when I run this I get a message saying 'unrecognised escape \s passed through at line 32', which seems to suggest the interpreter is reading and trying to execute the heredoc contents instead of simply storing them in the specified scalar.

Have I got the wrong end of the stick somewhere? Obviously I could just assign the heredoc contents directly to a variable, using escapes to insert the corresponding new lines and tabs and html formatting. However that gets very confusing very quickly and I thought the heredoc approach was meant to give a simpler 'wysiwig' method for doing this.

"Aure Entuluva!" - Hurin Thalion at the Nirnaeth Arnoediad.

Replies are listed 'Best First'.
Re: 'Here Documents' and unrecognized escapes
by Corion (Patriarch) on May 04, 2014 at 09:58 UTC

    A heredoc is "just" a string - see perlop on strings.

    In strings, the backslash is the universal escape - if you are using backslashes in your string, you have to double them.

    In your case, I would recommend to simply change the backslashes to forward slashes instead.

    As an alternative, I would store the templates in separate files instead of inlining them into the program.

Re: 'Here Documents' and unrecognized escapes
by Laurent_R (Canon) on May 04, 2014 at 10:27 UTC
    Normal strings created with single or double quotes (or q// and qq// operators) can be multiline:
    $ perl -le ' > use strict; > use warnings; > my $c = "multi line > content spanning > over three lines"; > print $c; > ' multi line content spanning over three lines
    But of course it would not be practical to use double quotes in your case, because you need double quotes within your template. However, single quotes or the q{} quote-like operator should be fine.

    Otherwise, using single quotes for introducing the 'HERE' tag will prevent any interpolation:

    use strict; use warnings; my $chapter_template=<<'HERE'; <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/T +R/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <meta http-equiv="Content-Type" content="application/xhtml+xml +; charset=utf-8" /> <link type="text/css" rel="stylesheet" href="..\css\style_shee +t.css" /> <title>*****ebook title goes here*****</title> <meta name="author" content="*****ebook author name(first, las +t) goes here*****" /> </head> <body> <h2 class="ebook" id="LinkID*****current link goes here*****"> +Chapter *****current chapter number goes here*****</h2> <p class="ebook">*****ebook content goes here onwards*****</p> </body> </html> HERE ; print $chapter_template;
    This happily prints the content of the here doc.

      MANY thanks - that sorts it out entirely! I shall give the 'template' library a look over as well as it may offer a better total solution

      "Aure Entuluva!" - Hurin Thalion at the Nirnaeth Arnoediad.
Re: 'Here Documents' and unrecognized escapes
by GrandFather (Saint) on May 04, 2014 at 10:39 UTC

    If you are using a regex in a search and replace on the template then ~~~~~ may be a better search sting than ***** because it doesn't need quoting in the regex.

    Perl is the programming world's equivalent of English
Re: 'Here Documents' and unrecognized escapes
by Anonymous Monk on May 04, 2014 at 11:32 UTC
    In the long run, a tool like Template would probably be much more satisfactory.

      I have done some reading of the manual pages that come with 'Template' and it seems pretty well suited to my needs. However one issue which makes it a little less than ideal is the fact it seems to require the template to be a separate text file, marked up apropriately. Have I got that right? Or can you use a string instead with the same markup? I suppose I could always write a temporary template file on the fly FROM a variable and then delete it when i am done... That feels like it defeats the object though!

      "Aure Entuluva!" - Hurin Thalion at the Nirnaeth Arnoediad.

        The second example in the Template Toolkit documentation shows how to pass it a string for the template:

        # text reference $text = "[% INCLUDE header %]\nHello world!\n[% INCLUDE footer %]" +; $tt->process(\$text) || die $tt->error(), "\n";

      I shall check that library out!

      "Aure Entuluva!" - Hurin Thalion at the Nirnaeth Arnoediad.