Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 42 additions & 50 deletions lib/erb.rb
Original file line number Diff line number Diff line change
Expand Up @@ -259,10 +259,9 @@
# # => "\n* 0,0\n\n* 0,1\n\n* 0,2\n\n* 1,0\n\n* 1,1\n\n* 1,2\n\n* 2,0\n\n* 2,1\n\n* 2,2\n\n"
# ```
#
# You can use keyword argument `trim_mode` to make certain adjustments to the processing;
# see ERB.new.
# #### Shorthand Format for Execution Tags
#
# In particular, you can give `trim_mode: '%'` to enable a shorthand format for execution tags;
# You can give `trim_mode: '%'` to enable a shorthand format for execution tags;
# this example uses the shorthand format `% _code_` instead of `<% _code_ %>`:
#
# ```
Expand Down Expand Up @@ -527,69 +526,62 @@ def self.version
VERSION
end

# :markup: markdown
#
# Constructs a new ERB object with the template specified in _str_.
# :call-seq:
# ERB.new(string, trim_mode: nil, eoutvar: '_erbout')
#
# An ERB object works by building a chunk of Ruby code that will output
# the completed template when run.
# Returns a new \ERB object containing the given +string+.
#
# If _trim_mode_ is passed a String containing one or more of the following
# modifiers, ERB will adjust its code generation as listed:
# For details about `string`, its embedded tags, and generated results, see ERB.
#
# % enables Ruby code processing for lines beginning with %
# <> omit newline for lines starting with <% and ending in %>
# > omit newline for lines ending in %>
# - omit blank lines ending in -%>
# **Keyword Argument `trim_mode`**
#
# _eoutvar_ can be used to set the name of the variable ERB will build up
# its output in. This is useful when you need to run multiple ERB
# templates through the same binding and/or when you want to control where
# output ends up. Pass the name of the variable to be used inside a String.
# When keyword argument `trim_mode` has a string value,
# that value may be one of:
#
# ### Example
# - `'%'`: Enable [shorthand format][shorthand format] for execution tags.
# - `'-'`: Omit each blank line ending with `'%>'`.
# - `'>'`: Omit newline for each line ending with `'%>'`.
# - `'<>'`: Omit newline for each line starting with `'<%'` and ending with `'%>'`.
#
# require "erb"
# The value may also be certain combinations of the above.
#
# # build data class
# class Listings
# PRODUCT = { :name => "Chicken Fried Steak",
# :desc => "A well messaged pattie, breaded and fried.",
# :cost => 9.95 }
# - `'%-'`: Enable shorthand and omit each blank line ending with `'%>'`.
# - `'%>'`: Enable shorthand and omit newline for each line ending with `'%>'`.
# - `'%<>'`: Enable shorthand and omit newline for each line starting with `'<%'` and ending with `'%>'`.
#
# attr_reader :product, :price
# **Keyword Argument `eoutvar`**
#
# def initialize( product = "", price = "" )
# @product = product
# @price = price
# end
# The string value of keyword argument `eoutvar` specifies the name of the variable
# that method #result uses to construct its result string.
# This is useful when you need to run multiple \ERB templates through the same binding
# and/or when you want to control where output ends up.
#
# def build
# b = binding
# # create and run templates, filling member data variables
# ERB.new(<<~'END_PRODUCT', trim_mode: "", eoutvar: "@product").result b
# <%= PRODUCT[:name] %>
# <%= PRODUCT[:desc] %>
# END_PRODUCT
# ERB.new(<<~'END_PRICE', trim_mode: "", eoutvar: "@price").result b
# <%= PRODUCT[:name] %> -- <%= PRODUCT[:cost] %>
# <%= PRODUCT[:desc] %>
# END_PRICE
# end
# end
# It's good practice to choose a variable name that begins with an underscore: `'_'`.
#
# # setup template data
# listings = Listings.new
# listings.build
# <b>Backward Compatibility</b>
#
# puts listings.product + "\n" + listings.price
# The calling sequence given above -- which is the one you should use --
# is a simplified version of the complete formal calling sequence,
# which is:
#
# _Generates_
# ```
# ERB.new(string,
# safe_level=NOT_GIVEN, legacy_trim_mode=NOT_GIVEN, legacy_eoutvar=NOT_GIVEN,
# trim_mode: nil, eoutvar: '_erbout')
# ```
#
# Chicken Fried Steak
# A well massaged pattie, breaded and fried.
# The second, third, and fourth positional arguments (those in the second line above) are deprecated;
# this method issues warnings if they are given.
#
# Chicken Fried Steak -- 9.95
# A well massaged pattie, breaded and fried.
# However, their values, if given, are handled thus:
#
# - `safe_level`: ignored.
# - `legacy_trim_mode: overrides keyword argument `trim_mode`.
# - `legacy_eoutvar: overrides keyword argument `eoutvar`.
#
# [shorthand format]: rdoc-ref:ERB@Shorthand+Format+for+Execution+Tags
#
def initialize(str, safe_level=NOT_GIVEN, legacy_trim_mode=NOT_GIVEN, legacy_eoutvar=NOT_GIVEN, trim_mode: nil, eoutvar: '_erbout')
# Complex initializer for $SAFE deprecation at [Feature #14256]. Use keyword arguments to pass trim_mode or eoutvar.
Expand Down
241 changes: 1 addition & 240 deletions spec/ruby/core/regexp/shared/new.rb
Original file line number Diff line number Diff line change
Expand Up @@ -195,190 +195,14 @@ def obj.to_int() ScratchPad.record(:called) end
-> { Regexp.send(@method, "\\\\") }.should_not raise_error(RegexpError)
end

it "accepts a backspace followed by a character" do
it "accepts a backspace followed by a non-special character" do
Regexp.send(@method, "\\N").should == /#{"\x5c"+"N"}/
end

it "accepts a one-digit octal value" do
Regexp.send(@method, "\0").should == /#{"\x00"}/
end

it "accepts a two-digit octal value" do
Regexp.send(@method, "\11").should == /#{"\x09"}/
end

it "accepts a one-digit hexadecimal value" do
Regexp.send(@method, "\x9n").should == /#{"\x09n"}/
end

it "accepts a two-digit hexadecimal value" do
Regexp.send(@method, "\x23").should == /#{"\x23"}/
end

it "interprets a digit following a two-digit hexadecimal value as a character" do
Regexp.send(@method, "\x420").should == /#{"\x420"}/
end

it "raises a RegexpError if \\x is not followed by any hexadecimal digits" do
-> { Regexp.send(@method, "\\" + "xn") }.should raise_error(RegexpError, Regexp.new(Regexp.escape("invalid hex escape: /\\xn/")))
end

it "accepts an escaped string interpolation" do
Regexp.send(@method, "\#{abc}").should == /#{"\#{abc}"}/
end

it "accepts '\\n'" do
Regexp.send(@method, "\n").should == /#{"\x0a"}/
end

it "accepts '\\t'" do
Regexp.send(@method, "\t").should == /#{"\x09"}/
end

it "accepts '\\r'" do
Regexp.send(@method, "\r").should == /#{"\x0d"}/
end

it "accepts '\\f'" do
Regexp.send(@method, "\f").should == /#{"\x0c"}/
end

it "accepts '\\v'" do
Regexp.send(@method, "\v").should == /#{"\x0b"}/
end

it "accepts '\\a'" do
Regexp.send(@method, "\a").should == /#{"\x07"}/
end

it "accepts '\\e'" do
Regexp.send(@method, "\e").should == /#{"\x1b"}/
end

it "accepts '\\C-\\n'" do
Regexp.send(@method, "\C-\n").should == /#{"\x0a"}/
end

it "accepts '\\C-\\t'" do
Regexp.send(@method, "\C-\t").should == /#{"\x09"}/
end

it "accepts '\\C-\\r'" do
Regexp.send(@method, "\C-\r").should == /#{"\x0d"}/
end

it "accepts '\\C-\\f'" do
Regexp.send(@method, "\C-\f").should == /#{"\x0c"}/
end

it "accepts '\\C-\\v'" do
Regexp.send(@method, "\C-\v").should == /#{"\x0b"}/
end

it "accepts '\\C-\\a'" do
Regexp.send(@method, "\C-\a").should == /#{"\x07"}/
end

it "accepts '\\C-\\e'" do
Regexp.send(@method, "\C-\e").should == /#{"\x1b"}/
end

it "accepts multiple consecutive '\\' characters" do
Regexp.send(@method, "\\\\\\N").should == /#{"\\\\\\"+"N"}/
end

it "accepts characters and escaped octal digits" do
Regexp.send(@method, "abc\076").should == /#{"abc\x3e"}/
end

it "accepts escaped octal digits and characters" do
Regexp.send(@method, "\076abc").should == /#{"\x3eabc"}/
end

it "accepts characters and escaped hexadecimal digits" do
Regexp.send(@method, "abc\x42").should == /#{"abc\x42"}/
end

it "accepts escaped hexadecimal digits and characters" do
Regexp.send(@method, "\x3eabc").should == /#{"\x3eabc"}/
end

it "accepts escaped hexadecimal and octal digits" do
Regexp.send(@method, "\061\x42").should == /#{"\x31\x42"}/
end

it "accepts \\u{H} for a single Unicode codepoint" do
Regexp.send(@method, "\u{f}").should == /#{"\x0f"}/
end

it "accepts \\u{HH} for a single Unicode codepoint" do
Regexp.send(@method, "\u{7f}").should == /#{"\x7f"}/
end

it "accepts \\u{HHH} for a single Unicode codepoint" do
Regexp.send(@method, "\u{07f}").should == /#{"\x7f"}/
end

it "accepts \\u{HHHH} for a single Unicode codepoint" do
Regexp.send(@method, "\u{0000}").should == /#{"\x00"}/
end

it "accepts \\u{HHHHH} for a single Unicode codepoint" do
Regexp.send(@method, "\u{00001}").should == /#{"\x01"}/
end

it "accepts \\u{HHHHHH} for a single Unicode codepoint" do
Regexp.send(@method, "\u{000000}").should == /#{"\x00"}/
end

it "accepts characters followed by \\u{HHHH}" do
Regexp.send(@method, "abc\u{3042}").should == /#{"abc\u3042"}/
end

it "accepts \\u{HHHH} followed by characters" do
Regexp.send(@method, "\u{3042}abc").should == /#{"\u3042abc"}/
end

it "accepts escaped hexadecimal digits followed by \\u{HHHH}" do
Regexp.send(@method, "\x42\u{3042}").should == /#{"\x42\u3042"}/
end

it "accepts escaped octal digits followed by \\u{HHHH}" do
Regexp.send(@method, "\056\u{3042}").should == /#{"\x2e\u3042"}/
end

it "accepts a combination of escaped octal and hexadecimal digits and \\u{HHHH}" do
Regexp.send(@method, "\056\x42\u{3042}\x52\076").should == /#{"\x2e\x42\u3042\x52\x3e"}/
end

it "accepts \\uHHHH for a single Unicode codepoint" do
Regexp.send(@method, "\u3042").should == /#{"\u3042"}/
end

it "accepts characters followed by \\uHHHH" do
Regexp.send(@method, "abc\u3042").should == /#{"abc\u3042"}/
end

it "accepts \\uHHHH followed by characters" do
Regexp.send(@method, "\u3042abc").should == /#{"\u3042abc"}/
end

it "accepts escaped hexadecimal digits followed by \\uHHHH" do
Regexp.send(@method, "\x42\u3042").should == /#{"\x42\u3042"}/
end

it "accepts escaped octal digits followed by \\uHHHH" do
Regexp.send(@method, "\056\u3042").should == /#{"\x2e\u3042"}/
end

it "accepts a combination of escaped octal and hexadecimal digits and \\uHHHH" do
Regexp.send(@method, "\056\x42\u3042\x52\076").should == /#{"\x2e\x42\u3042\x52\x3e"}/
end

it "accepts a multiple byte character which need not be escaped" do
Regexp.send(@method, "\�").should == /#{"�"}/
end

it "raises a RegexpError if less than four digits are given for \\uHHHH" do
-> { Regexp.send(@method, "\\" + "u304") }.should raise_error(RegexpError, Regexp.new(Regexp.escape("invalid Unicode escape: /\\u304/")))
end
Expand Down Expand Up @@ -433,69 +257,6 @@ def obj.to_int() ScratchPad.record(:called) end

describe :regexp_new_string_binary, shared: true do
describe "with escaped characters" do
it "accepts a three-digit octal value" do
Regexp.send(@method, "\315").should == /#{"\xcd"}/
end

it "interprets a digit following a three-digit octal value as a character" do
Regexp.send(@method, "\3762").should == /#{"\xfe2"}/
end

it "accepts '\\M-\\n'" do
Regexp.send(@method, "\M-\n").should == /#{"\x8a"}/
end

it "accepts '\\M-\\t'" do
Regexp.send(@method, "\M-\t").should == /#{"\x89"}/
end

it "accepts '\\M-\\r'" do
Regexp.send(@method, "\M-\r").should == /#{"\x8d"}/
end

it "accepts '\\M-\\f'" do
Regexp.send(@method, "\M-\f").should == /#{"\x8c"}/
end

it "accepts '\\M-\\v'" do
Regexp.send(@method, "\M-\v").should == /#{"\x8b"}/
end

it "accepts '\\M-\\a'" do
Regexp.send(@method, "\M-\a").should == /#{"\x87"}/
end

it "accepts '\\M-\\e'" do
Regexp.send(@method, "\M-\e").should == /#{"\x9b"}/
end

it "accepts '\\M-\\C-\\n'" do
Regexp.send(@method, "\M-\C-\n").should == /#{"\x8a"}/
end

it "accepts '\\M-\\C-\\t'" do
Regexp.send(@method, "\M-\C-\t").should == /#{"\x89"}/
end

it "accepts '\\M-\\C-\\r'" do
Regexp.send(@method, "\M-\C-\r").should == /#{"\x8d"}/
end

it "accepts '\\M-\\C-\\f'" do
Regexp.send(@method, "\M-\C-\f").should == /#{"\x8c"}/
end

it "accepts '\\M-\\C-\\v'" do
Regexp.send(@method, "\M-\C-\v").should == /#{"\x8b"}/
end

it "accepts '\\M-\\C-\\a'" do
Regexp.send(@method, "\M-\C-\a").should == /#{"\x87"}/
end

it "accepts '\\M-\\C-\\e'" do
Regexp.send(@method, "\M-\C-\e").should == /#{"\x9b"}/
end
end
end

Expand Down