diff --git a/README.md b/README.md index 908fdb7..c591c96 100644 --- a/README.md +++ b/README.md @@ -1,255 +1,98 @@ -# ERB +# \ERB (Embedded Ruby) -An easy to use but powerful templating system for Ruby. +\ERB is an easy-to-use, but also very powerful, [template processor][template processor]. -## Introduction +\ERB is commonly used to produce: -ERB provides an easy to use but powerful templating system for Ruby. Using -ERB, actual Ruby code can be added to any plain text document for the -purposes of generating document information details and/or flow control. +- Customized or personalized email messages. +- Customized or personalized web pages. +- Software code (in code-generating applications). -A very simple example is this: +Like method [sprintf][sprintf], \ERB can format run-time data into a string. +\ERB, however, is *much more powerful* -```rb -require 'erb' +## How \ERB Works -x = 42 -template = ERB.new <<-EOF - The value of x is: <%= x %> -EOF -puts template.result(binding) -``` +Using \ERB, you can create a *template*: a plain-text string that has specially-formatted *tags*, +then store it into an \ERB object; +when \ERB produces _result_ string, it: -Prints: `The value of x is: 42` +- Inserts run-time-evaluated expressions into the result. +- Executes snippets of Ruby code. +- Omits comments from the results. -More complex examples are given below. +In the result: -## Recognized Tags +- All non-tag text is passed through, _unchanged_. +- Each tag is either _replaced_ (expression tag), + or _omitted_ entirely (execution tag or comment tag). -ERB recognizes certain tags in the provided template and converts them based -on the rules below: +There are three types of tags: -```erb -<% Ruby code -- inline with output %> -<%= Ruby expression -- replace with result %> -<%# comment -- ignored -- useful in testing %> (`<% #` doesn't work. Don't use Ruby comments.) -% a line of Ruby code -- treated as <% line %> (optional -- see ERB.new) -%% replaced with % if first thing on a line and % processing is used -<%% or %%> -- replace with <% or %> respectively -``` +| Tag | Form | Action | Text in Result | +|----------------|:------------------------------------:|:-------------------------------------:|:--------------------:| +| Expression tag | '<%= _ruby_expression_ %>' | Evaluates _ruby_expression_. | Value of expression. | +| Execution tag | '<% _ruby_code_ %>' | Execute _ruby_code_. | None. | +| Comment tag | '<%# _comment_text_ %>' | None. | None. | -All other text is passed through ERB filtering unchanged. +These examples use `erb`, the \ERB command-line interface; +each "echoes" a string template and pipes it to `erb` as input: -## Options -There are several settings you can change when you use ERB: -* the nature of the tags that are recognized; -* the binding used to resolve local variables in the template. +- Expression tag: -See the ERB.new and ERB#result methods for more detail. + $ echo "<%= $VERBOSE %>" | erb + "false" + $ echo "<%= 2 + 2 %>" | erb + "4" -## Character encodings +- Execution tag: -ERB (or Ruby code generated by ERB) returns a string in the same -character encoding as the input string. When the input string has -a magic comment, however, it returns a string in the encoding specified -by the magic comment. + echo "<% if $VERBOSE %> Long message. <% else %> Short message. <% end %>" | erb + " Short message. " -```rb -# -*- coding: utf-8 -*- -require 'erb' +- Comment tag: -template = ERB.new < - __ENCODING__ is <%= __ENCODING__ %>. -EOF -puts template.result -``` + echo "<%# TODO: Fix this nonsense. %> Nonsense." | erb + " Nonsense." -Prints: `__ENCODING__ is Big5.` +## How to Use \ERB -## Examples +You can use \ERB either: -### Plain Text +- In a program: see class ERB. +- From the command line: see [ERB Executable][erb executable]. -ERB is useful for any generic templating situation. Note that in this example, we use the -convenient "% at start of line" tag, and we quote the template literally with -`%q{...}` to avoid trouble with the backslash. +## Installation -```rb -require "erb" +\ERB is installed with Ruby, and so there's no further installation needed. -# Create template. -template = %q{ - From: James Edward Gray II - To: <%= to %> - Subject: Addressing Needs +## Other Template Engines - <%= to[/\w+/] %>: - - Just wanted to send a quick note assuring that your needs are being - addressed. - - I want you to know that my team will keep working on the issues, - especially: - - <%# ignore numerous minor requests -- focus on priorities %> - % priorities.each do |priority| - * <%= priority %> - % end - - Thanks for your patience. - - James Edward Gray II -}.gsub(/^ /, '') - -message = ERB.new(template, trim_mode: "%<>") - -# Set up template data. -to = "Community Spokesman " -priorities = [ "Run Ruby Quiz", - "Document Modules", - "Answer Questions on Ruby Talk" ] - -# Produce result. -email = message.result -puts email -``` - -Generates: - -``` -From: James Edward Gray II -To: Community Spokesman -Subject: Addressing Needs - -Community: - -Just wanted to send a quick note assuring that your needs are being addressed. - -I want you to know that my team will keep working on the issues, especially: - - * Run Ruby Quiz - * Document Modules - * Answer Questions on Ruby Talk - -Thanks for your patience. - -James Edward Gray II -``` - -### Ruby in HTML - -ERB is often used in .rhtml files (HTML with embedded Ruby). Notice the need in -this example to provide a special binding when the template is run, so that the instance -variables in the Product object can be resolved. - -```rb -require "erb" - -# Build template data class. -class Product - def initialize( code, name, desc, cost ) - @code = code - @name = name - @desc = desc - @cost = cost - - @features = [ ] - end - - def add_feature( feature ) - @features << feature - end - - # Support templating of member data. - def get_binding - binding - end - - # ... -end - -# Create template. -template = %{ - - Ruby Toys -- <%= @name %> - - -

<%= @name %> (<%= @code %>)

-

<%= @desc %>

- -
    - <% @features.each do |f| %> -
  • <%= f %>
  • - <% end %> -
- -

- <% if @cost < 10 %> - Only <%= @cost %>!!! - <% else %> - Call for a price, today! - <% end %> -

- - - -}.gsub(/^ /, '') - -rhtml = ERB.new(template) +There are a variety of template engines available in various Ruby projects. +For example, [RDoc][rdoc], distributed with Ruby, uses its own template engine, which +can be reused elsewhere. -# Set up template data. -toy = Product.new( "TZ-1002", - "Rubysapien", - "Geek's Best Friend! Responds to Ruby commands...", - 999.95 ) -toy.add_feature("Listens for verbal commands in the Ruby language!") -toy.add_feature("Ignores Perl, Java, and all C variants.") -toy.add_feature("Karate-Chop Action!!!") -toy.add_feature("Matz signature on left leg.") -toy.add_feature("Gem studded eyes... Rubies, of course!") +Other popular template engines may be found in the [Ruby Toolbox][ruby toolbox]. -# Produce result. -rhtml.run(toy.get_binding) -``` +## Code -Generates (some blank lines removed): +The \ERB source code is in GitHub project [ruby/erb][ruby/erb]/ -```html - - Ruby Toys -- Rubysapien - - -

Rubysapien (TZ-1002)

-

Geek's Best Friend! Responds to Ruby commands...

- -
    -
  • Listens for verbal commands in the Ruby language!
  • -
  • Ignores Perl, Java, and all C variants.
  • -
  • Karate-Chop Action!!!
  • -
  • Matz signature on left leg.
  • -
  • Gem studded eyes... Rubies, of course!
  • -
- -

- Call for a price, today! -

- - - -``` - -## Notes - -There are a variety of templating solutions available in various Ruby projects. -For example, RDoc, distributed with Ruby, uses its own template engine, which -can be reused elsewhere. +## Bugs -Other popular engines could be found in the corresponding -[Category](https://www.ruby-toolbox.com/categories/template_engines) of -The Ruby Toolbox. +Bugs may be reported at [ERB Issues][erb issues]. ## License -The gem is available as open source under the terms of the [2-Clause BSD License](https://opensource.org/licenses/BSD-2-Clause). +This software is available as open source under the terms +of the [2-Clause BSD License][2-clause bsd license]. + +[2-clause bsd license]: https://opensource.org/licenses/BSD-2-Clause +[erb executable]: rdoc-ref:erb_executable.md +[erb issues]: https://github.com/ruby/erb/issues +[rdoc]: https://ruby.github.io/rdoc/ +[ruby/erb]: https://github.com/ruby/erb +[ruby toolbox]: https://www.ruby-toolbox.com/categories/template_engines +[sprintf]: https://docs.ruby-lang.org/en/master/Kernel.html#method-i-sprintf +[template processor]: https://en.wikipedia.org/wiki/Template_processor_ diff --git a/_doc/erb_executable.md b/_doc/erb_executable.md new file mode 100644 index 0000000..87a7883 --- /dev/null +++ b/_doc/erb_executable.md @@ -0,0 +1,240 @@ +# \ERB Executable + +The `erb` executable gives command-line access to ERB template processing. + +The executable is installed with \ERB, which is part of the Ruby installation. + +For a quick summary, type: + +```bash +$ erb --help +``` + +The format of the command is +`erb [_options_] [_filepaths_]`, +where: + +- _options_ are zero or more [options][options]. +- _filepaths_ are zero or more paths to files, each containing an plain text + that can include \ERB tags. + +## Filepaths + +With one or more _filepaths_ given, `erb` reads all the given files as a single template; +that is, `erb` processes multiple files into a single result: + +```bash +$ cat t.erb +<%= RUBY_VERSION %> +<%= Time.now %> +$ cat u.erb +% Encoding.list.take(4).each do |encoding| +* <%= encoding %> +% end +$ erb t.erb u.erb +3.4.5 +2025-09-24 00:23:00 +0100 +* ASCII-8BIT +* UTF-8 +* US-ASCII +* UTF-16BE +``` + +There is a special "filepath", `'-'`, that specifies the standard input: + +```bash +$ echo "<%= RUBY_VERSION %>" | erb u.erb - +* ASCII-8BIT +* UTF-8 +* US-ASCII +* UTF-16BE +3.4.5 +``` + +Any filepath, including `'-'`, may be repeated. + +With no _filepaths_ given, `erb` reads and processes the standard input: + +```bash +$ echo "<%= RUBY_VERSION %>" | erb # Prints the ERB version string. +``` + +## Options + +### `-d`, `--debug`: Set $DEBUG + +Use option `-d` or `--debug` to turn on debugging output: + +```bash +$ echo "<%= $DEBUG %>" | erb +"false" +$echo "<%= $DEBUG %>" | erb --debug +"true" +``` + +### `-E`, `--encoding`: Set Encodings + +Use option `-E` or `--encoding` to set the default external encoding to `_ex_` +and, if `_in_` is given, to set the default internal encoding to `_in_`. + +Each encoding, `ex` and `in`, must be the name of an Encoding: + +``` +erb -E ASCII-8BIT:ASCII-8BIT t.erb +``` + +### `-h`, `--help`: Print Help + +Use option `-h` or `--help` to print `erb` help text: + +```bash +$ erb --help +``` + +### `-n`: Print Source with Line Numbers + +Use option `-n` with option `-x` to print the output of ERB#src, +with numbered lines: + +```bash +$ cat t.erb +<%= RUBY_VERSION %> +<%= Time.now %> +$ erb -n -x t.erb + 1 #coding:UTF-8 + 2 _erbout = +''; _erbout.<<(( RUBY_VERSION ).to_s); _erbout.<< "\n".freeze + 3 ; _erbout.<<(( Time.now ).to_s); _erbout.<< "\n".freeze + 4 ; _erbout +``` + +Using option `-n` without option `-x` has no effect: + +```bash +$ erb -n t.erb +3.4.5 +2025-09-23 02:44:57 +0100 +``` + +### `-P`: Disable Execution Tag Shorthand + +By default, `erb` enables [execution tag shorthand][execution tag shorthand]: + +``` +$ cat u.erb +% Encoding.list.take(4).each do |encoding| +* <%= encoding %> +% end +$ erb u.erb +* ASCII-8BIT +* UTF-8 +* US-ASCII +* UTF-16BE +``` + +You can use option `-P` to disable the shorthand: + +``` +$ erb -P u.erb # Raises NameError: "undefined local variable or method 'encoding'" +``` + +### `-r`: Load Library + +You can use option `-r` to load a library; +the option may be given multiple times, to load multiple libraries: + +``` +$ erb -r csv -r bigdecimal t.erb +``` + +### `-T`: Set Trim Mode + +You can use option `-T` to set the trim mode. + +The values for the option are: + +- `'0'`, meaning `'%'`; enable execution tag shorthand; + see [execution tag shorthand][execution tag shorthand]. +- `'1'`, meaning `'%>'`: enable execution tag shorthand and omit newline for each line ending with `'%>'`; + see [suppressing unwanted newlines][suppressing unwanted newlines]. +- `'2'`, meaning `'<>'`: to suppress the trailing newline for each line + that both begins with `'<%'` and ends with `'%>'`; + see [suppressing unwanted newlines][suppressing unwanted newlines]. +- `'-'`, meaning `'%-'`: enable execution tag shorthand and omit each blank line ending with `'-%>'`. + see [execution tag shorthand][execution tag shorthand] + and [suppressing unwanted blank lines][suppressing unwanted blank lines]. + +Example: + +```bash +$ erb -T 0 t.erb +``` + +### `-U`: Set Default Encodings to UTF-8 + +You can use option `-U` to set both external and internal encodings to UTF-8: + +```bash +$ erb -U t.erb +``` + +### `-v`: Set $VERBOSE + +Use option `-v` to turn on verbose output: + +```bash +$ $ "<%= $VERBOSE %>" | erb +"false" +$ echo "<%= $VERBOSE %>" | erb -v +"true" +``` + +### `-v`: Print \ERB Version + +Use option `--version` to print the \ERB version string: + +```bash +$ erb --version +``` + +### `-x`: Print Source + +Use option `-x` to print the output of ERB#src, +which is the Ruby code that is to be run when ERB#result is called: + +```bash +$ cat t.erb +<%= RUBY_VERSION %> +<%= Time.now %> +$ erb -x t.erb +#coding:UTF-8 +_erbout = +''; _erbout.<<(( RUBY_VERSION ).to_s); _erbout.<< "\n".freeze +; _erbout.<<(( Time.now ).to_s); _erbout.<< "\n".freeze +; _erbout +``` + +### `--`: End of Options + +You can use option `'--'` to declare the end of options in the `erb` command; +`erb` treats each word following as a filepath (even if it looks like an option): + +``` +erb -- --help # Raises Errno::ENOENT: "No such file or directory @ rb_sysopen - --help" +``` + +### `name=value`: Set the Value of a Variable + +You can use option `name=value` to set the value of the variable named `name` +to the given `value`. + +The option may be given multiple times to set multiple variables: + +```bash +$ echo "<%= foo %> <%= bar %>" | erb foo=1 bar=2 +"1 2" +``` + +[erb.new]: https://docs.ruby-lang.org/en/master/ERB.html#method-c-new. +[execution tag shorthand]: rdoc-ref:ERB@Shorthand+Format+for+Execution+Tags +[options]: rdoc-ref:erb_executable.md@Options +[suppressing unwanted blank lines]: rdoc-ref:ERB@Suppressing+Unwanted+Blank+Lines +[suppressing unwanted newlines]: rdoc-ref:ERB@Suppressing+Unwanted+Newlines \ No newline at end of file diff --git a/lib/erb.rb b/lib/erb.rb index b9b4ef7..884a630 100644 --- a/lib/erb.rb +++ b/lib/erb.rb @@ -12,6 +12,24 @@ # # You can redistribute it and/or modify it under the same terms as Ruby. +# A NOTE ABOUT TERMS: +# +# Formerly: The documentation in this file used the term _template_ to refer to an ERB object. +# +# Now: The documentation in this file uses the term _template_ +# to refer to the string input to ERB.new. +# +# The reason for the change: When documenting the ERB executable erb, +# we need a term that refers to its string input; +# _source_ is not a good idea, because ERB#src means something entirely different; +# the two different sorts of sources would bring confusion. +# +# Therefore we use the term _template_ to refer to: +# +# - The string input to ERB.new +# - The string input to executable erb. +# + require 'erb/version' require 'erb/compiler' require 'erb/def_method' @@ -22,15 +40,6 @@ # Class **ERB** (the name stands for **Embedded Ruby**) # is an easy-to-use, but also very powerful, [template processor][template processor]. # -# Like method [sprintf][sprintf], \ERB can format run-time data into a string. -# \ERB, however,s is *much more powerful*. -# -# \ERB is commonly used to produce: -# -# - Customized or personalized email messages. -# - Customized or personalized web pages. -# - Software code (in code-generating applications). -# # ## Usage # # Before you can use \ERB, you must first require it @@ -44,7 +53,8 @@ # # Here's how \ERB works: # -# - You can create an \ERB object (a *template*) to store text that includes specially formatted *tags*. +# - You can create a *template*: a plain-text string that includes specially formatted *tags*.. +# - You can create an \ERB object to store the template. # - You can call instance method ERB#result to get the *result*. # # \ERB supports tags of three kinds: @@ -53,83 +63,85 @@ # each begins with `'<%'`, ends with `'%>'`; contains a Ruby expression; # in the result, the value of the expression replaces the entire tag: # +# template = 'The magic word is <%= magic_word %>.' +# erb = ERB.new(template) # magic_word = 'xyzzy' -# template.result(binding) # => "The magic word is xyzzy." -# -# ERB.new('Today is <%= Date::DAYNAMES[Date.today.wday] %>.').result # => "Today is Monday." +# erb.result(binding) # => "The magic word is xyzzy." # -# The first call to #result passes argument `binding`, +# The above call to #result passes argument `binding`, # which contains the binding of variable `magic_word` to its string value `'xyzzy'`. # -# The second call need not pass a binding, +# The below call to #result need not pass a binding, # because its expression `Date::DAYNAMES` is globally defined. # +# ERB.new('Today is <%= Date::DAYNAMES[Date.today.wday] %>.').result # => "Today is Monday." +# # - [Execution tags][execution tags]: # each begins with `'<%='`, ends with `'%>'`; contains Ruby code to be executed: # -# s = '<% File.write("t.txt", "Some stuff.") %>' -# ERB.new(s).result +# template = '<% File.write("t.txt", "Some stuff.") %>' +# ERB.new(template).result # File.read('t.txt') # => "Some stuff." # # - [Comment tags][comment tags]: # each begins with `'<%#'`, ends with `'%>'`; contains comment text; # in the result, the entire tag is omitted. # -# s = 'Some stuff;<%# Note to self: figure out what the stuff is. %> more stuff.' -# ERB.new(s).result # => "Some stuff; more stuff." +# template = 'Some stuff;<%# Note to self: figure out what the stuff is. %> more stuff.' +# ERB.new(template).result # => "Some stuff; more stuff." # # ## Some Simple Examples # # Here's a simple example of \ERB in action: # # ``` -# s = 'The time is <%= Time.now %>.' -# template = ERB.new(s) -# template.result +# template = 'The time is <%= Time.now %>.' +# erb = ERB.new(template) +# erb.result # # => "The time is 2025-09-09 10:49:26 -0500." # ``` # # Details: # -# 1. A plain-text string is assigned to variable `s`. +# 1. A plain-text string is assigned to variable `template`. # Its embedded [expression tag][expression tags] `'<%= Time.now %>'` includes a Ruby expression, `Time.now`. -# 2. The string is put into a new \ERB object, and stored in variable `template`. -# 4. Method call `template.result` generates a string that contains the run-time value of `Time.now`, +# 2. The string is put into a new \ERB object, and stored in variable `erb`. +# 4. Method call `erb.result` generates a string that contains the run-time value of `Time.now`, # as computed at the time of the call. # -# The template may be re-used: +# The +# \ERB object may be re-used: # # ``` -# template.result +# erb.result # # => "The time is 2025-09-09 10:49:33 -0500." # ``` # # Another example: # # ``` -# s = 'The magic word is <%= magic_word %>.' -# template = ERB.new(s) +# template = 'The magic word is <%= magic_word %>.' +# erb = ERB.new(template) # magic_word = 'abracadabra' -# # => "abracadabra" -# template.result(binding) +# erb.result(binding) # # => "The magic word is abracadabra." # ``` # # Details: # -# 1. As before, a plain-text string is assigned to variable `s`. +# 1. As before, a plain-text string is assigned to variable `template`. # Its embedded [expression tag][expression tags] `'<%= magic_word %>'` has a variable *name*, `magic_word`. -# 2. The string is put into a new \ERB object, and stored in variable `template`; +# 2. The string is put into a new \ERB object, and stored in variable `erb`; # note that `magic_word` need not be defined before the \ERB object is created. # 3. `magic_word = 'abracadabra'` assigns a value to variable `magic_word`. -# 4. Method call `template.result(binding)` generates a string +# 4. Method call `erb.result(binding)` generates a string # that contains the *value* of `magic_word`. # -# As before, the template may be re-used: +# As before, the \ERB object may be re-used: # # ``` # magic_word = 'xyzzy' -# template.result(binding) +# erb.result(binding) # # => "The magic word is xyzzy." # ``` # @@ -157,18 +169,17 @@ # these expression tags refer only to Ruby's global constant `RUBY_COPYRIGHT` and global variable `$0`: # # ``` -# s = <. # The current process is <%= $0 %>. -# EOT -# puts ERB.new(s).result +# TEMPLATE +# puts ERB.new(template).result # The Ruby copyright is "ruby - Copyright (C) 1993-2025 Yukihiro Matsumoto". # The current process is irb. # ``` # # (The current process is `irb` because that's where we're doing these examples!) # -# # ### Local Binding # # The default binding is *not* sufficient for an expression @@ -177,26 +188,27 @@ # ``` # Foo = 1 # Defines local constant Foo. # foo = 2 # Defines local variable foo. -# s = <. # The current value of variable foo is <%= foo %>. # The Ruby copyright is <%= RUBY_COPYRIGHT.inspect %>. # The current process is <%= $0 %>. -# EOT +# TEMPLATE +# erb = ERB.new(template) # ``` # -# This call raises `NameError` because although `Foo` and `foo` are defined locally, +# This call below raises `NameError` because although `Foo` and `foo` are defined locally, # they are not defined in the default binding: # # ``` -# ERB.new(s).result # Raises NameError. +# erb.result # Raises NameError. # ``` # # To make the locally-defined constants and variables available, # you can call #result with the local binding: # # ``` -# puts ERB.new(s).result(binding) +# puts erb.result(binding) # The current value of constant Foo is 1. # The current value of variable foo is 2. # The Ruby copyright is "ruby - Copyright (C) 1993-2025 Yukihiro Matsumoto". @@ -211,19 +223,21 @@ # in a copy of the default binding: # # ``` -# s = <. # The current value of variable baz is <%= baz %>. # The Ruby copyright is <%= RUBY_COPYRIGHT.inspect %>. # The current process is <%= $0 %>. +# TEMPLATE +# erb = ERB.new(template) # ``` # # Both of these calls raise `NameError`, because `bar` and `baz` # are not defined in either the default binding or the local binding. # # ``` -# puts ERB.new(s).result # Raises NameError. -# puts ERB.new(s).result(binding) # Raises NameError. +# puts erb.result # Raises NameError. +# puts erb.result(binding) # Raises NameError. # ``` # # This call passes a hash that causes `bar` and `baz` to be defined @@ -231,14 +245,11 @@ # # ``` # hash = {bar: 3, baz: 4} -# # => {bar: 3, baz: 4} -# ERB.new(s).result_with_hash(hash) -# puts ERB.new(s).result_with_hash(variables) +# puts erb.result_with_hash(hash) # The current value of variable bar is 3. # The current value of variable baz is 4. # The Ruby copyright is "ruby - Copyright (C) 1993-2025 Yukihiro Matsumoto". # The current process is irb. -# EOT # ``` # # ## Tags @@ -246,7 +257,7 @@ # The examples above use expression tags. # These are the tags available in \ERB: # -# - [Expression tag][expression tags]: the tag contains a Ruby exprssion; +# - [Expression tag][expression tags]: the tag contains a Ruby expression; # in the result, the entire tag is to be replaced with the run-time value of the expression. # - [Execution tag][execution tags]: the tag contains Ruby code; # in the result, the entire tag is to be replaced with the run-time value of the code. @@ -310,19 +321,19 @@ # Conditional: # # ``` -# s = < # An error has occurred. # <% else %> # Oops! # <% end %> -# EOT -# template = ERB.new(s) +# TEMPLATE +# erb = ERB.new(template) # verbosity = true -# template.result(binding) +# erb.result(binding) # # => "\nAn error has occurred.\n\n" # verbosity = false -# template.result(binding) +# erb.result(binding) # # => "\nOops!\n\n" # ``` # @@ -331,12 +342,12 @@ # Loop: # # ``` -# s = < # <%= dayname %> # <% end %> -# EOT -# ERB.new(s).result +# TEMPLATE +# ERB.new(template).result # # => "\nSun\n\nMon\n\nTue\n\nWed\n\nThu\n\nFri\n\nSat\n\n" # ``` # @@ -344,20 +355,20 @@ # and the Ruby code may itself contain regular Ruby comments: # # ``` -# s = < # <%= Time.now %> # <% sleep(1) # Let's make the times different. %> # <% end %> -# EOT -# ERB.new(s).result +# TEMPLATE +# ERB.new(template).result # # => "\n2025-09-09 11:36:02 -0500\n\n\n2025-09-09 11:36:03 -0500\n\n\n2025-09-09 11:36:04 -0500\n\n\n" # ``` # # The execution tag may also contain multiple lines of code: # # ``` -# s = < -# EOT -# ERB.new(s).result +# TEMPLATE +# ERB.new(template).result # # => "\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" # ``` # @@ -378,16 +389,16 @@ # this example uses the shorthand format `% _code_` instead of `<% _code_ %>`: # # ``` -# s = < # % end -# EOT -# template = ERB.new(s, trim_mode: '%') +# TEMPLATE +# erb = ERB.new(template, trim_mode: '%') # priorities = [ 'Run Ruby Quiz', # 'Document Modules', # 'Answer Questions on Ruby Talk' ] -# puts template.result(binding) +# puts erb.result(binding) # * Run Ruby Quiz # * Document Modules # * Answer Questions on Ruby Talk @@ -402,12 +413,12 @@ # all blank lines go into the result: # # ``` -# s = < # <%= RUBY_VERSION %> # <% end %> -# EOT -# ERB.new(s).result.lines.each {|line| puts line.inspect } +# TEMPLATE +# ERB.new(template).result.lines.each {|line| puts line.inspect } # "\n" # "3.4.5\n" # "\n" @@ -417,38 +428,38 @@ # whose source line ends with `-%>` (instead of `%>`): # # ``` -# s = < # <%= RUBY_VERSION %> # <% end -%> -# EOT -# ERB.new(s, trim_mode: '-').result.lines.each {|line| puts line.inspect } +# TEMPLATE +# ERB.new(template, trim_mode: '-').result.lines.each {|line| puts line.inspect } # "3.4.5\n" # ``` # # It is an error to use the trailing `'-%>'` notation without `trim_mode: '-'`: # # ``` -# ERB.new(s).result.lines.each {|line| puts line.inspect } # Raises SyntaxError. +# ERB.new(template).result.lines.each {|line| puts line.inspect } # Raises SyntaxError. # ``` # # #### Suppressing Unwanted Newlines # -# Consider this input string: +# Consider this template: # # ``` -# s = < # <%= RUBY_VERSION %> # foo <% RUBY_VERSION %> # foo <%= RUBY_VERSION %> -# EOT +# TEMPLATE # ``` # # With keyword argument `trim_mode` not given, all newlines go into the result: # # ``` -# ERB.new(s).result.lines.each {|line| puts line.inspect } +# ERB.new(template).result.lines.each {|line| puts line.inspect } # "\n" # "3.4.5\n" # "foo \n" @@ -459,7 +470,7 @@ # for each line that ends with `'%<'` (regardless of its beginning): # # ``` -# ERB.new(s, trim_mode: '>').result.lines.each {|line| puts line.inspect } +# ERB.new(template, trim_mode: '>').result.lines.each {|line| puts line.inspect } # "3.4.5foo foo 3.4.5" # ``` # @@ -467,7 +478,7 @@ # for each line that both begins with `'<%'` and ends with `'%>'`: # # ``` -# ERB.new(s, trim_mode: '<>').result.lines.each {|line| puts line.inspect } +# ERB.new(template, trim_mode: '<>').result.lines.each {|line| puts line.inspect } # "3.4.5foo \n" # "foo 3.4.5\n" # ``` @@ -493,11 +504,11 @@ # Example: # # ``` -# s = 'Some stuff;<%# Note to self: figure out what the stuff is. %> more stuff.' -# ERB.new(s).result # => "Some stuff; more stuff." +# template = 'Some stuff;<%# Note to self: figure out what the stuff is. %> more stuff.' +# ERB.new(template).result # => "Some stuff; more stuff." # ``` # -# A comment tag may appear anywhere in the template text. +# A comment tag may appear anywhere in the template. # # Note that the beginning of the tag must be `'<%#'`, not `'<% #'`. # @@ -511,32 +522,32 @@ # # ## Encodings # -# An \ERB template has an [encoding][encoding], -# which is by default the encoding of the source string; +# An \ERB object has an [encoding][encoding], +# which is by default the encoding of the template string; # the result string will also have that encoding. # # ``` -# s = < -# EOT -# template = ERB.new(s) -# s.encoding # => # -# template.encoding # => # -# template.result.encoding # => # +# TEMPLATE +# erb = ERB.new(template) +# template.encoding # => # +# erb.encoding # => # +# erb.result.encoding # => # # ``` # # You can specify a different encoding by adding a [magic comment][magic comments] -# at the top of the given string: +# at the top of the given template: # # ``` -# s = < # <%# Comment. %> -# EOT -# template = ERB.new(s) -# s.encoding # => # -# template.encoding # => # -# template.result.encoding # => # +# TEMPLATE +# erb = ERB.new(template) +# template.encoding # => # +# erb.encoding # => # +# erb.result.encoding # => # # ``` # # ## Error Reporting @@ -544,8 +555,8 @@ # Consider this template (containing an error): # # ``` -# s = '<%= nosuch %>' -# template = ERB.new(s) +# template = '<%= nosuch %>' +# erb = ERB.new(template) # ``` # # When \ERB reports an error, @@ -556,9 +567,9 @@ # these initial values are reported as `'(erb)'` and `1`, respectively: # # ``` -# template.filename # => nil -# template.lineno # => 0 -# template.result +# erb.filename # => nil +# erb.lineno # => 0 +# erb.result # (erb):1:in '
': undefined local variable or method 'nosuch' for main (NameError) # ``` # @@ -566,31 +577,29 @@ # that are more meaningful in your context: # # ``` -# template.filename = 't.txt' -# # => "t.txt" -# template.lineno = 555 -# # => 555 -# template.result +# erb.filename = 't.txt' +# erb.lineno = 555 +# erb.result # t.txt:556:in '
': undefined local variable or method 'nosuch' for main (NameError) # ``` # # You can use method #location= to set both values: # # ``` -# template.location = ['u.txt', 999] -# template.result +# erb.location = ['u.txt', 999] +# erb.result # u.txt:1000:in '
': undefined local variable or method 'nosuch' for main (NameError) # ``` # -# ## Plain Text Example +# ## Plain Text with Embedded Ruby # -# Here's a plain-text string; -# it uses the literal notation `'%q{ ... }'` to define the string +# Here's a plain-text template; +# it uses the literal notation `'%q{ ... }'` to define the template # (see [%q literals][%q literals]); # this avoids problems with backslashes. # # ``` -# s = %q{ +# template = %q{ # From: James Edward Gray II # To: <%= to %> # Subject: Addressing Needs @@ -623,11 +632,11 @@ # 'Answer Questions on Ruby Talk' ] # ``` # -# Finally, make the template and get the result +# Finally, create the \ERB object and get the result # # ``` -# template = ERB.new(s, trim_mode: '%<>') -# puts template.result(binding) +# erb = ERB.new(template, trim_mode: '%<>') +# puts erb.result(binding) # # From: James Edward Gray II # To: Community Spokesman @@ -650,7 +659,7 @@ # James Edward Gray II # ``` # -# ## HTML Example +# ## HTML with Embedded Ruby # # This example shows an HTML template. # @@ -696,7 +705,7 @@ # Here's the HTML: # # ``` -# s = < # Ruby Toys -- <%= @name %> # @@ -716,14 +725,14 @@ #

# # -# EOT +# TEMPLATE # ``` # -# Finally, build the template and get the result (omitting some blank lines): +# Finally, create the \ERB object and get the result (omitting some blank lines): # # ``` -# template = ERB.new(s) -# puts template.result(toy.get_binding) +# erb = ERB.new(template) +# puts erb.result(toy.get_binding) # # Ruby Toys -- Rubysapien # @@ -785,11 +794,11 @@ def self.version # :markup: markdown # # :call-seq: - # ERB.new(string, trim_mode: nil, eoutvar: '_erbout') + # ERB.new(template, trim_mode: nil, eoutvar: '_erbout') # - # Returns a new \ERB object containing the given +string+. + # Returns a new \ERB object containing the given string +template+. # - # For details about `string`, its embedded tags, and generated results, see ERB. + # For details about `template`, its embedded tags, and generated results, see ERB. # # **Keyword Argument `trim_mode`** # @@ -825,7 +834,7 @@ def self.version # which is: # # ``` - # ERB.new(string, + # ERB.new(template, # safe_level=NOT_GIVEN, legacy_trim_mode=NOT_GIVEN, legacy_eoutvar=NOT_GIVEN, # trim_mode: nil, eoutvar: '_erbout') # ``` @@ -892,23 +901,23 @@ def make_compiler(trim_mode) # :markup: markdown # - # Returns a string containing the Ruby code that, when executed, generates the result; + # Returns the Ruby code that, when executed, generates the result; # the code is executed by method #result, # and by its wrapper methods #result_with_hash and #run: # # ``` - # s = 'The time is <%= Time.now %>.' - # template = ERB.new(s) - # template.src + # template = 'The time is <%= Time.now %>.' + # erb = ERB.new(template) + # erb.src # # => "#coding:UTF-8\n_erbout = +''; _erbout.<< \"The time is \".freeze; _erbout.<<(( Time.now ).to_s); _erbout.<< \".\".freeze; _erbout" - # template.result + # erb.result # # => "The time is 2025-09-18 15:58:08 -0500." # ``` # # In a more readable format: # # ``` - # # puts template.src.split('; ') + # # puts erb.src.split('; ') # # #coding:UTF-8 # # _erbout = +'' # # _erbout.<< "The time is ".freeze @@ -922,7 +931,7 @@ def make_compiler(trim_mode) # and can be changed via keyword argument `eoutvar`: # # ``` - # template = ERB.new(s, eoutvar: '_foo') + # erb = ERB.new(template, eoutvar: '_foo') # puts template.src.split('; ') # #coding:UTF-8 # _foo = +'' @@ -1027,7 +1036,7 @@ def run(b=new_toplevel) # :call-seq: # result(binding = new_toplevel) -> new_string # - # Returns the new string formed by processing \ERB tags found in the stored string in `self`. + # Returns the string result formed by processing \ERB tags found in the stored template in `self`. # # With no argument given, uses the default binding; # see [Default Binding][default binding]. @@ -1050,9 +1059,9 @@ def result(b=new_toplevel) # :markup: markdown # # :call-seq: - # result_with_hash(hash) -> string + # result_with_hash(hash) -> new_string # - # Returns the new string formed by processing \ERB tags found in the stored string in `self`; + # Returns the string result formed by processing \ERB tags found in the stored string in `self`; # see [Augmented Binding][augmented binding]. # # See also #result. @@ -1112,10 +1121,10 @@ def new_toplevel(vars = nil) # [error reporting]: rdoc-ref:ERB@Error+Reporting # # ``` - # s = '<%= arg1 %> <%= arg2 %>' - # template = ERB.new(s) + # template = '<%= arg1 %> <%= arg2 %>' + # erb = ERB.new(template) # MyModule = Module.new - # template.def_method(MyModule, 'render(arg1, arg2)') # => :render + # erb.def_method(MyModule, 'render(arg1, arg2)') # => :render # class MyClass; include MyModule; end # MyClass.new.render('foo', 123) # => "foo 123" # ``` @@ -1135,8 +1144,8 @@ def def_method(mod, methodname, fname='(ERB)') # Returns a new nameless module that has instance method `method_name`. # # ``` - # s = '<%= arg1 %> <%= arg2 %>' - # template = ERB.new(s) + # template = '<%= arg1 %> <%= arg2 %>' + # erb = ERB.new(template) # MyModule = template.def_module('render(arg1, arg2)') # class MyClass # include MyModule @@ -1162,14 +1171,14 @@ def def_module(methodname='erb') # Create a template from HTML that has embedded expression tags that use `@arg1` and `@arg2`: # # ``` - # html = < # #

<%= @arg1 %>

#

<%= @arg2 %>

# # - # EOT + # TEMPLATE # template = ERB.new(html) # ``` # diff --git a/libexec/erb b/libexec/erb index 4381671..a1fb745 100755 --- a/libexec/erb +++ b/libexec/erb @@ -90,29 +90,49 @@ class ERB when '-P' disable_percent = true when '--help' - raise "print this help" + raise '' when /\A-/ - raise "unknown switch #{switch.dump}" + raise "Unknown switch: #{switch.dump}" else var, val = *switch.split('=', 2) (variables ||= {})[var] = val end end rescue # usage - STDERR.puts $!.to_s - STDERR.puts File.basename($0) + - " [switches] [var=value...] [inputfile]" + message = $!.to_s + STDERR.puts message unless message.empty? + STDERR.puts 'Usage:' + STDERR.puts " #{File.basename($0)} [options] [filepaths]" STDERR.puts <'; '2' means '<>'; '-' means '%-'. + -U Set default encoding to UTF-8. + -v Set $VERBOSE to enable debugging, + --version Print ERB version string and exit. + -x Print generated Ruby source code. + -- Treat all following words as filepaths (not options). + name=value Set the variable named name to the given string value. + +Filepaths: + The erb program reads the text from all files at the filepaths as a single ERB template: + plain text, possibly with embedded ERB tags; + filepaths may be repeated. + + The pseudo-filepath '-' (hyphen character) specifies the standard input. + + If no filepaths are given, the sole input is the standard input. + +See details and examples at https://docs.ruby-lang.org/en/master/erb_executable_md.html EOU exit 1 end