Here document: Difference between revisions

From Rosetta Code
Content added Content deleted
(Here docs in PowerShell)
Line 448: Line 448:
### This is after the text ###
### This is after the text ###
</pre>
</pre>

=={{header|PowerShell}}==

In PowerShell, here-docs are known as "Here-Strings".
The Key is the At symbol @.

<lang PowerShell>
$XMLdata=@"
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
<servicing>
<package action="configure">
<assemblyIdentity name="Microsoft-Windows-Foundation-Package" version="${strFullVersion}" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="" />
<selection name="RemoteServerAdministrationTools" state="true" />
<selection name="RemoteServerAdministrationTools-Roles-AD" state="true" />
<selection name="RemoteServerAdministrationTools-Roles-AD-DS" state="true" />
<selection name="RemoteServerAdministrationTools-Roles-AD-DS-SnapIns" state="true" />
<selection name="RemoteServerAdministrationTools-Features-StorageManager" state="true" />
<selection name="RemoteServerAdministrationTools-Features-Wsrm" state="true" />
</package>
</servicing>
<cpi:offlineImage cpi:source="wim:d:/2008r2wim/install.wim#Windows Server 2008 R2 SERVERSTANDARD" xmlns:cpi="urn:schemas-microsoft-com:cpi" />
</unattend>
"@
</lang>


=={{header|Python}}==
=={{header|Python}}==

Revision as of 16:59, 10 February 2012

Task
Here document
You are encouraged to solve this task according to the task description, using any language you may know.

A here document (or "heredoc") is a way of specifying a text block, preserving the line breaks, indentation and other whitespace within the text. Depending on the language being used a here document is constructed using a command followed by "<<" (or some other symbol) followed by a token string. The text block will then start on the next line, and will be followed by the chosen token at the beginning of the following line, which is used to mark the end of the textblock.

The task is to demonstrate the use of here documents within the language.

ALGOL 68

Works with: ALGOL 68 version Revision 1 - no extensions to language used.
Works with: ALGOL 68G version Any - tested with release 1.18.0-9h.tiny.

Algol 68 does not have a "heredoc" feature. It can be crudely achieved using an array of strings:

<lang algol68>#!/usr/local/bin/a68g --script #

[]STRING help = ( "Usage: thingy [OPTIONS]", " -h Display this usage message", " -H hostname Hostname to connect to" );

printf(($gl$,help,$l$));

printf(($gl$, "The river was deep but I swam it, Janet.", "The future is ours so let's plan it, Janet.", "So please don't tell me to can it, Janet.", "I've one thing to say and that's ...", "Dammit. Janet, I love you." )) </lang>

Output:

Usage: thingy [OPTIONS]
     -h                        Display this usage message
     -H hostname               Hostname to connect to

The river was deep but I swam it, Janet.
The future is ours so let's plan it, Janet.
So please don't tell me to can it, Janet.
I've one thing to say and that's ...
Dammit. Janet, I love you.

AutoHotkey

AutoHotkey uses "continuation sections" for literal text:

<lang AutoHotkey>MyVar = "This is the text inside MyVar" MyVariable = (

  Note that whitespace is preserved
  As well as newlines.
  The LTrim option can be present to remove left whitespace.
  Variable references such as %MyVar% are expanded.

) MsgBox % MyVariable</lang>

C#

C# has a string literal call which is used for heredoc functionality

<lang C sharp>using System;

class Program {

   static void Main(string[] args)
   {
       Console.Write(@"

multiline strings are easy to put together in C#");

   }

}</lang>

CoffeeScript

CoffeeScript borrows the triple-quoted string syntax from Python. Note that these strings strip leading whitespace in CoffeeScript, to allow you to neatly align the heredoc string.

<lang coffeescript>myDoc =

       Single-quoted heredocs allows no '#{foo}' interpolation.
       This behavior is similar to single-quoted strings.
       

doc2 = """

       However, double-quoted heredocs *do* allow these.
       See it in action:
           Content: "#{myDoc}"
       """

console.log doc2</lang>

The above would output the following:

However, double-quoted heredocs *do* allow these.
See it in action:
    Content: "Single-quoted heredocs allows no '#{foo}' interpolation.
This behavior is similar to single-quoted strings."

Note how the extra indentation in the third line of doc2 is preserved.

D

Works with: D version 2

In D there are delimited strings: a 'q' followed by double quotes and an opening and closing delimiter of choice: <lang d>auto s = q"[a string that you "don't" have to escape]";</lang>

If the delimiter is an identifier, the identifier must be immediately followed by a newline, and the matching delimiter is the same identifier starting at the beginning of the line:

<lang d>writefln(q"EOS This is a multi-line heredoc string EOS" );</lang>

a string you " " don't have to escape

This
is a multi-line
heredoc string

Forth

Works with: GForth

<lang Forth>\ GForth specific words: \ under+ ( a b c -- a+c b) , latest ( -- nt ) , name>string ( nt -- ca u ) \ Should not be a problem to modify it to work with other Forth implementation:

$! ( ca u -- a )
 dup >R dup , here swap move R> allot ;
$@ ( a -- ca u )
 dup @ 1 cells under+ ;
c!+ ( c ca - ca+1 )
 tuck c! 1+ ;
$!+ ( a u a' -- a'+u ; string-store-plus )
 2dup + >R swap move R> ;

\ --- UNIX end-of-line adapted words 10 constant EOL

input-fix ( -- ; for interactive use ! )
 source-id 0= IF cr THEN ;
get_line ( -- ca u ) EOL parse input-fix ;
EOL!+ ( a -- a' ; eol-store-plus ) EOL swap c!+ ;
EOD ( -- ca u ; end-of-doc )
 latest name>string ;
>> ( "doc-name" "doc-body" -- ) input-fix
 CREATE 0 ,              \ post body length
 here dup >R
 BEGIN  refill >R
        get_line 2dup EOD compare
        R> AND	          \ notEOD && input-stream ->
 WHILE  rot $!+ EOL!+
 REPEAT 2drop
 R> tuck - dup allot
 swap -1 cells + !       \ fixup body length
 DOES>  ( -- ca u )  $@ ;

\ TEST ; excerpt from Project Gutenberg 'Alice in Wonderland'

>> ALICE CHAPTER I. Down the Rabbit-Hole

Alice was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it, 'and what is the use of a book,' thought Alice 'without pictures or conversation?' ALICE >> RABBIT RABBIT ALICE type ." --" cr RABBIT type</lang>

CHAPTER I. Down the Rabbit-Hole

Alice was beginning to get very tired of sitting by her sister on the
bank, and of having nothing to do: once or twice she had peeped into the
book her sister was reading, but it had no pictures or conversations in
it, 'and what is the use of a book,' thought Alice 'without pictures or
conversation?'
--

Go

Go does not have here documents. Multiline string literals serve this purpose.

<lang go>var m = ` leading spaces

and blank lines`</lang>

Groovy

Groovy has two types of multi-line strings, which behave similarly to "here documents"

Multi-line String literal

The literal text, preserving lines and spacing <lang groovy>println Time's a strange fellow;

                       more he gives than takes

(and he takes all) nor any marvel finds quite disappearance but some keener makes losing, gaining

              --love! if a world ends

</lang>

Output:

Time's a strange fellow;
                        more he gives than takes
(and he takes all) nor any marvel finds
quite disappearance but some keener makes
losing, gaining
               --love! if a world ends

Multi-line GString expression

Like single-line GString expressions, any subexpression delimited with ${ } is substituted with its "toString()" value. Preserves lines and spacing outside of the subexpressions. <lang groovy>def expired='defunct' def horse='stallion' def christ='Jesus'

println """ Buffalo Bill's

             ${expired} 
                         who used to 
                         ride a watersmooth-silver 
                                                                 ${horse} 
             and break onetwothreefourfive pigeonsjustlikethat 
                                                                                          ${christ}
             he was a handsome man 
                                                   and what i want to know is 
             how do you like your blueeyed boy 
             Mister Death

"""</lang>

Output:

Buffalo Bill's 
              defunct 
                          who used to 
                          ride a watersmooth-silver 
                                                                  stallion 
              and break onetwothreefourfive pigeonsjustlikethat 
                                                                                           Jesus

              he was a handsome man 
                                                    and what i want to know is 
              how do you like your blueeyed boy 
              Mister Death

J

<lang j>here=:0 :0

 0 :0 will be replaced by the text on the following lines.
 This is three tokens: two instances of the number 0 and
 one instance of the explicit definition token ':'.
 Any indentation in the here document will be retained in the result.
 There must be a space to the left of : or it will combine with the
 0 on its left to form the token 0: which is something completely 
 different.
 The here document is terminated by a line which contains only a
 single right parenthesis ')' and optional white space.  In J's
 documentation the family of entities which include here documents
 (and verb definitions and so on) are called 'scripts'.
 When several scripts are referenced on the same line, they are used
 sequentially in an order determined by their appearance on the line.
 The leftmost 'script' reference gets the last script and the rightmost
 reference gets the first script.  But this is a rare usage.
 Typically, such values are assigned a name so that they can be
 used later.  However, they may also be discarded and/or ignored, in
 which case they are logically equivalent to multi-line comments.

)

and_here=:noun define

 'noun define' is an alternative and perhaps more "user friendly"
 way of declaring a here document.  It achieves the same thing as
 0 :0 and in fact 'noun' has the value 0 and 'define' has the value :0
 And, of course, there must be a space between the word 'noun' and
 the word 'define'.
 Other useful alternatives include verb (which has the value 3)
 and dyad (which has the value 4), and adverb (which has the value 1).
 In other words 'verb define' (if unquoted) would be replaced by a 
 verb whose definition is provided in the following 'script'.
 However, all of these names are normal variables which can
 be declared to have different values by the developer.  And, of course,
 note that this mechanism is significantly more verbose than using
 the underlying 0 :0 mechanism directly.

)</lang>

NMAKE.EXE

<lang nmake.exe>target0: dependent0

   command0 <<

temporary, discarded inline file ... <<

target1: dependent1

   command1 <<

temporary, but preserved inline file ... <<KEEP

target2: dependent2

   command2 <<filename2

named, but discarded inline file ... <<NOKEEP

target3: dependent3

   command3 <<filename3

named and preserved inline file ... <<KEEP</lang>

NewLISP

<lang NewLISP>; here-document.lsp

oofoe 2012-01-19
http://rosettacode.org/wiki/Here_document

(print (format [text]

   Blast it %s! I'm a %s,
   not a %s!
      --- %s

[/text] "James" "magician" "doctor" "L. McCoy"))

(exit)</lang>

Sample output:

    Blast it James! I'm a magician,
    not a doctor!
       --- L. McCoy

Perl

In Perl, there must not be a space between the "<<" and the token string. The ending token must always be the entire end line (i.e. no surrounding spaces) for it to be recognised. Interpolation is allowed, like a double-quoted string:

<lang perl>$address = <<END; 1, High Street, $town_name, West Midlands. WM4 5HD. END</lang>

If the token string contains spaces, the token after the "<<" must be quoted; otherwise the double-quotes is implicit: <lang perl>$pancake = <<"NO MORE INGREDIENTS"; egg milk flour NO MORE INGREDIENTS</lang>

It is possible to make a here-document that behaves differently than a double-quoted string, by applying a different kind of quoting to the token. For example, if you use single quotes, then the here document will not support interpolation, like a normal single-quoted string:

<lang perl>$x = <<'FOO'; No $interpolation here FOO</lang>

Alternately, you can use backticks to cause the here document to be executed and the result returned, just like a normal backtick operator:

<lang perl>$output = <<`BAR`; ls /home BAR</lang>

Note that in the above examples, that a semicolon was left after the here document's token string. This is because (unlike PHP) the here document does not start immediately at the "<<END" token -- it starts on the next line. The "<<END" is actually an expression, whose value will be substituted by the contents of the here document. The "<<END" must still live inside a valid statement on the line that it's used. To further illustrate this fact, we can use the "<<END" inside a complex, nested expression:

<lang perl>print(<<EOF . "lamb\n"); Mary had

 a little

EOF</lang>

Although, technically speaking, it is also possible to break a statement into two parts, with the here document in the middle (i.e. continue the statement on the line after the terminating token). However, please don't do this.

<lang perl>print(<<EOF Mary had

 a little

EOF

  . "lamb\n");</lang>

Perl 6

Heredocs in Perl 6 use the :to modifier to a quoting operator, such as q or qq. Multiple here docs may be stacked on top of each other.

Works with: niecza

<lang perl6>my $contrived_example = 'Dylan'; sub freewheelin() {

       print q :to 'QUOTE', '-- ', qq :to 'AUTHOR';
         I'll let you be in my dream,
           if I can be in yours.
       QUOTE
               Bob $contrived_example
               AUTHOR

}

freewheelin;</lang>

Output:

  I'll let you be in my dream,
    if I can be in yours.
-- Bob Dylan

PHP

In PHP, the here document symbol is 3 less-than signs, not two: <<<

There must not be a space between the "<<<" and the token string. The ending token must always be the entire end line (i.e. no surrounding spaces) for it to be recognised, except for a possible semicolon. Interpolation is allowed, like a double-quoted string:

<lang php>$address = <<<END 1, High Street, $town_name, West Midlands. WM4 5HD. END;</lang>

In PHP 5.3+, it is possible to make a here-document that does not interpolate (PHP calls this a "nowdoc"), by surrounding the token with single-quotes (like in Perl):

<lang php>$x = <<<'FOO' No $interpolation here FOO;</lang>

PicoLisp

We can use the 'here' function:

<lang PicoLisp>(out "file.txt" # Write to "file.txt"

  (prinl "### This is before the text ###")
  (here "TEXT-END")
  (prinl "### This is after the text ###") )

"There must be some way out of here", said the joker to the thief "There's too much confusion, I can't get no relief" TEXT-END

(in "file.txt" (echo)) # Show "file.txt"</lang>

Output:

### This is before the text ###
"There must be some way out of here", said the joker to the thief
"There's too much confusion, I can't get no relief"
### This is after the text ###

PowerShell

In PowerShell, here-docs are known as "Here-Strings". The Key is the At symbol @.

<lang PowerShell> $XMLdata=@" <?xml version="1.0" encoding="utf-8"?> <unattend xmlns="urn:schemas-microsoft-com:unattend">

   <servicing>
       <package action="configure">
           <assemblyIdentity name="Microsoft-Windows-Foundation-Package" version="${strFullVersion}" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="" />
           <selection name="RemoteServerAdministrationTools" state="true" />
           <selection name="RemoteServerAdministrationTools-Roles-AD" state="true" />
           <selection name="RemoteServerAdministrationTools-Roles-AD-DS" state="true" />
           <selection name="RemoteServerAdministrationTools-Roles-AD-DS-SnapIns" state="true" />
           <selection name="RemoteServerAdministrationTools-Features-StorageManager" state="true" />
           <selection name="RemoteServerAdministrationTools-Features-Wsrm" state="true" />
       </package>
   </servicing>
   <cpi:offlineImage cpi:source="wim:d:/2008r2wim/install.wim#Windows Server 2008 R2 SERVERSTANDARD" xmlns:cpi="urn:schemas-microsoft-com:cpi" />

</unattend> "@ </lang>

Python

Python does not have here-docs. It does however have triple-quoted strings which can be used similarly.

<lang python>print("""\ Usage: thingy [OPTIONS]

    -h                        Display this usage message
    -H hostname               Hostname to connect to

""")</lang>

Retro

Retro does not have a builtin here document. It does support multiline strings:

<lang Retro>"This is

 a multi-line string
   with indention

and such"</lang>

If you need an actual heredoc function, the following should suffice:

<lang Retro>{{

 : getDelimiter ( "-$ )
   getToken keepString cr ;
 : prepare      ( -$ )
   remapping off "" tempString ;
 : readLine     ( "-$ )
   10 accept tib ;
 : append?      ( $$-$$f )
   [ over ] dip  compare [ 0 ] [ tib ^strings'append 10 ^strings'appendChar -1 ] if ;

---reveal---

 : heredoc ( "-$ )
   heap [ remapping [ getDelimiter prepare [ readLine append? ] while nip ] preserve ] preserve ;

}}

heredoc [END] 1 2 3

 4 5 6
   7 8 9

[END]</lang>

Ruby

In Ruby, there must not be a space between the "<<" and the token string. The ending token must always be the entire end line (i.e. no surrounding spaces) for it to be recognised, unless you use "<<-" instead of "<<", in which case indentation before the ending token is allowed. Interpolation is allowed, like a double-quoted string:

<lang ruby>address = <<END 1, High Street,

  1. {town_name},

West Midlands. WM4 5HD. END</lang>

If the token string contains spaces, the token after the "<<" must be quoted; otherwise the double-quotes is implicit:

<lang ruby>pancake = <<"NO MORE INGREDIENTS" egg milk flour NO MORE INGREDIENTS</lang>

It is possible to make a here-document that behaves differently than a double-quoted string, by applying a different kind of quoting to the token. For example, if you use single quotes, then the here document will not support interpolation, like a normal single-quoted string:

<lang ruby>x = <<'FOO' No

  1. {interpolation}

here FOO</lang>

Alternately, you can use backticks to cause the here document to be executed and the result returned, just like a normal backtick operator:

<lang ruby>output = <<`BAR` ls /home BAR</lang>

The here document does not start immediately at the "<<END" token -- it starts on the next line. The "<<END" is actually an expression, whose value will be substituted by the contents of the here document. The "<<END" must still live inside a valid statement on the line that it's used. To further illustrate this fact, we can use the "<<END" inside a complex, nested expression:

<lang ruby>puts <<EOF + "lamb" Mary had

 a little

EOF</lang>

Tcl

<lang tcl>set hereDocExample { In Tcl, the {curly brace} notation is strictly a here-document style notation as it permits arbitrary content inside it *except* for an unbalanced brace. That is typically not a problem as seen in reality, as almost all content that might be placed in a here-doc is either brace-free or balanced. The content of the braces is not interpreted at all; no substitutions are performed on it.

The sole exception is that there is limited processing of backslashes; a single backslash at the end of a line causes the end-of-line plus all whitespace at the start of the next line to be compressed to a single space. }</lang>

If substitution is desired within the document, it should either be written inside "double quotes" (instead of {braces}) or it should be passed through the subst command, which performs another round of substitutions.

TXR

TXR was originally conceived out of the need to have "there documents": parse a document and extract variables, but in a style similar to generation of here documents. Here doc output was added later.

We use @(maybe)/@(or)/@(end) to set up some default values for variables which are overridden from the command line. Unification fails for an overridden variable, which is why we have to separate out the bind directives into the branches of a maybe.

By passing the script to txr using -f we can pass additional command arguments to the resulting script which are interpreted by txr.

<lang txr>#!/usr/bin/txr -f @(maybe) @(bind USER "Unknown User") @(or) @(bind MB "???") @(end) @(output) Dear @USER

Your are over your disk quota by @MB megabytes.

The Computer @(end)</lang>

Test runs

$ ./quota.txr -DMB=20
Dear Unknown User

Your are over your disk quota by 20 megabytes.

The Computer
$ ./quota.txr -DUSER=Bob
Dear Bob

Your are over your disk quota by ??? megabytes.

The Computer
$ ./quota.txr -DUSER=Bob -DMB=15
Dear Bob

Your are over your disk quota by 15 megabytes.

The Computer

Unbound variables throw exceptions:

$ txr -c '@(output)
@FOO
@(end)'
txr: unhandled exception of type query_error:
txr: (cmdline:2) bad substitution: FOO

UNIX Shell

In the shell, here document act as input to the command, rather than providing a string definition.

Works with: Bourne Shell

<lang bash>#!/bin/sh cat << ANARBITRARYTOKEN The river was deep but I swam it, Janet. The future is ours so let's plan it, Janet. So please don't tell me to can it, Janet. I've one thing to say and that's ... Dammit. Janet, I love you. ANARBITRARYTOKEN</lang>

<lang bash>cat << EOF Here documents do parameter and command substitution:

* Your HOME is $HOME
* 2 + 2 is `expr 2 + 2`
* Backslash quotes a literal \$, \` or \\

EOF</lang>

<lang bash>if true; then cat <<- EOF The <<- variant deletes any tabs from start of each line. EOF fi</lang>

<lang bash>cat << 'TOKEN' If TOKEN has any quoted characters (like 'TOKEN', "TOKEN" or \TOKEN), then all $ ` \ in the here document are literal characters.

$PATH \$PATH `shutdown now` TOKEN</lang>

C Shell

<lang csh>#!/bin/csh -f cat << ANARBITRARYTOKEN

* Your HOME is $HOME
* 2 + 2 is `@ n = 2 + 2; echo \$n`

ANARBITRARYTOKEN

cat << 'ANARBITRARYTOKEN' $PATH \$PATH `shutdown now` 'ANARBITRARYTOKEN'</lang>

Ursala

<lang Ursala>hd =

-[ The text enclosed within the so called dash-brackets shown above and below will be interpreted as a list of character strings. It can contain anything except uninterpreted dash-brackets, and can be used in any declaration or expression. The dash-brackets don't have to be on a line by themselves. ]-


example =

-[Some additional facilities allow here-documents to be nested and combined. Writing something like -[ hd ]- within a nested pair of dash-brackets will cause the text declared above (having the identifer hd) to be inserted at that point. The enclosed item can be any expression that evaluates to a list of character strings. We could therefore "escape" a literal dash-bracket within a here-document by writing -[ <'-['> ]-. Dash-brackets can be nested to any depth, alternating between literal text and compiled code on each level.]-

template "x" =

-[A further use of this notation involves defining a text-valued function. The output of this function will be this text, with the argument inserted here -["x"]- and again here -["x"]-. The argument type should be a list of character strings.]-

formletter ("x","y") =

-[Other calling conventions are possible. The left argument comes out here -["x"]- and the right one here -["y"]-.]-

designpattern =

-[A point-free style of function declaration is also supported. The argument comes out here -[. ~& ]-, after being fed through the function appearing within the nested dash-brackets (in this case the identity function). This usage is indicated by a period after the left inner dash-bracket. Nesting is also allowed in point free dash-bracket function specifications.]-

abstractionastronaut =

-[Higher order functions to any level are specified by piling on the periods like this -[.. ~&]-. This one is a second order function that needs to be applied to another function in order to get a first order function such as the previous three examples.]-</lang>