Here document

From Rosetta Code
Jump to: navigation, search
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.

Contents

[edit] Ada

Ada has neither heredocs nor multiline strings. They are easy to implement using containers of strings:

with Ada.Containers.Indefinite_Vectors, Ada.Text_IO;
 
procedure Here_Doc is
 
package String_Vec is new Ada.Containers.Indefinite_Vectors
(Index_Type => Positive,
Element_Type => String);
 
use type String_Vec.Vector;
 
Document: String_Vec.Vector := String_Vec.Empty_Vector
& "This is a vector of strings with the following properties:"
& " - indention is preserved, and"
& " - a quotation mark '""' must be ""escaped"" by a double-quote '""""'.";
begin
Document := Document & "Have fun!";
for I in Document.First_Index .. Document.Last_Index loop
Ada.Text_IO.Put_Line(Document.Element(I));
end loop;
end Here_Doc;
Output:
This is a vector of strings with the following properties:
  - indention is preserved, and
  - a quotation mark '"' must be "escaped" by a double-quote '""'.
Have fun!

[edit] 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:

#!/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."
))
 

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.

[edit] AutoHotkey

AutoHotkey uses "continuation sections" for literal text:

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

[edit] AWK

The awk extraction and reporting language does not provide any markup facility for embedding here documents within an awk script. The awk utility is really a helper tool often used from within the Unix shell. The Unix shell in which awk scripts are usually embedded does support the use of here documents, and the way that here documents are used within the shell make them ideal for passing to awk as is, without the need for an additional facility in awk.

[edit] C#

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

using System;
 
class Program
{
static void Main(string[] args)
{
Console.Write(@"
multiline
strings are easy
to put together
in C#"
);
}
}

[edit] 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.

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

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.

[edit] D

import std.stdio, std.string;
 
void main() {
// Delimited strings: a 'q' followed by double quotes and an
// opening and closing delimiter of choice:
 
q"[a string that you "don't" have to escape]"
.writeln;
 
// 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:
 
q"EOS
This
is a multi-line
heredoc string
EOS".outdent.writeln;
 
// std.string.outdent is used to remove the four spaces indent.
}
Output:
a string that you "don't" have to escape
This
is a multi-line
heredoc string

[edit] DWScript

Double-quotes (") denote a multi-line string, to include a double-quote in such a string, you need to double it.

PrintLn("This is
a multiline
""string""
sample");

Output:

This is
a multiline
"string"
sample

[edit] Erlang

Multiline strings look like this in the Erlang shell:

 
2> S = " ad
2> 123
2> the end"
.
3> io:fwrite( S ).
ad
123
the end
 

[edit] Forth

Works with: GForth
\ 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
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?'
--

[edit] Frink

Frink does not have awkward here-docs. Triple-quoted strings serve the same purpose, but more concisely. (The Perl, PHP, etc. syntax for here-documents is a violation of the "define everything at most once" principle of software engineering.) Variable interpolation is allowed within triple-quoted strings.

 
lyrics = """Oh, Danny Boy,
The pipes, the pipes are calling
From glen to glen and down the mountainside"""
 

[edit] Go

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

var m = `    leading spaces
 
and blank lines`

[edit] Groovy

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

[edit] Multi-line String literal

The literal text, preserving lines and spacing

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
'''

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

[edit] 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.

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
"""

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

[edit] 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.
)

[edit] Julia

Like Python, Julia has triple-quoted string literals, which are similar to here-docs:

print("""\
Usage: thingy [OPTIONS]
-h Display this usage message
-H hostname Hostname to connect to
""")

[edit] Lua

Lua uses the [ [ to mark the start of a dochere block and ] ] to mark the end. It can be used directly or while assigning strings to a variable.

 
print([[
This is a long paragraph of text
it is the simplest while using it
with lua, however it will have the
same line breaks and spacing as
you set in this block.
]])
 
local msg = [[this is a message that spans
multiple lines and will have the next lines
preserved as they were entered, so be careful
when using this]]
 
print(msg)
 
 

[edit] 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

[edit] 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)

Sample output:

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

[edit] OxygenBasic

Use the keyword quote followed by a keyword or group of symbols to mark the beginning and end of text


s=quote
""""
    She said "He said 'I said `There is a rumour
    going around.` ' "
""""

print s

[edit] 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:

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

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

$pancake = <<"NO MORE INGREDIENTS";
egg
milk
flour
NO MORE INGREDIENTS

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:

$x = <<'FOO';
No
$interpolation
here
FOO

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

$output = <<`BAR`;
ls /home
BAR

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:

print(<<EOF . "lamb\n");
Mary had
a little
EOF

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.

print(<<EOF
Mary had
a little
EOF
. "lamb\n");

[edit] Perl 6

Heredocs in Perl 6 use the :to modifier to a quoting operator, such as q or qq.

my $color = 'green';
my $text = qq :to 'EOT';
some line
color: $color
last line
EOT

Result:

some line
color: green
last line

(Note that the quotes around the "EOT" are not magic --- the marker is just a regular string; it's the `q` or `qq` that decides whether or not the heredoc interpolates.)

Multiple here docs may be stacked on top of each other.

Works with: niecza
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;

Output:

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

[edit] 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:

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

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):

$x = <<<'FOO'
No
$interpolation
here
FOO
;

[edit] PicoLisp

We can use the 'here' function:

(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"

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 ###

[edit] PowerShell

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

 
$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>
"@

[edit] Python

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

print("""\
Usage: thingy [OPTIONS]
-h Display this usage message
-H hostname Hostname to connect to
"""
)

[edit] Racket

Racket has a raw built-in here-document syntax, with the usual problems that it has (breaks code indentation, no "interpolation"):

 
#lang racket/base
 
(displayln #<<EOF
Blah blah blah
with indentation intact
and "free" \punctuations\
EOF
)
 

In addition, Racket has "@-forms", which are a syntax for free text (described here) that works well with code:

 
#lang at-exp racket/base
 
(require scribble/text)
 
(define excited "!!!")
(define (shout . text) @list{>>> @text <<<})
 
(output
@list{Blah blah blah
with indentation intact
but respecting the indentation of
the whole code
and "free" \punctuations\
and even string interpolation-like @excited
but really @shout{any code}
 
})
 
(output @list|<<{And customizable delimiters
so @foo{} is just plain text}>>|)
 

[edit] Raven

As a list:

'Buffy the Vampire Slayer' as sender
'Spike' as recipient
 
[
"Dear %(recipient)s,
"
"I wish you to leave Sunnydale and never return.
"
"Not Quite Love,
"%(sender)s
] "\n" join print
 

Using group to place the data on the stack:

'Buffy the Vampire Slayer' as sender
'Spike' as recipient
 
group
"Dear %(recipient)s,
"
"I wish you to leave Sunnydale and never return.
"
"Not Quite Love,
 %(sender)s\n"
list "\n" join print
 
Output:
Dear Spike,

I wish you to leave Sunnydale and never return.

Not Quite Love,
Buffy the Vampire Slayer

[edit] Retro

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

"This is
a multi-line string
with indention
and such"

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

{{
 : 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]

[edit] REXX

/*REXX program demonstrates a method to use  "here"  documents in REXX. */
parse arg doc . /*"here" name is case sensitive. */
 
do j=1 for sourceline()
if sourceline(j)\=='◄◄'doc then iterate
do !=j+1 to sourceline() while sourceline(!)\=='◄◄.'
say sourceline(!)
end /*!*/
exit /*stick a fork in it, we're done.*/
end /*j*/
 
say doc '"here" document not found.'
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────start of "here" docs──────────────────
◄◄rs-232
RS─232 Signals and Pinouts ┌─────────────────────────────────────────────────┐
│13 12 11 10 9 8 7 6 5 4 3 2 1│
──► Interface between data └┐ 25 24 23 22 21 20 19 18 17 16 15 14┌┘
terminal equipment (DTE/male)└───────────────────────────────────────────────┘
and data communication equipment
[DCE/female] employing serial ┌───────────────────────────────────────────┐
binary data interchange. │ 12◄─secondary carrier detect [SCD] DCE │
┌─────────────────────────────────┤ 13◄─secondary clear to send [SCS] DCE │
│ 1◄─protective ground [PG, GND] │ 14◄─secondary transmitted data [STD] DTE │
│ 2◄─transmitted data [TD] DTE │ 15◄─transmit clock [TC] DCE │
│ 3◄─received data [RD] DCE │ 16◄─secondary received data [SRD] DCE │
│ 4◄─request to send [RTS] DTE │ 17◄─receiver clock [RC] DCE │
│ 5◄─clear to send [CTS] DCE │ 18◄─unassigned │
│ 6◄─data set ready [DSR] DCE │ 19◄─secondary request to send [SRS] DTE │
│ 7◄─signal ground [SG] │ 20◄─data terminal ready [DTR] DTE │
│ (common return) │ 21◄─signal quality detector [SQD] DCE │
│ 8◄─carrier detect [CD] DCE │ 22◄─ring indicator [RI] DCE │
│ 9◄─positive voltage [-] │ 23◄─data rate select [DRS] DCE/DTE │
│10◄─negative voltage [-] │ 24◄─external clock [XTC] DTE │
│11◄─unassigned │ 25◄─unassigned │
└─────────────────────────────────┴───────────────────────────────────────────┘
◄◄.
◄◄can
┌──────┐
│ │
│ ├┐
│ ├┘
│ │
│ │
│ │
│ │
│ │ ┌─────┐
└──┬┬──┘ │┌───┐│
││ ├┤ ├┤
││ ┌───────────────┐ ││ ││
││ ┌┴──────────────┬┘ └┤ ├┘
│└───┤ │ └───┘
└────┤ ┌──┘
│ │
└──┐ │
│ │
│ │
│ │
└─────────┘
◄◄.
────────────────────────────────────end of "here" docs──────────────────*/

output when using the input of: rs-232

RS─232 Signals and Pinouts  ┌─────────────────────────────────────────────────┐
                            │13  12  11  10  9   8   7   6   5   4   3   2   1│
──►  Interface between data └┐ 25  24  23  22  21  20  19  18  17  16  15  14┌┘
terminal equipment (DTE/male)└───────────────────────────────────────────────┘
and data communication equipment
[DCE/female]  employing  serial   ┌───────────────────────────────────────────┐
binary  data  interchange.        │ 12◄─secondary carrier detect   [SCD]  DCE │
┌─────────────────────────────────┤ 13◄─secondary clear to send    [SCS]  DCE │
│ 1◄─protective ground  [PG, GND] │ 14◄─secondary transmitted data [STD]  DTE │
│ 2◄─transmitted data   [TD]  DTE │ 15◄─transmit clock             [TC]   DCE │
│ 3◄─received data      [RD]  DCE │ 16◄─secondary received data    [SRD]  DCE │
│ 4◄─request to send    [RTS] DTE │ 17◄─receiver clock             [RC]   DCE │
│ 5◄─clear to send      [CTS] DCE │ 18◄─unassigned                            │
│ 6◄─data set ready     [DSR] DCE │ 19◄─secondary request to send  [SRS]  DTE │
│ 7◄─signal ground      [SG]      │ 20◄─data terminal ready        [DTR]  DTE │
│      (common return)            │ 21◄─signal quality detector    [SQD]  DCE │
│ 8◄─carrier detect     [CD]  DCE │ 22◄─ring indicator             [RI]   DCE │
│ 9◄─positive voltage   [-]       │ 23◄─data rate select       [DRS]  DCE/DTE │
│10◄─negative voltage   [-]       │ 24◄─external clock             [XTC]  DTE │
│11◄─unassigned                   │ 25◄─unassigned                            │
└─────────────────────────────────┴───────────────────────────────────────────┘

output when using the input of: can

        ┌──────┐
        │      │
        │      ├┐
        │      ├┘
        │      │
        │      │
        │      │
        │      │
        │      │                                         ┌─────┐
        └──┬┬──┘                                         │┌───┐│
           ││                                            ├┤   ├┤
           ││    ┌───────────────┐                       ││   ││
           ││   ┌┴──────────────┬┘                       └┤   ├┘
           │└───┤               │                         └───┘
           └────┤            ┌──┘
                │            │
                └──┐         │
                   │         │
                   │         │
                   │         │
                   └─────────┘

[edit] 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:

address = <<END
1, High Street,
#{town_name},
West Midlands.
WM4 5HD.
END

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

pancake = <<"NO MORE INGREDIENTS"
egg
milk
flour
NO MORE INGREDIENTS

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:

x = <<'FOO'
No
#{interpolation}
here
FOO

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

output = <<`BAR`
ls /home
BAR

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:

puts <<EOF + "lamb"
Mary had
a little
EOF

[edit] Run BASIC

text$ ="
<<'FOO'
Now
is
the
time
for
all
good mem
to come to the aid of their country."
print text$

Output:

<<'FOO'
Now
   is
     the 
       time
            for
               all
                  good mem
to come to the aid of their country.

[edit] Scala

[edit] All versions

Scala multiline literal are called raw strings. Triple quotes (""") marks the beginning and end. Specially handy when using escape sequences in e.g. regular expressions.

Library: Scala
object temp {
val MemoriesOfHolland=
"""Thinking of Holland
|I see broad rivers
|slowly chuntering
|through endless lowlands,
|rows of implausibly
|airy poplars
|standing like tall plumes
|against the horizon;
|and sunk in the unbounded
|vastness of space
|homesteads and boweries
|dotted across the land,
|copses, villages,
|couchant towers,
|churches and elm-trees,
|bound in one great unity.
|There the sky hangs low,
|and steadily the sun
|is smothered in a greyly
|iridescent smirr,
|and in every province
|the voice of water
|with its lapping disasters
|is feared and hearkened."
"".stripMargin
}

All control codes are transparent e.g. new lines. In order for a neat code each lines has as prefix spaces and a | symbol which will be removed by the stripMargin function.

[edit] Sidef

There must not be a space between the "<<" and the token string. When the token string is double-quoted ("") or not quoted, the content will be interpolated like a double-quoted string:

var text = <<"EOF";
a = #{1+2}
b = #{3+4}
EOF

If single quotes are used, then the here document will not support interpolation, like a normal single-quoted string:

var x = <<'FOO';
No
#{interpolation}
here
FOO

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. To further illustrate this fact, we can use the "<<END" inside a complex, nested expression:

say (<<EOF + "lamb");
Mary had
a little
EOF

which is equivalent with:

say (<<EOF
Mary had
a little
EOF

+ "lamb");

[edit] 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.
}

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.

[edit] 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.

#!/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)

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

[edit] UNIX Shell

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

Works with: Bourne Shell
#!/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
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
if true; then
cat <<- EOF
The <<- variant deletes any tabs from start of each line.
EOF
fi
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

[edit] C Shell

#!/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'

[edit] 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.]-


[edit] VBScript

There is no such thing in VBScript but we need it, too. The following is a workaround tool.

It will prompt you to select a Txt-based file and do its best to create VBScript code that will recreate that Txt-based file!

 
'Purpose: Converts TXT files into VBS code with a function that returns a text string with the contents of the TXT file
' The TXT file can even be another VBS file.
 
'History:
' 1.0 8may2009 Initial release
'
'
Const ForReading = 1
Const ForWriting = 2
Const ForAppending = 8
Const TristateUseDefault = -2
 
set WshShell = CreateObject("WSCript.shell")
 
'File browse dialog box
Set objDialog = CreateObject("UserAccounts.CommonDialog")
objDialog.Filter = "All Files|*.*"
objDialog.InitialDir = WshShell.CurrentDirectory
intResult = objDialog.ShowOpen
 
If intResult = 0 Then
WshShell.Popup "No file selected.", 2, " ", 64
Wscript.Quit
Else
strFileNameIN = objDialog.FileName
End If
 
strFileNameOUT= strFileNameIN & "_CONVERTED.Vbs"
 
'Check if strFileNameOUT exists already
Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists(strFileNameOUT) then 'does the file EXIST?
' WScript.Echo "found"
OVRWT=MSGBOX(strFileNameOUT & " exists already"&vbCRLF&"Overwrite?",vbYesNoCancel,"Overwrite?")
if OVRWT = 6 then
'proceed
objFSO.DeleteFile(strFileNameOUT)
else
WshShell.Popup "Exiting as requested.", 1, " ", 64
Wscript.Quit
End If
Else
' WScript.Echo "not found" 'strFileNameOUT does NOT exists already
 
END if
 
strBaseName=objFSO.GetBaseName(strFileNameIN)
 
 
'open strFileNameANSI file, and put entire file into a variable ****SIZE LIMIT ??*****
Set objFile = objFSO.OpenTextFile(strFileNameIN, ForReading)
strText = objFile.ReadAll
objFile.Close
 
'Start converting
 
'Convert " to ""
strOldText = Chr(34)
strNewText = Chr(34)&Chr(34)
strText = Replace(strText, strOldText, strNewText)
 
'Add objTXTFile.writeline ("
strOldText = VBCRLF
strNewText = """) &vbCrLf"&VBCRLF&" strText=strText& ("""
strText = Replace(strText, strOldText, strNewText)
'Converting done
 
strFileName=objFSO.GetFileName(strFileNameIN)
 
'Write to file
Set objFile = objFSO.OpenTextFile(strFileNameOUT, ForAppending, True)
objFile.WriteLine "'this Function will return a string containing the contents of the file called "&strFileName
objFile.WriteLine "msgbox "&strBaseName &"()"
objFile.WriteLine vbCrLf
objFile.WriteLine "Function "&strBaseName&"()"
objFile.WriteLine " 'returns a string containing the contents of the file called "&strFileName
objFile.WriteLine " Dim strText"
objFile.WriteLine " strText= ("""&strText&""") &vbCrLf"
objFile.WriteLine " "&strBaseName&"=strText"
objFile.WriteLine "End Function"
objFile.Close
 
WshShell.Popup "created " & strFileNameOUT, 3, "Completed", 64
 

[edit] XPL0

code Text=12;
Text(0, " ^"Heredocs^" are pretty much automatic. Multiple lines and
whitespace, such as indentations, are output exactly as written. Quote
marks (^") and any carets (^^) within the string must be escaped.")

[edit] XSLT

Being a dialect of XML, XSLT inherits CDATA sections. Not quite heredocs, these are more like raw triple quotes in Python (r"""…""") or Scala ("""…""") in that anything except the end delimiter is treated literally.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text"/>
 
<xsl:template match="/">
<![CDATA[
 
This text is in a CDATA section. In here, it's okay to include <, >, &, ", and '
without any special treatment.
 
The section is terminated by a three-character sequence consisting of two right
brackets ("]]") followed by a greater-than (">"). If this sequence appears in
your text, a workaround is to drop out of the CDATA section, output part of the
terminator, then start a new CDATA section and output the rest. Let's do this
now:
 
]]>]]<![CDATA[>
 
Newlines and spacing are retained as well, as long as they're evaluated in a
context that bothers preserving them. Whether or not the spaces before and after
the CDATA section are also preserved may be application-dependent.
 
]]>
</xsl:template>
</xsl:stylesheet>

Output from xsltproc (input is ignored):




This text is in a CDATA section. In here, it's okay to include <, >, &, ", and '
without any special treatment.

The section is terminated by a three-character sequence consisting of two right
brackets ("]]") followed by a greater-than (">"). If this sequence appears in
your text, a workaround is to drop out of the CDATA section, output part of the
terminator, then start a new CDATA section and output the rest. Let's do this
now:

	]]>

Newlines and spacing are retained as well, as long as they're evaluated in a
context that bothers preserving them. Whether or not the spaces before and after
the CDATA section are also preserved may be application-dependent.


Personal tools
Namespaces

Variants
Actions
Community
Explore
Misc
Toolbox