This question is partly answered in How do I remove leading whitespace chars from Ruby HEREDOC?
In Rails 3 there is a method #strip_heredoc
, that strips all whitespace.
But when inserting lines in an existing file, that already has identation, this doesn't work too well. An example:
begin
insert_into_file "#{app_name}/config/environments/production.rb", <<-DEVISE_MAILER_STUFF.strip_heredoc, :before => "end\n"
# for devise
config.action_mailer.default_url_options = { :protocol => 'https', :host => 'YOURHOSTNAME' }
config.action_mailer.delivery_method = :smtp
something.each do |x|
do stuff
end
DEVISE_MAILER_STUFF
end
The 'begin' and 'end' are only added to show that the source code has indentation. The heredoc has 4 spaces before the line '# for devise'. @strip_heredoc will delete all these spaces, but it will maintain the two extra spaces in the line 'do stuff'.
In environments/production.rb
this will look like this:
MyApp::Application.configure do
# Settings specified here will take precedence over those in config/application.rb
# *** Identation here is two spaces! (We are in a block.) ***
# for devise
config.action_mailer.default_url_options = { :protocol => 'https', :host => 'YOURHOSTNAME' }
config.action_mailer.delivery_method = :smtp
something.each do |x|
do stuff
end
# back to original identation of this file
end # MyApp::Application.configure block!
How to solve this?
Maybe there are other ways instead of a heredoc?
I thought maybe strip_heredoc(min)
where min
is the minimum of spaces to keep, but that doesn't work well with tabs I guess. Or have the first line of the heredoc determine the left margin, like this:
puts <<-HEREDOC
FIRST_LINE
Real code here
HEREDOC
That 'FIRST_LINE' would be deleted by strip_heredoc
, but it would also set the number of spaces/whitespace that needs to be deleted. So the output would have 2 spaces in front of 'Real code here'.
Update: Maybe something like this:
String.class_eval do
def strip_heredoc_with_indent(indent=0)
new_indent = ( self.empty? ? 0 : ( scan(/^[ \t]*(?=\S)/).min.size - indent ) )
gsub(/^[ \t]{#{new_indent}}/, '')
end
end