Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there an easy way to do multiline indented strings in Ruby? [duplicate]

Tags:

Say I wanted to have a very large block of pretty printed html code strait inline with my ruby code. What is the cleanest way to do this without losing any formatting in my string or having to remember some sort of gsub regex.

Encoding it all in one line is easy to do but hard to read:

1.times do
  # Note that the spaces have been changed to _ so that they are easy to see here.
  doc = "\n<html>\n__<head>\n____<title>\n______Title\n____</title>\n__</head>\n__<body>\n____Body\n__</body>\n</html>\n"
  ans = "Your document: %s" % [doc]
  puts ans
end

Multiline text in ruby is easier to read but the string can't be indented with the rest of the code:

1.times do
  doc = "
<html>
  <head>
    <title>
      Title
    </title>
  </head>
  <body>
    Body
  </body>
</html>
"
  ans = "Your document: %s" % [doc]
  puts ans
end

For example the following is indented with my code, but the string now has four extra spaces in front of every line:

1.times do
  doc = <<-EOM

    <html>
      <head>
        <title>
          Title
        </title>
      </head>
      <body>
        Body
      </body>
    </html>
  EOM
  ans = "Your document: %s" % [doc]
  puts ans
end

Most people go with the HEREDOC code above, and do a regex replace on the result to take out the extra whitespace at the beginning of each line. I would like a way where I don't have to go through the trouble of regexing each time.

like image 810
Vanson Samuel Avatar asked Apr 05 '13 16:04

Vanson Samuel


Video Answer


1 Answers

Since Ruby 2.3, the <<~ heredoc strips leading content whitespace:

def make_doc(body)
  <<~EOF
  <html>
    <body>
      #{body}
    </body>
  </html>
  EOF
end

puts make_doc('hello')

For older Ruby versions, the following is more verbose than the solutions presented in the other answers, but there's almost no performance overhead. It's about as fast as a single long string literal:

def make_doc(body)
  "<html>\n"       \
  "  <body>\n"     \
  "    #{body}\n"  \
  "  </body>\n"    \
  "</html>"
end
like image 109
ens Avatar answered Jan 03 '23 18:01

ens