ebnf 2.3.3 → 2.3.5

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.
data/lib/ebnf/writer.rb CHANGED
@@ -11,42 +11,81 @@ module EBNF
11
11
  LINE_LENGTH = 80
12
12
  LINE_LENGTH_HTML = 200
13
13
 
14
- # ASCII escape names
15
- ASCII_ESCAPE_NAMES = [
16
- "null", #x00
17
- "start of heading", #x01
18
- "start of text", #x02
19
- "end of text", #x03
20
- "end of transmission", #x04
21
- "enquiry", #x05
22
- "acknowledge", #x06
23
- "bell", #x07
24
- "backspace", #x08
25
- "horizontal tab", #x09
26
- "new line", #x0A
27
- "vertical tab", #x0B
28
- "form feed", #x0C
29
- "carriage return", #x0D
30
- "shift out", #x0E
31
- "shift in", #x0F
32
- "data link escape", #x10
33
- "device control 1", #x11
34
- "device control 2", #x12
35
- "device control 3", #x13
36
- "device control 4", #x14
37
- "negative acknowledge", #x15
38
- "synchronous idle", #x16
39
- "end of trans. block", #x17
40
- "cancel", #x18
41
- "end of medium", #x19
42
- "substitute", #x1A
43
- "escape", #x1B
44
- "file separator", #x1C
45
- "group separator", #x1D
46
- "record separator", #x1E
47
- "unit separator", #x1F
48
- "space" #x20
49
- ]
14
+ # UNICODE escape names
15
+ # From https://en.wikipedia.org/wiki/List_of_Unicode_characters
16
+ UNICODE_ESCAPE_NAMES = {
17
+ 0x00 => 'null',
18
+ 0x01 => 'start of heading',
19
+ 0x02 => 'start of text',
20
+ 0x03 => 'end of text',
21
+ 0x04 => 'end of transmission',
22
+ 0x05 => 'enquiry',
23
+ 0x06 => 'acknowledge',
24
+ 0x07 => 'bell',
25
+ 0x08 => 'backspace',
26
+ 0x09 => 'horizontal tab',
27
+ 0x0A => 'new line',
28
+ 0x0B => 'vertical tab',
29
+ 0x0C => 'form feed',
30
+ 0x0D => 'carriage return',
31
+ 0x0E => 'shift out',
32
+ 0x0F => 'shift in',
33
+ 0x10 => 'data link escape',
34
+ 0x11 => 'device control 1',
35
+ 0x12 => 'device control 2',
36
+ 0x13 => 'device control 3',
37
+ 0x14 => 'device control 4',
38
+ 0x15 => 'negative acknowledge',
39
+ 0x16 => 'synchronous idle',
40
+ 0x17 => 'end of trans. block',
41
+ 0x18 => 'cancel',
42
+ 0x19 => 'end of medium',
43
+ 0x1A => 'substitute',
44
+ 0x1B => 'escape',
45
+ 0x1C => 'file separator',
46
+ 0x1D => 'group separator',
47
+ 0x1E => 'record separator',
48
+ 0x1F => 'unit separator',
49
+ 0x20 => 'space',
50
+ 0x22 => 'dquote',
51
+ 0x27 => 'apos',
52
+ 0x2F => 'slash',
53
+ 0x5C => 'backslash',
54
+ 0x60 => 'grave',
55
+ 0x7F => 'delete',
56
+ 0x80 => 'padding character',
57
+ 0x81 => 'high octet preset',
58
+ 0x82 => 'break permitted here',
59
+ 0x83 => 'no break here',
60
+ 0x84 => 'index',
61
+ 0x85 => 'next line',
62
+ 0x86 => 'start of selected area',
63
+ 0x87 => 'end of selected area',
64
+ 0x88 => 'character tabulation set',
65
+ 0x89 => 'character tabulation with justification',
66
+ 0x8A => 'line tabulation set',
67
+ 0x8B => 'partial line forward',
68
+ 0x8C => 'partial line backward',
69
+ 0x8D => 'reverse line feed',
70
+ 0x8E => 'single-shift two',
71
+ 0x8F => 'single-shift three',
72
+ 0x90 => 'device control string',
73
+ 0x91 => 'private use 1',
74
+ 0x92 => 'private use 2',
75
+ 0x93 => 'set transmit state',
76
+ 0x94 => 'cancel character',
77
+ 0x95 => 'message waiting',
78
+ 0x96 => 'start of protected area',
79
+ 0x97 => 'end of protected area',
80
+ 0x98 => 'start of string',
81
+ 0x99 => 'single graphic character introducer',
82
+ 0x9A => 'single character intro introducer',
83
+ 0x9B => 'control sequence introducer',
84
+ 0x9C => 'string terminator',
85
+ 0x9D => 'operating system command',
86
+ 0x9E => 'private message',
87
+ 0x9F => 'application program command',
88
+ }
50
89
 
51
90
  ##
52
91
  # Format rules to a String
@@ -133,7 +172,8 @@ module EBNF
133
172
  formatted_rules = rules.map do |rule|
134
173
  if rule.kind == :terminals || rule.kind == :pass
135
174
  OpenStruct.new(id: ("@#{rule.kind}"),
136
- sym: nil,
175
+ class: :declaration,
176
+ sym: rule.kind,
137
177
  assign: nil,
138
178
  formatted: (
139
179
  rule.kind == :terminals ?
@@ -150,17 +190,18 @@ module EBNF
150
190
  split(/\s*--rule-extensions--\s*/).each_with_index do |formatted, ndx|
151
191
  assign = case format
152
192
  when :ebnf
153
- formatted.sub!(%r{\s*<code>\|</code>\s*}, '')
154
- (ndx > 0 ? (rule.alt? ? '|' : '') : '::=')
193
+ formatted.sub!(%r{\s*<code[^>]*>\|</code>\s*}, '')
194
+ (ndx > 0 ? (rule.alt? ? '<code class="grammar-alt">|</code>' : '') : '::=')
155
195
  when :abnf
156
- formatted.sub!(%r{\s*<code>/</code>\s*}, '')
157
- (ndx > 0 ? '=/' : '=')
196
+ formatted.sub!(%r{\s*<code[^>]>/</code>\s*}, '')
197
+ (ndx > 0 ? '<code class="grammar-alt">=/</code>' : '=')
158
198
  else
159
- formatted.sub!(%r{\s*<code>\|</code>\s*}, '')
160
- (ndx > 0 ? (rule.alt? ? '|' : '') : '=')
199
+ formatted.sub!(%r{\s*<code[^>]>\|</code>\s*}, '')
200
+ (ndx > 0 ? (rule.alt? ? '<code class="grammar-alt">|</code>' : '') : '=')
161
201
  end
162
202
  lines << OpenStruct.new(id: ((ndx == 0 ? "[#{rule.id}]" : "") if rule.id),
163
203
  sym: (rule.sym if ndx == 0 || format == :abnf),
204
+ class: :production,
164
205
  assign: assign,
165
206
  formatted: formatted)
166
207
  end
@@ -170,6 +211,7 @@ module EBNF
170
211
  lines
171
212
  else
172
213
  OpenStruct.new(id: ("[#{rule.id}]" if rule.id),
214
+ class: :production,
173
215
  sym: rule.sym,
174
216
  assign: (format == :ebnf ? '::=' : '='),
175
217
  formatted: (formatted_expr + (format == :isoebnf ? ' ;' : '')))
@@ -351,33 +393,25 @@ module EBNF
351
393
  end
352
394
  end
353
395
 
354
- res = "#{quote}#{string}#{quote}"
355
- @options[:html] ? @coder.encode(res) : res
396
+ res = @options[:html] ? %(<code class="grammar-literal">#{@coder.encode(string)}</code>) : string
397
+ res = "#{quote}#{res}#{quote}"
356
398
  end
357
399
 
358
400
  def escape_ebnf_hex(u)
359
401
  fmt = case u.ord
360
- when 0x00..0x20 then "#x%02X"
361
402
  when 0x0000..0x00ff then "#x%02X"
362
403
  when 0x0100..0xffff then "#x%04X"
363
404
  else "#x%08X"
364
405
  end
365
406
  char = fmt % u.ord
366
407
  if @options[:html]
367
- char = if u.ord <= 0x20
368
- %(<abbr title="#{ASCII_ESCAPE_NAMES[u.ord]}">#{@coder.encode char}</abbr>)
369
- elsif u.ord == 0x22
370
- %(<abbr title="quot">>&quot;</abbr>)
371
- elsif u.ord < 0x7F
372
- %(<abbr title="ascii '#{@coder.encode u}'">#{@coder.encode char}</abbr>)
373
- elsif u.ord == 0x7F
374
- %(<abbr title="delete">#{@coder.encode char}</abbr>)
375
- elsif u.ord <= 0xFF
376
- %(<abbr title="extended ascii '#{@coder.encode char}'">#{char}</abbr>)
377
- elsif (%w(Control Private-use Surrogate Noncharacter Reserved) - ::Unicode::Types.of(u)).empty?
378
- %(<abbr title="unicode '#{u}'">#{char}</abbr>)
408
+ char = if UNICODE_ESCAPE_NAMES.include?(u.ord)
409
+ %(<abbr title="#{UNICODE_ESCAPE_NAMES[u.ord]}">#{char}</abbr>)
410
+ elsif ([::Unicode::Types.of(u)] - %w(Control Private-use Surrogate Noncharacter Reserved)).empty?
411
+ %(<abbr title="unicode '#{@coder.encode u}'">#{char}</abbr>)
379
412
  else
380
- %(<abbr title="unicode '#{::Unicode::Types.of(u).first}'">#{char}</abbr>)
413
+ uni_esc = "U+%04X" % u.ord
414
+ %(<abbr title="unicode #{uni_esc}">#{char}</abbr>)
381
415
  end
382
416
  %(<code class="grammar-char-escape">#{char}</code>)
383
417
  else
@@ -558,18 +592,13 @@ module EBNF
558
592
  end
559
593
  char = "%x" + (fmt % u.ord).upcase
560
594
  if @options[:html]
561
- if u.ord <= 0x20
562
- char = %(<abbr title="#{ASCII_ESCAPE_NAMES[u.ord]}">#{@coder.encode char}</abbr>)
563
- elsif u.ord == 0x22
564
- %(<abbr title="quot">>&quot;</abbr>)
565
- elsif u.ord < 0x7F
566
- char = %(<abbr title="ascii '#{u}'">#{@coder.encode char}</abbr>)
567
- elsif u.ord == 0x7F
568
- char = %(<abbr title="delete">#{@coder.encode char}</abbr>)
569
- elsif u.ord <= 0xFF
570
- char = %(<abbr title="extended ascii '#{u}'">#{char}</abbr>)
595
+ char = if UNICODE_ESCAPE_NAMES.include?(u.ord)
596
+ %(<abbr title="#{UNICODE_ESCAPE_NAMES[u.ord]}">#{char}</abbr>)
597
+ elsif ([::Unicode::Types.of(u)] - %w(Control Private-use Surrogate Noncharacter Reserved)).empty?
598
+ %(<abbr title="unicode '#{@coder.encode u}'">#{char}</abbr>)
571
599
  else
572
- char = %(<abbr title="unicode '#{u.unicode_normaliz}'">#{char}</abbr>)
600
+ uni_esc = "U+%04X" % u.ord
601
+ %(<abbr title="unicode #{uni_esc}">#{char}</abbr>)
573
602
  end
574
603
  %(<code class="grammar-char-escape">#{char}</code>)
575
604
  else
@@ -708,17 +737,16 @@ module EBNF
708
737
  chars.length == 1 ? chars.last.inspect : chars.unshift(:alt)
709
738
  end
710
739
 
711
- ERB_DESC = %q(
712
- <!-- Generated with ebnf version #{EBNF::VERSION}. See https://github.com/dryruby/ebnf. -->
713
- <table class="grammar">
740
+ ERB_DESC = %(<!-- Generated with ebnf version #{EBNF::VERSION}. See https://github.com/dryruby/ebnf. -->\n) +
741
+ %q(<table class="grammar">
714
742
  <tbody id="grammar-productions" class="<%= @format %>">
715
743
  <% for rule in @rules %>
716
- <tr<%= %{ id="grammar-production-#{rule.sym}"} unless %w(=/ |).include?(rule.assign) || rule.sym.nil?%>>
744
+ <tr<%= %{ id="grammar-#{rule[:class]}-#{rule.sym}"} unless %w(=/ |).include?(rule.assign) || rule.sym.nil?%>>
717
745
  <% if rule.id %>
718
746
  <td<%= " colspan=2" unless rule.sym %>><%= rule.id %></td>
719
747
  <% end %>
720
748
  <% if rule.sym %>
721
- <td><code><%== rule.sym %></code></td>
749
+ <td><code><%== (rule.sym unless rule.class == :declaration) %></code></td>
722
750
  <% end %>
723
751
  <td><%= rule.assign %></td>
724
752
  <td><%= rule.formatted %></td>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ebnf
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.3
4
+ version: 2.3.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gregg Kellogg
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-06-02 00:00:00.000000000 Z
11
+ date: 2023-07-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sxp
@@ -300,7 +300,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
300
300
  - !ruby/object:Gem::Version
301
301
  version: '0'
302
302
  requirements: []
303
- rubygems_version: 3.4.6
303
+ rubygems_version: 3.4.13
304
304
  signing_key:
305
305
  specification_version: 4
306
306
  summary: EBNF parser and parser generator in Ruby.