ruby-vpi 16.0.1 → 17.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (247) hide show
  1. data/LICENSE +19 -19
  2. data/README +1 -1
  3. data/Rakefile +35 -32
  4. data/bin/convert.rb +28 -0
  5. data/bin/generate/design.rb +16 -0
  6. data/bin/generate/proto.rb +13 -0
  7. data/bin/generate/runner.rake +33 -0
  8. data/bin/generate/spec.rb +45 -0
  9. data/bin/generate.rb +177 -0
  10. data/bin/ruby-vpi +56 -0
  11. data/doc/Rakefile +20 -4
  12. data/doc/common.css +92 -33
  13. data/doc/common.inc +13 -0
  14. data/doc/common.tpl +42 -28
  15. data/doc/history.doc +11 -11
  16. data/doc/history.html +769 -248
  17. data/doc/history.inc +909 -0
  18. data/doc/history.rb +9 -0
  19. data/doc/history.yaml +69 -0
  20. data/doc/intro.inc +170 -178
  21. data/doc/lib/doc_format.rb +57 -144
  22. data/doc/lib/doc_proxy.rb +504 -88
  23. data/doc/lib/erb_content.rb +8 -8
  24. data/doc/lib/erb_proxy.rb +17 -17
  25. data/doc/manual.doc +626 -777
  26. data/doc/manual.html +1541 -1031
  27. data/doc/memo.doc +38 -36
  28. data/doc/memo.html +64 -28
  29. data/doc/readme.doc +4 -31
  30. data/doc/readme.html +221 -163
  31. data/doc/rss.erb +1 -1
  32. data/doc/rss.xml +73 -1761
  33. data/ext/Rakefile +6 -5
  34. data/ext/main.c +17 -15
  35. data/ext/relay.c +4 -7
  36. data/ext/relay.h +2 -2
  37. data/ext/swig_vpi.h +2 -2
  38. data/ext/swig_vpi.i +1 -2
  39. data/ext/swig_wrap.cin +12 -16
  40. data/ext/vlog.c +5 -5
  41. data/ext/vlog.h +2 -2
  42. data/lib/ruby-vpi/erb.rb +3 -3
  43. data/lib/ruby-vpi/float.rb +2 -2
  44. data/lib/ruby-vpi/rcov.rb +5 -7
  45. data/lib/ruby-vpi/runner.rb +43 -41
  46. data/lib/ruby-vpi/runner_boot_loader.rb +117 -0
  47. data/lib/ruby-vpi/runner_proxy.rb +6 -8
  48. data/lib/ruby-vpi/util.rb +10 -0
  49. data/lib/ruby-vpi/verilog_parser.rb +28 -56
  50. data/lib/ruby-vpi/vpi.rb +168 -123
  51. data/lib/ruby-vpi.rb +22 -143
  52. data/ref/c/annotated.html +1 -1
  53. data/ref/c/common_8h.html +1 -1
  54. data/ref/c/files.html +1 -1
  55. data/ref/c/functions.html +1 -1
  56. data/ref/c/functions_vars.html +1 -1
  57. data/ref/c/globals.html +1 -1
  58. data/ref/c/globals_0x63.html +1 -1
  59. data/ref/c/globals_0x65.html +1 -1
  60. data/ref/c/globals_0x66.html +1 -1
  61. data/ref/c/globals_0x6d.html +1 -1
  62. data/ref/c/globals_0x70.html +1 -1
  63. data/ref/c/globals_0x72.html +1 -1
  64. data/ref/c/globals_0x73.html +1 -1
  65. data/ref/c/globals_0x74.html +1 -1
  66. data/ref/c/globals_0x76.html +1 -1
  67. data/ref/c/globals_0x78.html +1 -1
  68. data/ref/c/globals_defs.html +1 -1
  69. data/ref/c/globals_defs_0x65.html +1 -1
  70. data/ref/c/globals_defs_0x70.html +1 -1
  71. data/ref/c/globals_defs_0x76.html +1 -1
  72. data/ref/c/globals_defs_0x78.html +1 -1
  73. data/ref/c/globals_enum.html +1 -1
  74. data/ref/c/globals_eval.html +1 -1
  75. data/ref/c/globals_func.html +1 -1
  76. data/ref/c/globals_type.html +1 -1
  77. data/ref/c/globals_vars.html +1 -1
  78. data/ref/c/index.html +1 -1
  79. data/ref/c/main_8c.html +1 -1
  80. data/ref/c/main_8h.html +1 -1
  81. data/ref/c/relay_8c.html +1 -1
  82. data/ref/c/relay_8h.html +1 -1
  83. data/ref/c/structt__cb__data.html +1 -1
  84. data/ref/c/structt__vpi__delay.html +1 -1
  85. data/ref/c/structt__vpi__error__info.html +1 -1
  86. data/ref/c/structt__vpi__strengthval.html +1 -1
  87. data/ref/c/structt__vpi__systf__data.html +1 -1
  88. data/ref/c/structt__vpi__time.html +1 -1
  89. data/ref/c/structt__vpi__value.html +1 -1
  90. data/ref/c/structt__vpi__vecval.html +1 -1
  91. data/ref/c/structt__vpi__vlog__info.html +1 -1
  92. data/ref/c/verilog_8h.html +1 -1
  93. data/ref/c/vlog_8c.html +1 -1
  94. data/ref/c/vlog_8h.html +1 -1
  95. data/ref/c/vpi__user_8h.html +1 -1
  96. data/ref/ruby/classes/ERB.html +5 -5
  97. data/ref/ruby/classes/ERB.src/{M000024.html → M000026.html} +0 -0
  98. data/ref/ruby/classes/FileUtils.html +11 -11
  99. data/ref/ruby/classes/FileUtils.src/{M000025.html → M000027.html} +0 -0
  100. data/ref/ruby/classes/FileUtils.src/{M000026.html → M000028.html} +0 -0
  101. data/ref/ruby/classes/Float.html +6 -6
  102. data/ref/ruby/classes/Float.src/{M000020.html → M000021.html} +0 -0
  103. data/ref/ruby/classes/Integer.html +65 -65
  104. data/ref/ruby/classes/Integer.src/M000009.html +12 -5
  105. data/ref/ruby/classes/Integer.src/M000010.html +5 -5
  106. data/ref/ruby/classes/Integer.src/M000011.html +5 -5
  107. data/ref/ruby/classes/Integer.src/M000012.html +5 -5
  108. data/ref/ruby/classes/Integer.src/M000013.html +5 -5
  109. data/ref/ruby/classes/Integer.src/M000014.html +18 -0
  110. data/ref/ruby/classes/Integer.src/M000017.html +12 -18
  111. data/ref/ruby/classes/Integer.src/M000018.html +18 -12
  112. data/ref/ruby/classes/Integer.src/M000019.html +12 -17
  113. data/ref/ruby/classes/Integer.src/M000020.html +30 -0
  114. data/ref/ruby/classes/RDoc.html +5 -5
  115. data/ref/ruby/classes/RDoc.src/{M000053.html → M000058.html} +0 -0
  116. data/ref/ruby/classes/{RubyVpi/Config.html → RubyVPI.html} +20 -6
  117. data/ref/ruby/classes/String.html +34 -15
  118. data/ref/ruby/classes/String.src/M000022.html +5 -28
  119. data/ref/ruby/classes/String.src/M000023.html +5 -5
  120. data/ref/ruby/classes/String.src/{M000021.html → M000024.html} +0 -0
  121. data/ref/ruby/classes/String.src/M000025.html +41 -0
  122. data/ref/ruby/classes/VerilogParser/Module/Port.html +16 -36
  123. data/ref/ruby/classes/VerilogParser/Module/Port.src/M000006.html +10 -5
  124. data/ref/ruby/classes/VerilogParser/Module/Port.src/{M000004.html → M000007.html} +4 -4
  125. data/ref/ruby/classes/VerilogParser/Module/Port.src/{M000005.html → M000008.html} +4 -4
  126. data/ref/ruby/classes/VerilogParser/Module.html +28 -9
  127. data/ref/ruby/classes/VerilogParser/Module.src/M000005.html +29 -0
  128. data/ref/ruby/classes/VerilogParser.html +5 -39
  129. data/ref/ruby/classes/VerilogParser.src/M000004.html +26 -0
  130. data/ref/ruby/classes/Vpi/Handle.html +179 -77
  131. data/ref/ruby/classes/Vpi/Handle.src/M000035.html +18 -0
  132. data/ref/ruby/classes/Vpi/Handle.src/M000036.html +5 -5
  133. data/ref/ruby/classes/Vpi/Handle.src/M000037.html +5 -5
  134. data/ref/ruby/classes/Vpi/Handle.src/M000038.html +5 -5
  135. data/ref/ruby/classes/Vpi/Handle.src/M000039.html +5 -5
  136. data/ref/ruby/classes/Vpi/Handle.src/M000040.html +5 -8
  137. data/ref/ruby/classes/Vpi/Handle.src/M000041.html +5 -8
  138. data/ref/ruby/classes/Vpi/Handle.src/M000042.html +5 -9
  139. data/ref/ruby/classes/Vpi/Handle.src/M000043.html +8 -31
  140. data/ref/ruby/classes/Vpi/Handle.src/M000044.html +8 -74
  141. data/ref/ruby/classes/Vpi/Handle.src/M000045.html +9 -17
  142. data/ref/ruby/classes/Vpi/Handle.src/M000046.html +31 -11
  143. data/ref/ruby/classes/Vpi/Handle.src/M000047.html +86 -0
  144. data/ref/ruby/classes/Vpi/Handle.src/M000048.html +17 -18
  145. data/ref/ruby/classes/Vpi/Handle.src/M000050.html +18 -0
  146. data/ref/ruby/classes/Vpi/Handle.src/M000051.html +24 -0
  147. data/ref/ruby/classes/Vpi/Handle.src/M000053.html +31 -0
  148. data/ref/ruby/classes/Vpi/Handle.src/M000054.html +89 -0
  149. data/ref/ruby/classes/Vpi/S_vpi_time.html +16 -16
  150. data/ref/ruby/classes/Vpi/S_vpi_time.src/{M000050.html → M000055.html} +4 -4
  151. data/ref/ruby/classes/Vpi/S_vpi_time.src/{M000051.html → M000056.html} +5 -5
  152. data/ref/ruby/classes/Vpi/S_vpi_value.html +15 -15
  153. data/ref/ruby/classes/Vpi/S_vpi_value.src/{M000035.html → M000032.html} +5 -5
  154. data/ref/ruby/classes/Vpi/S_vpi_value.src/M000033.html +5 -5
  155. data/ref/ruby/classes/Vpi/S_vpi_value.src/M000034.html +5 -5
  156. data/ref/ruby/classes/Vpi.html +6 -42
  157. data/ref/ruby/classes/Vpi.src/M000029.html +15 -5
  158. data/ref/ruby/classes/Vpi.src/M000030.html +24 -24
  159. data/ref/ruby/classes/Vpi.src/M000031.html +6 -8
  160. data/ref/ruby/created.rid +1 -1
  161. data/ref/ruby/files/bin/{header_to_ruby_rb.html → convert_rb.html} +5 -5
  162. data/ref/ruby/files/bin/{generate_test_rb.html → generate_rb.html} +8 -21
  163. data/ref/ruby/files/lib/ruby-vpi/erb_rb.html +1 -1
  164. data/ref/ruby/files/lib/ruby-vpi/float_rb.html +1 -1
  165. data/ref/ruby/files/lib/ruby-vpi/integer_rb.html +1 -1
  166. data/ref/ruby/files/lib/ruby-vpi/rake_rb.html +1 -1
  167. data/ref/ruby/files/lib/ruby-vpi/rcov_rb.html +1 -1
  168. data/ref/ruby/files/lib/ruby-vpi/rdoc_rb.html +1 -1
  169. data/ref/ruby/files/lib/ruby-vpi/runner_boot_loader_rb.html +197 -0
  170. data/ref/ruby/files/lib/ruby-vpi/runner_boot_loader_rb.src/M000001.html +17 -0
  171. data/ref/ruby/files/lib/ruby-vpi/runner_boot_loader_rb.src/M000002.html +18 -0
  172. data/ref/ruby/files/lib/ruby-vpi/runner_proxy_rb.html +1 -1
  173. data/ref/ruby/files/lib/ruby-vpi/runner_rb.html +6 -19
  174. data/ref/ruby/files/lib/ruby-vpi/util_rb.html +101 -0
  175. data/ref/ruby/files/lib/ruby-vpi/verilog_parser_rb.html +8 -1
  176. data/ref/ruby/files/lib/ruby-vpi/vpi_rb.html +1 -1
  177. data/ref/ruby/files/lib/ruby-vpi_rb.html +2 -14
  178. data/ref/ruby/fr_class_index.html +1 -3
  179. data/ref/ruby/fr_file_index.html +4 -2
  180. data/ref/ruby/fr_method_index.html +56 -51
  181. data/ref/ruby/index.html +1 -1
  182. data/samp/counter/RSpec/Rakefile +1 -0
  183. data/samp/counter/RSpec/counter_design.rb +15 -0
  184. data/samp/counter/RSpec/counter_proto.rb +10 -0
  185. data/samp/counter/RSpec/counter_runner.rake +44 -0
  186. data/samp/counter/RSpec/counter_spec.rb +39 -0
  187. data/samp/counter/Rakefile +1 -1
  188. data/samp/counter/counter.v +7 -7
  189. data/samp/counter/xUnit/Rakefile +1 -0
  190. data/samp/counter/xUnit/counter_bench.rb +95 -0
  191. data/samp/counter/{counter_xunit_bench.v → xUnit/counter_bench.v} +0 -0
  192. data/samp/counter/xUnit/counter_design.rb +15 -0
  193. data/samp/counter/xUnit/counter_proto.rb +10 -0
  194. data/samp/counter/xUnit/counter_runner.rake +44 -0
  195. data/samp/counter/{counter_xunit_spec.rb → xUnit/counter_spec.rb} +9 -9
  196. data/samp/pipelined_alu/Rakefile +1 -1
  197. data/samp/pipelined_alu/TestHw5UnitModel.rb +4 -5
  198. data/samp/pipelined_alu/hw5_unit.v +55 -85
  199. data/samp/pipelined_alu/hw5_unit_design.rb +51 -0
  200. data/samp/pipelined_alu/hw5_unit_proto.rb +4 -0
  201. data/samp/pipelined_alu/hw5_unit_runner.rake +43 -0
  202. data/samp/pipelined_alu/hw5_unit_spec.rb +64 -0
  203. data/samp/register_file/LICENSE +20 -0
  204. data/samp/register_file/README +4 -0
  205. data/samp/register_file/Rakefile +1 -0
  206. data/samp/register_file/register_file.v +18 -0
  207. data/samp/register_file/register_file_design.rb +11 -0
  208. data/samp/register_file/register_file_proto.rb +11 -0
  209. data/samp/register_file/register_file_runner.rake +43 -0
  210. data/samp/register_file/register_file_spec.rb +58 -0
  211. metadata +78 -66
  212. data/bin/generate_test.rb +0 -200
  213. data/bin/generate_test_tpl/bench.rb +0 -89
  214. data/bin/generate_test_tpl/bench.v +0 -26
  215. data/bin/generate_test_tpl/design.rb +0 -11
  216. data/bin/generate_test_tpl/proto.rb +0 -16
  217. data/bin/generate_test_tpl/runner.rake +0 -42
  218. data/bin/generate_test_tpl/spec.rb +0 -37
  219. data/bin/header_to_ruby.rb +0 -27
  220. data/ref/ruby/classes/Integer.src/M000008.html +0 -25
  221. data/ref/ruby/classes/Integer.src/M000016.html +0 -25
  222. data/ref/ruby/classes/RubyVpi.html +0 -199
  223. data/ref/ruby/classes/RubyVpi.src/M000027.html +0 -121
  224. data/ref/ruby/classes/VerilogParser/Module/Parameter.html +0 -160
  225. data/ref/ruby/classes/VerilogParser/Module/Parameter.src/M000007.html +0 -19
  226. data/ref/ruby/classes/VerilogParser/Module/Port.src/M000003.html +0 -21
  227. data/ref/ruby/classes/VerilogParser/Module.src/M000002.html +0 -34
  228. data/ref/ruby/classes/VerilogParser.src/M000001.html +0 -34
  229. data/ref/ruby/classes/Vpi/Handle.src/M000049.html +0 -69
  230. data/ref/ruby/classes/Vpi.src/M000028.html +0 -28
  231. data/ref/ruby/classes/Vpi.src/M000032.html +0 -22
  232. data/samp/counter/counter_rspec_bench.rb +0 -86
  233. data/samp/counter/counter_rspec_bench.v +0 -9
  234. data/samp/counter/counter_rspec_design.rb +0 -8
  235. data/samp/counter/counter_rspec_proto.rb +0 -13
  236. data/samp/counter/counter_rspec_runner.rake +0 -52
  237. data/samp/counter/counter_rspec_spec.rb +0 -39
  238. data/samp/counter/counter_xunit_bench.rb +0 -86
  239. data/samp/counter/counter_xunit_design.rb +0 -8
  240. data/samp/counter/counter_xunit_proto.rb +0 -13
  241. data/samp/counter/counter_xunit_runner.rake +0 -52
  242. data/samp/pipelined_alu/hw5_unit_test_bench.rb +0 -86
  243. data/samp/pipelined_alu/hw5_unit_test_bench.v +0 -14
  244. data/samp/pipelined_alu/hw5_unit_test_design.rb +0 -61
  245. data/samp/pipelined_alu/hw5_unit_test_proto.rb +0 -7
  246. data/samp/pipelined_alu/hw5_unit_test_runner.rake +0 -52
  247. data/samp/pipelined_alu/hw5_unit_test_spec.rb +0 -68
@@ -3,33 +3,60 @@
3
3
  # See the file named LICENSE for details.
4
4
 
5
5
  require 'cgi'
6
- require 'rubygems'
6
+ require 'digest/md5'
7
+
8
+ begin
9
+ require 'rubygems'
10
+ rescue LoadError
11
+ end
12
+
7
13
  require 'coderay'
8
14
  require 'redcloth'
9
15
 
10
16
  class String
11
- # The content of these HTML tags will be preserved verbatim when they are
12
- # processed by Textile.
13
- PRESERVED_TAGS = [:code, :tt]
17
+ # The content of these HTML tags will be preserved verbatim
18
+ # when they are processed by Textile. By doing this, we
19
+ # avoid unwanted Textile transformations, such as quotation
20
+ # marks becoming curly ( ), in source code.
21
+ PRESERVED_TAGS = %w[tt code pre]
14
22
 
15
23
  # Transforms this string into HTML.
16
24
  def to_html
17
25
  text = dup
18
26
 
19
- # prevent the content of these tags from being transformed by Textile.
20
- # for example, Textile transforms quotation marks in code into curly ones
21
- # ( ) -- this ruins any source code in the content of the tags!
22
- PRESERVED_TAGS.each do |tag|
23
- text.gsub! \
24
- %r{<#{tag}(.*?)>(.*?)</#{tag}>}m,
25
- %{<pre tag=#{tag.inspect}\\1>\\2</pre>}
27
+ # escape preserved tags
28
+ preserved = {} # escaped => original
29
+
30
+ PRESERVED_TAGS.each do |tag|
31
+ text.gsub! %r{(<#{tag}.*?>)(.*?)(</#{tag}>)}m do
32
+ orig = $1 + CGI.escapeHTML(CGI.unescapeHTML($2)) + $3
33
+ esc = Digest::MD5.hexdigest(orig)
34
+
35
+ preserved[esc] = orig
36
+ esc
26
37
  end
38
+ end
39
+
27
40
 
41
+ # convert Textile into HTML
28
42
  html = text.redcloth
29
43
 
30
- # redcloth wraps a single item within paragraph tags, which prevents the
31
- # item's HTML from being validly injected within other block-level
32
- # elements, such as headings (h1, h2, etc.)
44
+
45
+ # restore preserved tags
46
+ preserved.each_pair do |esc, orig|
47
+ html.gsub! %r{<p>#{esc}</p>|#{esc}}, orig
48
+ end
49
+
50
+
51
+ ## fix annoyances in Textile conversion
52
+
53
+ # redcloth wraps indented text within <pre> tags
54
+ html.gsub! %r{(<pre>)\s*<code>(.*?)\s*</code>\s*(</pre>)}m, '\1\2\3'
55
+ html.gsub! %r{(<pre>)\s*<pre>(.*?)</pre>\s*(</pre>)}m, '\1\2\3'
56
+
57
+ # redcloth wraps a single item within paragraph tags, which
58
+ # prevents the item's HTML from being validly injected within
59
+ # other block-level elements, such as headings (h1, h2, etc.)
33
60
  html.sub! %r{^<p>(.*)</p>$}m do |match|
34
61
  payload = $1
35
62
 
@@ -40,26 +67,9 @@ class String
40
67
  end
41
68
  end
42
69
 
43
- # restore the original tags for the preserved tags
44
- # unescape content of <pre> tags because they may contain nested
45
- # preserved tags (redcloth escapes the content of <pre> tags)
46
- html.gsub! %r{(<pre>)(.*?)(</pre>)}m do
47
- $1 + CGI.unescapeHTML($2) + $3
48
- end
49
-
50
- PRESERVED_TAGS.each do |tag|
51
- html.gsub! \
52
- %r{<pre tag=#{tag.inspect}(.*?)>(.*?)</pre>}m,
53
- %{<#{tag}\\1>\\2</#{tag}>}
54
- end
70
+ # redcloth adds <span> tags around acronyms
71
+ html.gsub! %r{<span class="caps">([[:upper:][:digit:]]+)</span>}, '\1'
55
72
 
56
- # assume that indented text in Textile is NOT source code
57
- html.gsub! %r{(<pre>)\s*<code>(.*?)\s*</code>\s*(</pre>)}m, '\1\2\3'
58
-
59
- # escape content of <pre> tags, because we un-escaped it above
60
- html.gsub! %r{(<pre>)(.*?)(</pre>)}m do
61
- $1 + CGI.escapeHTML($2) + $3
62
- end
63
73
 
64
74
  html.coderay
65
75
  end
@@ -98,121 +108,24 @@ class String
98
108
  end
99
109
  end
100
110
 
101
-
102
111
  # Transforms this string into a valid XHTML anchor (ID attribute).
103
112
  # See http://www.nmt.edu/tcc/help/pubs/xhtml/id-type.html
104
113
  def to_html_anchor
105
- # The first or only character must be a letter.
106
- buf =
107
- if self[0,1] =~ /[[:alpha:]]/
108
- self
109
- else
110
- 'a' + self
111
- end
112
-
113
- # The remaining characters must be letters, digits, hyphens (-),
114
- # underscores (_), colons (:), or periods (.) [or Unicode characters]
115
- buf.unpack('U*').map! do |code|
116
- if code > 0xFF or code.chr =~ /[[:alnum:]\-_:\.]/
117
- code
118
- else
119
- ?_
120
- end
121
- end.pack('U*')
122
- end
123
-
124
- @@anchors = []
125
-
126
- # Resets the list of anchors encountered thus far.
127
- def String.reset_anchors
128
- @@anchors.clear
129
- end
114
+ # remove HTML tags from the input
115
+ buf = self.gsub(/<.*?>/, '')
130
116
 
131
- # Builds a table of contents from XHTML headings (<h1>, <h2>, etc.) found
132
- # in this string and returns an array containing [toc, text] where:
133
- #
134
- # toc:: the generated table of contents
135
- #
136
- # text:: a modified version of this string which contains anchors for the
137
- # hyperlinks in the table of contents (so that the TOC can link to
138
- # the content in this string)
139
- #
140
- # If a block is given, it will be invoked every time a heading is found, with
141
- # information about the found heading.
142
- #
143
- def table_of_contents
144
- toc = '<ul>'
145
- prevDepth = 0
146
- prevIndex = ''
147
-
148
- text = gsub %r{<h(\d)(.*?)>(.*?)</h\1>$}m do
149
- depth, atts, title = $1.to_i, $2, $3.strip
150
-
151
- # generate a LaTeX-style index (section number) for the heading
152
- depthDiff = (depth - prevDepth).abs
153
-
154
- index =
155
- if depth > prevDepth
156
- toc << '<li><ul>' * depthDiff
157
-
158
- s = prevIndex + ('.1' * depthDiff)
159
- s.sub(/^\./, '')
160
-
161
- elsif depth < prevDepth
162
- toc << '</ul></li>' * depthDiff
163
-
164
- s = prevIndex.sub(/(\.\d+){#{depthDiff}}$/, '')
165
- s.next
166
-
167
- else
168
- prevIndex.next
169
-
170
- end
171
-
172
- prevDepth = depth
173
- prevIndex = index
174
-
175
- # generate a unique HTML anchor for the heading
176
- anchor = CGI.unescape(
177
- if atts =~ /id=('|")(.*?)\1/
178
- atts = $` + $'
179
- $2
180
- else
181
- title
182
- end
183
- ).to_html_anchor
184
-
185
- anchor << anchor.object_id.to_s while @@anchors.include? anchor
186
- @@anchors << anchor
187
-
188
- yield title, anchor, index, depth, atts if block_given?
189
-
190
- # provide hyperlinks for traveling between TOC and heading
191
- dst = anchor
192
- src = dst.object_id.to_s.to_html_anchor
193
-
194
- # forward link from TOC to heading
195
- toc << %{<li><a id="#{src}" href="##{dst}">#{title}</a></li>}
196
-
197
- # reverse link from heading to TOC
198
- %{<h#{depth}#{atts}><a id="#{dst}" href="##{src}">#{index}</a> &nbsp; #{title}</h#{depth}>}
199
- end
200
-
201
- if prevIndex.empty?
202
- toc = nil # there were no headings
203
- else
204
- toc << '</ul></li>' * prevDepth
205
- toc << '</ul>'
206
-
207
- # collapse redundant list elements
208
- while toc.gsub! %r{(<li>.*?)</li><li>(<ul>)}, '\1\2'
209
- end
210
-
211
- # collapse unnecessary levels
212
- while toc.gsub! %r{(<ul>)<li><ul>(.*)</ul></li>(</ul>)}, '\1\2\3'
117
+ # The first or only character must be a letter.
118
+ buf.insert(0, 'a') unless buf[0,1] =~ /[[:alpha:]]/
119
+
120
+ # The remaining characters must be letters,
121
+ # digits, hyphens (-), underscores (_), colons
122
+ # (:), or periods (.) [or Unicode characters]
123
+ buf.unpack('U*').map! do |code|
124
+ if code > 0xFF or code.chr =~ /[[:alnum:]\-_:\.]/
125
+ code
126
+ else
127
+ ?_
213
128
  end
214
- end
215
-
216
- [toc, text]
129
+ end.pack('U*')
217
130
  end
218
131
  end