Proposal - delayed intropolation in heredoc

yet another crazy proposal from me… read on, am I crazy?

motivation

···

==========

I use heredocs for small templates, ala

class HTML
# …
def write_page(body, title, css, filename)
html = <<EOHTML

<?xml version="1.0" encoding="ISO-8859-1"?> #{title} #{css} #{body} EOHTML File.open(filename, "w+") {|f| f.write(html) } end # ... end # class HTML

Its disturbing to have many such heredocs which breaks indendation
completely. The problem with ‘<<-EOHTML’ is that you get the indention
from your source into the output. To circumvent this I often make use of
<<-EOHTML.gsub(/^\s*/, “”) which removes that indentation, however the
interpolated text gets also gsub’ed which Im not interested in.

I could do eval of <<‘EOHTML’.gsub(/^\s*/, “”), but then the simple idea
turns into a long beast, which confuses more that it helps. Then it
probably better to use doublequotes than heredoc.

proposal

If we somehow could manipulate the text string before interpolation
occured. For instance by executing code on the HereDoc end tag.

ruby a.rb
a.rb:10: can’t find string “EOF” anywhere before EOF
a.rb:3: syntax error
expand -t2 a.rb
def m
inline = “1\n space\n3”
text = <<-EOF
pre
#{inline}
post
EOF.gsub(/^\s*/, ‘’)
text
end
p m

Tell me is this a bad idea?


Simon Strandgaard

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag
news:pan.2004.03.29.15.12.59.760809@adslhome.dk…

yet another crazy proposal from me… read on, am I crazy?

Without reading on: yes, you are. But aren’t we all? :-))

motivation

I use heredocs for small templates, ala

class HTML

def write_page(body, title, css, filename)
html = <<EOHTML

<?xml version="1.0" encoding="ISO-8859-1"?> #{title} #{css} #{body} EOHTML File.open(filename, "w+") {|f| f.write(html) } end # ... end # class HTML

Its disturbing to have many such heredocs which breaks indendation
completely. The problem with ‘<<-EOHTML’ is that you get the indention
from your source into the output. To circumvent this I often make use of
<<-EOHTML.gsub(/^\s*/, “”) which removes that indentation, however the
interpolated text gets also gsub’ed which Im not interested in.

I could do eval of <<‘EOHTML’.gsub(/^\s*/, “”), but then the simple idea
turns into a long beast, which confuses more that it helps. Then it
probably better to use doublequotes than heredoc.

proposal

If we somehow could manipulate the text string before interpolation
occured. For instance by executing code on the HereDoc end tag.

In your case manipulation after interpolation would be sufficient.

ruby a.rb
a.rb:10: can’t find string “EOF” anywhere before EOF
a.rb:3: syntax error
expand -t2 a.rb
def m
inline = “1\n space\n3”
text = <<-EOF
pre
#{inline}
post
EOF.gsub(/^\s*/, ‘’)
text
end
p m

That syntax error is easily fixed:

def m
inline = “1\n space\n3”
text = <<-EOF.gsub(/^\s+/, ‘’)
pre
#{inline}
post
EOF
text
end
p m

Tell me is this a bad idea?

I’ve missed proper indentation often, too. But if you want indentation
why don’t you just suggest indentation? The rule could be that as much
white space sitting in front of the terminator is removed from the lines
preceding it, i.e.

str = <<-FOO
def x
puts ‘foo’
end
FOO

becomes
def x
puts ‘foo’
end

and not

def x
puts ‘foo’
end

like today.

Hm…

robert

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag
news:pan.2004.03.29.15.12.59.760809@adslhome.dk…

yet another crazy proposal from me… read on, am I crazy?

Without reading on: yes, you are. But aren’t we all? :-))

I was afraid of that. If you are a genius then its ok to be crazy,
except that I am not a genius, then its not ok :wink:

[snip motivation]

proposal

If we somehow could manipulate the text string before interpolation
occured. For instance by executing code on the HereDoc end tag.

In your case manipulation after interpolation would be sufficient.

No, I want to preserve the ‘spa ces’ in the inline string.

The code I have posted is suppose to output
“pre\n1\n space\n3\npost\n”

Your suggested code outputs:
“pre\n1\nspace\n3\npost\n”

Space isn’t preserved… I think you have misunderstood my proposal :wink:

Tell me is this a bad idea?

I’ve missed proper indentation often, too. But if you want indentation
why don’t you just suggest indentation? The rule could be that as much
white space sitting in front of the terminator is removed from the lines
preceding it, i.e.

str = <<-FOO
def x
puts ‘foo’
end
FOO

becomes
def x
puts ‘foo’
end

Good idea as long its spaces. I wonder how tabs can be handled properly.
Should tabs be converted to 8 spaces? Should tabs be sliced?

···

On Mon, 29 Mar 2004 18:38:20 +0200, Robert Klemme wrote:


Simon Strandgaard

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag
news:pan.2004.03.29.15.49.45.527862@adslhome.dk…

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag
news:pan.2004.03.29.15.12.59.760809@adslhome.dk…

yet another crazy proposal from me… read on, am I crazy?

Without reading on: yes, you are. But aren’t we all? :-))

I was afraid of that. If you are a genius then its ok to be crazy,
except that I am not a genius, then its not ok :wink:

Hey, we can just pretend we’re geniusses. If all are crazy anyway then
nobody’ll notice. :slight_smile:

[snip motivation]

proposal

If we somehow could manipulate the text string before interpolation
occured. For instance by executing code on the HereDoc end tag.

In your case manipulation after interpolation would be sufficient.

No, I want to preserve the ‘spa ces’ in the inline string.

The code I have posted is suppose to output
“pre\n1\n space\n3\npost\n”

Your suggested code outputs:
“pre\n1\nspace\n3\npost\n”

Space isn’t preserved… I think you have misunderstood my proposal :wink:

Yeah, I overlooked the spaces in the string you insert. But OTOH how
common is this case?

Tell me is this a bad idea?

I’ve missed proper indentation often, too. But if you want
indentation
why don’t you just suggest indentation? The rule could be that as
much
white space sitting in front of the terminator is removed from the
lines
preceding it, i.e.

str = <<-FOO
def x
puts ‘foo’
end
FOO

becomes
def x
puts ‘foo’
end

Good idea as long its spaces. I wonder how tabs can be handled properly.
Should tabs be converted to 8 spaces? Should tabs be sliced?

I’d just place the general rule that exactly the whitespace that precedes
the terminator is removed from lines inside the here doc, if present. So
if there’s a tab in front of the terminator but the lines of the here doc
start with spaces then these are not removed. Don’t you think this is
sufficient?

Kind regards

robert
···

On Mon, 29 Mar 2004 18:38:20 +0200, Robert Klemme wrote:

In Message-Id: pan.2004.03.29.15.49.45.527862@adslhome.dk
Simon Strandgaard neoneye@adslhome.dk writes:

Space isn’t preserved… I think you have misunderstood my proposal :wink:

This particular case, you can use sprintf or String#%, can’t you?

> ruby <<EOS
str = <<END.gsub(/^\s{2}/, "")
  string
  %s
  string
END
puts str%"  inserted"
EOS
string
  inserted
string
···


kjana@dm4lab.to March 30, 2004
Whatever is worth doing at all is worth doing well.

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag
news:pan.2004.03.29.15.49.45.527862@adslhome.dk…

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag
news:pan.2004.03.29.15.12.59.760809@adslhome.dk…

yet another crazy proposal from me… read on, am I crazy?

Without reading on: yes, you are. But aren’t we all? :-))

I was afraid of that. If you are a genius then its ok to be crazy,
except that I am not a genius, then its not ok :wink:

Hey, we can just pretend we’re geniusses. If all are crazy anyway then
nobody’ll notice. :slight_smile:

I prefer being my self, rather than pretending to be somebody else :wink:

[snip motivation]

proposal

If we somehow could manipulate the text string before interpolation
occured. For instance by executing code on the HereDoc end tag.

In your case manipulation after interpolation would be sufficient.

No, I want to preserve the ‘spa ces’ in the inline string.

The code I have posted is suppose to output
“pre\n1\n space\n3\npost\n”

Your suggested code outputs:
“pre\n1\nspace\n3\npost\n”

Space isn’t preserved… I think you have misunderstood my proposal :wink:

Yeah, I overlooked the spaces in the string you insert. But OTOH how
common is this case?

Both in the coverage2html and the ruby2html pieces of code I rely
on that spaces is preserved this way. Otherwise indentation will mess up.
I could use ’ ’ but it takes up much space.

http://neoneye.dk/coverage/
http://neoneye.dk/syntax.html

Tell me is this a bad idea?

I’ve missed proper indentation often, too. But if you want
indentation
why don’t you just suggest indentation? The rule could be that as
much
white space sitting in front of the terminator is removed from the
lines
preceding it, i.e.

str = <<-FOO
def x
puts ‘foo’
end
FOO

becomes
def x
puts ‘foo’
end

Good idea as long its spaces. I wonder how tabs can be handled properly.
Should tabs be converted to 8 spaces? Should tabs be sliced?

I’d just place the general rule that exactly the whitespace that precedes
the terminator is removed from lines inside the here doc, if present. So
if there’s a tab in front of the terminator but the lines of the here doc
start with spaces then these are not removed. Don’t you think this is
sufficient?

Not sure if I understand your idea on how to deal with tabs.
I seems kind of kludgy, sorry.

···

On Tue, 30 Mar 2004 14:36:46 +0200, Robert Klemme wrote:

On Mon, 29 Mar 2004 18:38:20 +0200, Robert Klemme wrote:


Simon Strandgaard

Bommer… Yes ‘%’ does the trick. Silly me. I have been using this many
times before, but without realizing its potential.

Thanks Yanagawa, this is awesome :wink:

···

On Tue, 30 Mar 2004 21:58:06 +0900, YANAGAWA Kazuhisa wrote:

In Message-Id: pan.2004.03.29.15.49.45.527862@adslhome.dk
Simon Strandgaard neoneye@adslhome.dk writes:

Space isn’t preserved… I think you have misunderstood my proposal :wink:

This particular case, you can use sprintf or String#%, can’t you?

> ruby <<EOS
str = <<END.gsub(/^\s{2}/, "")
  string
  %s
  string
END
puts str%"  inserted"
EOS
string
  inserted
string


Simon Strandgaard

In Message-Id: pan.2004.03.29.15.49.45.527862@adslhome.dk
Simon Strandgaard neoneye@adslhome.dk writes:

Space isn’t preserved… I think you have misunderstood my proposal :wink:

This particular case, you can use sprintf or String#%, can’t you?
[snip]

Bommer… Yes ‘%’ does the trick. Silly me. I have been using this many
times before, but without realizing its potential.

Thanks Yanagawa, this is awesome :wink:

BTW: now the xhtml template looks like:

def write_page(body, title, css, filename)
html = <<-EOHTML.gsub(/^\s*/, ‘’) % [title, css, body]

<?xml version="1.0" encoding="ISO-8859-1"?> %s %s %s EOHTML File.open(filename, "w+") {|f| f.write(html) } end

Only drawback is that ‘%s’ isn’t that fool-proof as ‘#{var}’

···

On Tue, 30 Mar 2004 23:13:38 +0200, Simon Strandgaard wrote:

On Tue, 30 Mar 2004 21:58:06 +0900, YANAGAWA Kazuhisa wrote:


Simon Strandgaard

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag
news:pan.2004.03.30.20.09.50.501@adslhome.dk…

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag
news:pan.2004.03.29.15.49.45.527862@adslhome.dk…

“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag
news:pan.2004.03.29.15.12.59.760809@adslhome.dk…

yet another crazy proposal from me… read on, am I crazy?

Without reading on: yes, you are. But aren’t we all? :-))

I was afraid of that. If you are a genius then its ok to be crazy,
except that I am not a genius, then its not ok :wink:

Hey, we can just pretend we’re geniusses. If all are crazy anyway
then
nobody’ll notice. :slight_smile:

I prefer being my self, rather than pretending to be somebody else :wink:

Well, you can be many people at the same time. => MPD :slight_smile:

Good idea as long its spaces. I wonder how tabs can be handled
properly.
Should tabs be converted to 8 spaces? Should tabs be sliced?

I’d just place the general rule that exactly the whitespace that
precedes
the terminator is removed from lines inside the here doc, if present.
So
if there’s a tab in front of the terminator but the lines of the here
doc
start with spaces then these are not removed. Don’t you think this is
sufficient?

Not sure if I understand your idea on how to deal with tabs.
I seems kind of kludgy, sorry.

Example (with some special chars shown):

str =<<FOO
x
FOO

yields “x\n”

\tstr=<<FOO
\tx
\tFOO

yields “x\n”

\tstr=<<FOO
x
\tFOO

yields

" x\n"

i.e. since the whitespace preceding the “x” is different from the ws
preceding the FOO it is not removed.

robert
···

On Tue, 30 Mar 2004 14:36:46 +0200, Robert Klemme wrote:

On Mon, 29 Mar 2004 18:38:20 +0200, Robert Klemme wrote: