erb 5.0.2 → 6.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +1 -1
- data/.github/workflows/dependabot_automerge.yml +30 -0
- data/.github/workflows/push-gem.yml +51 -0
- data/.github/workflows/sync-ruby.yml +33 -0
- data/.github/workflows/test.yml +4 -1
- data/Gemfile +1 -0
- data/NEWS.md +30 -1
- data/README.md +64 -221
- data/_doc/erb_executable.md +240 -0
- data/erb.gemspec +1 -0
- data/ext/erb/escape/escape.c +20 -8
- data/lib/erb/compiler.rb +1 -2
- data/lib/erb/util.rb +16 -15
- data/lib/erb/version.rb +2 -1
- data/lib/erb.rb +970 -299
- data/libexec/erb +35 -15
- metadata +7 -2
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# \ERB Executable
|
|
2
|
+
|
|
3
|
+
The `erb` executable gives command-line access to ERB template processing.
|
|
4
|
+
|
|
5
|
+
The executable is installed with \ERB, which is part of the Ruby installation.
|
|
6
|
+
|
|
7
|
+
For a quick summary, type:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
$ erb --help
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
The format of the command is
|
|
14
|
+
`erb [_options_] [_filepaths_]`,
|
|
15
|
+
where:
|
|
16
|
+
|
|
17
|
+
- _options_ are zero or more [options][options].
|
|
18
|
+
- _filepaths_ are zero or more paths to files, each containing an plain text
|
|
19
|
+
that can include \ERB tags.
|
|
20
|
+
|
|
21
|
+
## Filepaths
|
|
22
|
+
|
|
23
|
+
With one or more _filepaths_ given, `erb` reads all the given files as a single template;
|
|
24
|
+
that is, `erb` processes multiple files into a single result:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
$ cat t.erb
|
|
28
|
+
<%= RUBY_VERSION %>
|
|
29
|
+
<%= Time.now %>
|
|
30
|
+
$ cat u.erb
|
|
31
|
+
% Encoding.list.take(4).each do |encoding|
|
|
32
|
+
* <%= encoding %>
|
|
33
|
+
% end
|
|
34
|
+
$ erb t.erb u.erb
|
|
35
|
+
3.4.5
|
|
36
|
+
2025-09-24 00:23:00 +0100
|
|
37
|
+
* ASCII-8BIT
|
|
38
|
+
* UTF-8
|
|
39
|
+
* US-ASCII
|
|
40
|
+
* UTF-16BE
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
There is a special "filepath", `'-'`, that specifies the standard input:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
$ echo "<%= RUBY_VERSION %>" | erb u.erb -
|
|
47
|
+
* ASCII-8BIT
|
|
48
|
+
* UTF-8
|
|
49
|
+
* US-ASCII
|
|
50
|
+
* UTF-16BE
|
|
51
|
+
3.4.5
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Any filepath, including `'-'`, may be repeated.
|
|
55
|
+
|
|
56
|
+
With no _filepaths_ given, `erb` reads and processes the standard input:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
$ echo "<%= RUBY_VERSION %>" | erb # Prints the ERB version string.
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Options
|
|
63
|
+
|
|
64
|
+
### `-d`, `--debug`: Set $DEBUG
|
|
65
|
+
|
|
66
|
+
Use option `-d` or `--debug` to turn on debugging output:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
$ echo "<%= $DEBUG %>" | erb
|
|
70
|
+
"false"
|
|
71
|
+
$echo "<%= $DEBUG %>" | erb --debug
|
|
72
|
+
"true"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### `-E`, `--encoding`: Set Encodings
|
|
76
|
+
|
|
77
|
+
Use option `-E` or `--encoding` to set the default external encoding to `_ex_`
|
|
78
|
+
and, if `_in_` is given, to set the default internal encoding to `_in_`.
|
|
79
|
+
|
|
80
|
+
Each encoding, `ex` and `in`, must be the name of an Encoding:
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
erb -E ASCII-8BIT:ASCII-8BIT t.erb
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### `-h`, `--help`: Print Help
|
|
87
|
+
|
|
88
|
+
Use option `-h` or `--help` to print `erb` help text:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
$ erb --help
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### `-n`: Print Source with Line Numbers
|
|
95
|
+
|
|
96
|
+
Use option `-n` with option `-x` to print the output of ERB#src,
|
|
97
|
+
with numbered lines:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
$ cat t.erb
|
|
101
|
+
<%= RUBY_VERSION %>
|
|
102
|
+
<%= Time.now %>
|
|
103
|
+
$ erb -n -x t.erb
|
|
104
|
+
1 #coding:UTF-8
|
|
105
|
+
2 _erbout = +''; _erbout.<<(( RUBY_VERSION ).to_s); _erbout.<< "\n".freeze
|
|
106
|
+
3 ; _erbout.<<(( Time.now ).to_s); _erbout.<< "\n".freeze
|
|
107
|
+
4 ; _erbout
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Using option `-n` without option `-x` has no effect:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
$ erb -n t.erb
|
|
114
|
+
3.4.5
|
|
115
|
+
2025-09-23 02:44:57 +0100
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### `-P`: Disable Execution Tag Shorthand
|
|
119
|
+
|
|
120
|
+
By default, `erb` enables [execution tag shorthand][execution tag shorthand]:
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
$ cat u.erb
|
|
124
|
+
% Encoding.list.take(4).each do |encoding|
|
|
125
|
+
* <%= encoding %>
|
|
126
|
+
% end
|
|
127
|
+
$ erb u.erb
|
|
128
|
+
* ASCII-8BIT
|
|
129
|
+
* UTF-8
|
|
130
|
+
* US-ASCII
|
|
131
|
+
* UTF-16BE
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
You can use option `-P` to disable the shorthand:
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
$ erb -P u.erb # Raises NameError: "undefined local variable or method 'encoding'"
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### `-r`: Load Library
|
|
141
|
+
|
|
142
|
+
You can use option `-r` to load a library;
|
|
143
|
+
the option may be given multiple times, to load multiple libraries:
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
$ erb -r csv -r bigdecimal t.erb
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### `-T`: Set Trim Mode
|
|
150
|
+
|
|
151
|
+
You can use option `-T` to set the trim mode.
|
|
152
|
+
|
|
153
|
+
The values for the option are:
|
|
154
|
+
|
|
155
|
+
- `'0'`, meaning `'%'`; enable execution tag shorthand;
|
|
156
|
+
see [execution tag shorthand][execution tag shorthand].
|
|
157
|
+
- `'1'`, meaning `'%>'`: enable execution tag shorthand and omit newline for each line ending with `'%>'`;
|
|
158
|
+
see [suppressing unwanted newlines][suppressing unwanted newlines].
|
|
159
|
+
- `'2'`, meaning `'<>'`: to suppress the trailing newline for each line
|
|
160
|
+
that both begins with `'<%'` and ends with `'%>'`;
|
|
161
|
+
see [suppressing unwanted newlines][suppressing unwanted newlines].
|
|
162
|
+
- `'-'`, meaning `'%-'`: enable execution tag shorthand and omit each blank line ending with `'-%>'`.
|
|
163
|
+
see [execution tag shorthand][execution tag shorthand]
|
|
164
|
+
and [suppressing unwanted blank lines][suppressing unwanted blank lines].
|
|
165
|
+
|
|
166
|
+
Example:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
$ erb -T 0 t.erb
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### `-U`: Set Default Encodings to UTF-8
|
|
173
|
+
|
|
174
|
+
You can use option `-U` to set both external and internal encodings to UTF-8:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
$ erb -U t.erb
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### `-v`: Set $VERBOSE
|
|
181
|
+
|
|
182
|
+
Use option `-v` to turn on verbose output:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
$ $ "<%= $VERBOSE %>" | erb
|
|
186
|
+
"false"
|
|
187
|
+
$ echo "<%= $VERBOSE %>" | erb -v
|
|
188
|
+
"true"
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### `-v`: Print \ERB Version
|
|
192
|
+
|
|
193
|
+
Use option `--version` to print the \ERB version string:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
$ erb --version
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### `-x`: Print Source
|
|
200
|
+
|
|
201
|
+
Use option `-x` to print the output of ERB#src,
|
|
202
|
+
which is the Ruby code that is to be run when ERB#result is called:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
$ cat t.erb
|
|
206
|
+
<%= RUBY_VERSION %>
|
|
207
|
+
<%= Time.now %>
|
|
208
|
+
$ erb -x t.erb
|
|
209
|
+
#coding:UTF-8
|
|
210
|
+
_erbout = +''; _erbout.<<(( RUBY_VERSION ).to_s); _erbout.<< "\n".freeze
|
|
211
|
+
; _erbout.<<(( Time.now ).to_s); _erbout.<< "\n".freeze
|
|
212
|
+
; _erbout
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### `--`: End of Options
|
|
216
|
+
|
|
217
|
+
You can use option `'--'` to declare the end of options in the `erb` command;
|
|
218
|
+
`erb` treats each word following as a filepath (even if it looks like an option):
|
|
219
|
+
|
|
220
|
+
```
|
|
221
|
+
erb -- --help # Raises Errno::ENOENT: "No such file or directory @ rb_sysopen - --help"
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### `name=value`: Set the Value of a Variable
|
|
225
|
+
|
|
226
|
+
You can use option `name=value` to set the value of the variable named `name`
|
|
227
|
+
to the given `value`.
|
|
228
|
+
|
|
229
|
+
The option may be given multiple times to set multiple variables:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
$ echo "<%= foo %> <%= bar %>" | erb foo=1 bar=2
|
|
233
|
+
"1 2"
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
[erb.new]: https://docs.ruby-lang.org/en/master/ERB.html#method-c-new.
|
|
237
|
+
[execution tag shorthand]: rdoc-ref:ERB@Shorthand+Format+for+Execution+Tags
|
|
238
|
+
[options]: rdoc-ref:erb_executable.md@Options
|
|
239
|
+
[suppressing unwanted blank lines]: rdoc-ref:ERB@Suppressing+Unwanted+Blank+Lines
|
|
240
|
+
[suppressing unwanted newlines]: rdoc-ref:ERB@Suppressing+Unwanted+Newlines
|
data/erb.gemspec
CHANGED
|
@@ -18,6 +18,7 @@ Gem::Specification.new do |spec|
|
|
|
18
18
|
|
|
19
19
|
spec.metadata['homepage_uri'] = spec.homepage
|
|
20
20
|
spec.metadata['source_code_uri'] = spec.homepage
|
|
21
|
+
spec.metadata['changelog_uri'] = "https://github.com/ruby/erb/blob/v#{spec.version}/NEWS.md"
|
|
21
22
|
|
|
22
23
|
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
|
23
24
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
data/ext/erb/escape/escape.c
CHANGED
|
@@ -39,29 +39,41 @@ static VALUE
|
|
|
39
39
|
optimized_escape_html(VALUE str)
|
|
40
40
|
{
|
|
41
41
|
VALUE vbuf;
|
|
42
|
-
char *buf =
|
|
42
|
+
char *buf = NULL;
|
|
43
43
|
const char *cstr = RSTRING_PTR(str);
|
|
44
44
|
const char *end = cstr + RSTRING_LEN(str);
|
|
45
45
|
|
|
46
|
-
char *
|
|
46
|
+
const char *segment_start = cstr;
|
|
47
|
+
char *dest = NULL;
|
|
47
48
|
while (cstr < end) {
|
|
48
49
|
const unsigned char c = *cstr++;
|
|
49
50
|
uint8_t len = html_escape_table[c].len;
|
|
50
51
|
if (len) {
|
|
52
|
+
size_t segment_len = cstr - segment_start - 1;
|
|
53
|
+
if (!buf) {
|
|
54
|
+
buf = ALLOCV_N(char, vbuf, escaped_length(str));
|
|
55
|
+
dest = buf;
|
|
56
|
+
}
|
|
57
|
+
if (segment_len) {
|
|
58
|
+
memcpy(dest, segment_start, segment_len);
|
|
59
|
+
dest += segment_len;
|
|
60
|
+
}
|
|
61
|
+
segment_start = cstr;
|
|
51
62
|
memcpy(dest, html_escape_table[c].str, len);
|
|
52
63
|
dest += len;
|
|
53
64
|
}
|
|
54
|
-
else {
|
|
55
|
-
*dest++ = c;
|
|
56
|
-
}
|
|
57
65
|
}
|
|
58
|
-
|
|
59
66
|
VALUE escaped = str;
|
|
60
|
-
if (
|
|
67
|
+
if (buf) {
|
|
68
|
+
size_t segment_len = cstr - segment_start;
|
|
69
|
+
if (segment_len) {
|
|
70
|
+
memcpy(dest, segment_start, segment_len);
|
|
71
|
+
dest += segment_len;
|
|
72
|
+
}
|
|
61
73
|
escaped = rb_str_new(buf, dest - buf);
|
|
62
74
|
preserve_original_state(str, escaped);
|
|
75
|
+
ALLOCV_END(vbuf);
|
|
63
76
|
}
|
|
64
|
-
ALLOCV_END(vbuf);
|
|
65
77
|
return escaped;
|
|
66
78
|
}
|
|
67
79
|
|
data/lib/erb/compiler.rb
CHANGED
|
@@ -225,7 +225,7 @@ class ERB::Compiler # :nodoc:
|
|
|
225
225
|
end
|
|
226
226
|
end
|
|
227
227
|
|
|
228
|
-
ERB_STAG = %w(<%= <%# <%)
|
|
228
|
+
ERB_STAG = %w(<%= <%# <%).freeze
|
|
229
229
|
def is_erb_stag?(s)
|
|
230
230
|
ERB_STAG.member?(s)
|
|
231
231
|
end
|
|
@@ -480,7 +480,6 @@ class ERB::Compiler # :nodoc:
|
|
|
480
480
|
end
|
|
481
481
|
}.new(caller(0)).c
|
|
482
482
|
private_constant :WARNING_UPLEVEL
|
|
483
|
-
# :startdoc:
|
|
484
483
|
|
|
485
484
|
def warn_invalid_trim_mode(mode, uplevel:)
|
|
486
485
|
warn "Invalid ERB trim mode: #{mode.inspect} (trim_mode: nil, 0, 1, 2, or String composed of '%' and/or '-', '>', '<>')", uplevel: uplevel + WARNING_UPLEVEL
|
data/lib/erb/util.rb
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
# Load CGI.escapeHTML and CGI.escapeURIComponent.
|
|
4
4
|
# CRuby:
|
|
5
|
-
# cgi.gem v0.1.0+ (Ruby 2.7-3.4) and Ruby
|
|
6
|
-
# cgi.gem v0.3.3+ (Ruby 3.2-3.4) and Ruby
|
|
5
|
+
# cgi.gem v0.1.0+ (Ruby 2.7-3.4) and Ruby 4.0+ stdlib have 'cgi/escape' and CGI.escapeHTML.
|
|
6
|
+
# cgi.gem v0.3.3+ (Ruby 3.2-3.4) and Ruby 4.0+ stdlib have CGI.escapeURIComponent.
|
|
7
7
|
# JRuby: cgi.gem has a Java extension 'cgi/escape'.
|
|
8
8
|
# TruffleRuby: lib/truffle/cgi/escape.rb requires 'cgi/util'.
|
|
9
9
|
require 'cgi/escape'
|
|
10
10
|
|
|
11
11
|
# Load or define ERB::Escape#html_escape.
|
|
12
|
-
# We don't build the C
|
|
12
|
+
# We don't build the C extension 'cgi/escape' for JRuby, TruffleRuby, and WASM.
|
|
13
13
|
# miniruby (used by CRuby build scripts) also fails to load erb/escape.so.
|
|
14
14
|
begin
|
|
15
15
|
require 'erb/escape'
|
|
@@ -19,6 +19,7 @@ rescue LoadError
|
|
|
19
19
|
# A subset of ERB::Util. Unlike ERB::Util#html_escape, we expect/hope
|
|
20
20
|
# Rails will not monkey-patch ERB::Escape#html_escape.
|
|
21
21
|
module ERB::Escape
|
|
22
|
+
# :stopdoc:
|
|
22
23
|
def html_escape(s)
|
|
23
24
|
CGI.escapeHTML(s.to_s)
|
|
24
25
|
end
|
|
@@ -47,19 +48,19 @@ module ERB::Util
|
|
|
47
48
|
alias h html_escape
|
|
48
49
|
module_function :h
|
|
49
50
|
|
|
50
|
-
#
|
|
51
|
-
# A utility method for encoding the String _s_ as a URL.
|
|
52
|
-
#
|
|
53
|
-
# require "erb"
|
|
54
|
-
# include ERB::Util
|
|
55
|
-
#
|
|
56
|
-
# puts url_encode("Programming Ruby: The Pragmatic Programmer's Guide")
|
|
57
|
-
#
|
|
58
|
-
# _Generates_
|
|
59
|
-
#
|
|
60
|
-
# Programming%20Ruby%3A%20%20The%20Pragmatic%20Programmer%27s%20Guide
|
|
61
|
-
#
|
|
62
51
|
if CGI.respond_to?(:escapeURIComponent)
|
|
52
|
+
#
|
|
53
|
+
# A utility method for encoding the String _s_ as a URL.
|
|
54
|
+
#
|
|
55
|
+
# require "erb"
|
|
56
|
+
# include ERB::Util
|
|
57
|
+
#
|
|
58
|
+
# puts url_encode("Programming Ruby: The Pragmatic Programmer's Guide")
|
|
59
|
+
#
|
|
60
|
+
# _Generates_
|
|
61
|
+
#
|
|
62
|
+
# Programming%20Ruby%3A%20%20The%20Pragmatic%20Programmer%27s%20Guide
|
|
63
|
+
#
|
|
63
64
|
def url_encode(s)
|
|
64
65
|
CGI.escapeURIComponent(s.to_s)
|
|
65
66
|
end
|
data/lib/erb/version.rb
CHANGED