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.
- data/LICENSE +19 -19
- data/README +1 -1
- data/Rakefile +35 -32
- data/bin/convert.rb +28 -0
- data/bin/generate/design.rb +16 -0
- data/bin/generate/proto.rb +13 -0
- data/bin/generate/runner.rake +33 -0
- data/bin/generate/spec.rb +45 -0
- data/bin/generate.rb +177 -0
- data/bin/ruby-vpi +56 -0
- data/doc/Rakefile +20 -4
- data/doc/common.css +92 -33
- data/doc/common.inc +13 -0
- data/doc/common.tpl +42 -28
- data/doc/history.doc +11 -11
- data/doc/history.html +769 -248
- data/doc/history.inc +909 -0
- data/doc/history.rb +9 -0
- data/doc/history.yaml +69 -0
- data/doc/intro.inc +170 -178
- data/doc/lib/doc_format.rb +57 -144
- data/doc/lib/doc_proxy.rb +504 -88
- data/doc/lib/erb_content.rb +8 -8
- data/doc/lib/erb_proxy.rb +17 -17
- data/doc/manual.doc +626 -777
- data/doc/manual.html +1541 -1031
- data/doc/memo.doc +38 -36
- data/doc/memo.html +64 -28
- data/doc/readme.doc +4 -31
- data/doc/readme.html +221 -163
- data/doc/rss.erb +1 -1
- data/doc/rss.xml +73 -1761
- data/ext/Rakefile +6 -5
- data/ext/main.c +17 -15
- data/ext/relay.c +4 -7
- data/ext/relay.h +2 -2
- data/ext/swig_vpi.h +2 -2
- data/ext/swig_vpi.i +1 -2
- data/ext/swig_wrap.cin +12 -16
- data/ext/vlog.c +5 -5
- data/ext/vlog.h +2 -2
- data/lib/ruby-vpi/erb.rb +3 -3
- data/lib/ruby-vpi/float.rb +2 -2
- data/lib/ruby-vpi/rcov.rb +5 -7
- data/lib/ruby-vpi/runner.rb +43 -41
- data/lib/ruby-vpi/runner_boot_loader.rb +117 -0
- data/lib/ruby-vpi/runner_proxy.rb +6 -8
- data/lib/ruby-vpi/util.rb +10 -0
- data/lib/ruby-vpi/verilog_parser.rb +28 -56
- data/lib/ruby-vpi/vpi.rb +168 -123
- data/lib/ruby-vpi.rb +22 -143
- data/ref/c/annotated.html +1 -1
- data/ref/c/common_8h.html +1 -1
- data/ref/c/files.html +1 -1
- data/ref/c/functions.html +1 -1
- data/ref/c/functions_vars.html +1 -1
- data/ref/c/globals.html +1 -1
- data/ref/c/globals_0x63.html +1 -1
- data/ref/c/globals_0x65.html +1 -1
- data/ref/c/globals_0x66.html +1 -1
- data/ref/c/globals_0x6d.html +1 -1
- data/ref/c/globals_0x70.html +1 -1
- data/ref/c/globals_0x72.html +1 -1
- data/ref/c/globals_0x73.html +1 -1
- data/ref/c/globals_0x74.html +1 -1
- data/ref/c/globals_0x76.html +1 -1
- data/ref/c/globals_0x78.html +1 -1
- data/ref/c/globals_defs.html +1 -1
- data/ref/c/globals_defs_0x65.html +1 -1
- data/ref/c/globals_defs_0x70.html +1 -1
- data/ref/c/globals_defs_0x76.html +1 -1
- data/ref/c/globals_defs_0x78.html +1 -1
- data/ref/c/globals_enum.html +1 -1
- data/ref/c/globals_eval.html +1 -1
- data/ref/c/globals_func.html +1 -1
- data/ref/c/globals_type.html +1 -1
- data/ref/c/globals_vars.html +1 -1
- data/ref/c/index.html +1 -1
- data/ref/c/main_8c.html +1 -1
- data/ref/c/main_8h.html +1 -1
- data/ref/c/relay_8c.html +1 -1
- data/ref/c/relay_8h.html +1 -1
- data/ref/c/structt__cb__data.html +1 -1
- data/ref/c/structt__vpi__delay.html +1 -1
- data/ref/c/structt__vpi__error__info.html +1 -1
- data/ref/c/structt__vpi__strengthval.html +1 -1
- data/ref/c/structt__vpi__systf__data.html +1 -1
- data/ref/c/structt__vpi__time.html +1 -1
- data/ref/c/structt__vpi__value.html +1 -1
- data/ref/c/structt__vpi__vecval.html +1 -1
- data/ref/c/structt__vpi__vlog__info.html +1 -1
- data/ref/c/verilog_8h.html +1 -1
- data/ref/c/vlog_8c.html +1 -1
- data/ref/c/vlog_8h.html +1 -1
- data/ref/c/vpi__user_8h.html +1 -1
- data/ref/ruby/classes/ERB.html +5 -5
- data/ref/ruby/classes/ERB.src/{M000024.html → M000026.html} +0 -0
- data/ref/ruby/classes/FileUtils.html +11 -11
- data/ref/ruby/classes/FileUtils.src/{M000025.html → M000027.html} +0 -0
- data/ref/ruby/classes/FileUtils.src/{M000026.html → M000028.html} +0 -0
- data/ref/ruby/classes/Float.html +6 -6
- data/ref/ruby/classes/Float.src/{M000020.html → M000021.html} +0 -0
- data/ref/ruby/classes/Integer.html +65 -65
- data/ref/ruby/classes/Integer.src/M000009.html +12 -5
- data/ref/ruby/classes/Integer.src/M000010.html +5 -5
- data/ref/ruby/classes/Integer.src/M000011.html +5 -5
- data/ref/ruby/classes/Integer.src/M000012.html +5 -5
- data/ref/ruby/classes/Integer.src/M000013.html +5 -5
- data/ref/ruby/classes/Integer.src/M000014.html +18 -0
- data/ref/ruby/classes/Integer.src/M000017.html +12 -18
- data/ref/ruby/classes/Integer.src/M000018.html +18 -12
- data/ref/ruby/classes/Integer.src/M000019.html +12 -17
- data/ref/ruby/classes/Integer.src/M000020.html +30 -0
- data/ref/ruby/classes/RDoc.html +5 -5
- data/ref/ruby/classes/RDoc.src/{M000053.html → M000058.html} +0 -0
- data/ref/ruby/classes/{RubyVpi/Config.html → RubyVPI.html} +20 -6
- data/ref/ruby/classes/String.html +34 -15
- data/ref/ruby/classes/String.src/M000022.html +5 -28
- data/ref/ruby/classes/String.src/M000023.html +5 -5
- data/ref/ruby/classes/String.src/{M000021.html → M000024.html} +0 -0
- data/ref/ruby/classes/String.src/M000025.html +41 -0
- data/ref/ruby/classes/VerilogParser/Module/Port.html +16 -36
- data/ref/ruby/classes/VerilogParser/Module/Port.src/M000006.html +10 -5
- data/ref/ruby/classes/VerilogParser/Module/Port.src/{M000004.html → M000007.html} +4 -4
- data/ref/ruby/classes/VerilogParser/Module/Port.src/{M000005.html → M000008.html} +4 -4
- data/ref/ruby/classes/VerilogParser/Module.html +28 -9
- data/ref/ruby/classes/VerilogParser/Module.src/M000005.html +29 -0
- data/ref/ruby/classes/VerilogParser.html +5 -39
- data/ref/ruby/classes/VerilogParser.src/M000004.html +26 -0
- data/ref/ruby/classes/Vpi/Handle.html +179 -77
- data/ref/ruby/classes/Vpi/Handle.src/M000035.html +18 -0
- data/ref/ruby/classes/Vpi/Handle.src/M000036.html +5 -5
- data/ref/ruby/classes/Vpi/Handle.src/M000037.html +5 -5
- data/ref/ruby/classes/Vpi/Handle.src/M000038.html +5 -5
- data/ref/ruby/classes/Vpi/Handle.src/M000039.html +5 -5
- data/ref/ruby/classes/Vpi/Handle.src/M000040.html +5 -8
- data/ref/ruby/classes/Vpi/Handle.src/M000041.html +5 -8
- data/ref/ruby/classes/Vpi/Handle.src/M000042.html +5 -9
- data/ref/ruby/classes/Vpi/Handle.src/M000043.html +8 -31
- data/ref/ruby/classes/Vpi/Handle.src/M000044.html +8 -74
- data/ref/ruby/classes/Vpi/Handle.src/M000045.html +9 -17
- data/ref/ruby/classes/Vpi/Handle.src/M000046.html +31 -11
- data/ref/ruby/classes/Vpi/Handle.src/M000047.html +86 -0
- data/ref/ruby/classes/Vpi/Handle.src/M000048.html +17 -18
- data/ref/ruby/classes/Vpi/Handle.src/M000050.html +18 -0
- data/ref/ruby/classes/Vpi/Handle.src/M000051.html +24 -0
- data/ref/ruby/classes/Vpi/Handle.src/M000053.html +31 -0
- data/ref/ruby/classes/Vpi/Handle.src/M000054.html +89 -0
- data/ref/ruby/classes/Vpi/S_vpi_time.html +16 -16
- data/ref/ruby/classes/Vpi/S_vpi_time.src/{M000050.html → M000055.html} +4 -4
- data/ref/ruby/classes/Vpi/S_vpi_time.src/{M000051.html → M000056.html} +5 -5
- data/ref/ruby/classes/Vpi/S_vpi_value.html +15 -15
- data/ref/ruby/classes/Vpi/S_vpi_value.src/{M000035.html → M000032.html} +5 -5
- data/ref/ruby/classes/Vpi/S_vpi_value.src/M000033.html +5 -5
- data/ref/ruby/classes/Vpi/S_vpi_value.src/M000034.html +5 -5
- data/ref/ruby/classes/Vpi.html +6 -42
- data/ref/ruby/classes/Vpi.src/M000029.html +15 -5
- data/ref/ruby/classes/Vpi.src/M000030.html +24 -24
- data/ref/ruby/classes/Vpi.src/M000031.html +6 -8
- data/ref/ruby/created.rid +1 -1
- data/ref/ruby/files/bin/{header_to_ruby_rb.html → convert_rb.html} +5 -5
- data/ref/ruby/files/bin/{generate_test_rb.html → generate_rb.html} +8 -21
- data/ref/ruby/files/lib/ruby-vpi/erb_rb.html +1 -1
- data/ref/ruby/files/lib/ruby-vpi/float_rb.html +1 -1
- data/ref/ruby/files/lib/ruby-vpi/integer_rb.html +1 -1
- data/ref/ruby/files/lib/ruby-vpi/rake_rb.html +1 -1
- data/ref/ruby/files/lib/ruby-vpi/rcov_rb.html +1 -1
- data/ref/ruby/files/lib/ruby-vpi/rdoc_rb.html +1 -1
- data/ref/ruby/files/lib/ruby-vpi/runner_boot_loader_rb.html +197 -0
- data/ref/ruby/files/lib/ruby-vpi/runner_boot_loader_rb.src/M000001.html +17 -0
- data/ref/ruby/files/lib/ruby-vpi/runner_boot_loader_rb.src/M000002.html +18 -0
- data/ref/ruby/files/lib/ruby-vpi/runner_proxy_rb.html +1 -1
- data/ref/ruby/files/lib/ruby-vpi/runner_rb.html +6 -19
- data/ref/ruby/files/lib/ruby-vpi/util_rb.html +101 -0
- data/ref/ruby/files/lib/ruby-vpi/verilog_parser_rb.html +8 -1
- data/ref/ruby/files/lib/ruby-vpi/vpi_rb.html +1 -1
- data/ref/ruby/files/lib/ruby-vpi_rb.html +2 -14
- data/ref/ruby/fr_class_index.html +1 -3
- data/ref/ruby/fr_file_index.html +4 -2
- data/ref/ruby/fr_method_index.html +56 -51
- data/ref/ruby/index.html +1 -1
- data/samp/counter/RSpec/Rakefile +1 -0
- data/samp/counter/RSpec/counter_design.rb +15 -0
- data/samp/counter/RSpec/counter_proto.rb +10 -0
- data/samp/counter/RSpec/counter_runner.rake +44 -0
- data/samp/counter/RSpec/counter_spec.rb +39 -0
- data/samp/counter/Rakefile +1 -1
- data/samp/counter/counter.v +7 -7
- data/samp/counter/xUnit/Rakefile +1 -0
- data/samp/counter/xUnit/counter_bench.rb +95 -0
- data/samp/counter/{counter_xunit_bench.v → xUnit/counter_bench.v} +0 -0
- data/samp/counter/xUnit/counter_design.rb +15 -0
- data/samp/counter/xUnit/counter_proto.rb +10 -0
- data/samp/counter/xUnit/counter_runner.rake +44 -0
- data/samp/counter/{counter_xunit_spec.rb → xUnit/counter_spec.rb} +9 -9
- data/samp/pipelined_alu/Rakefile +1 -1
- data/samp/pipelined_alu/TestHw5UnitModel.rb +4 -5
- data/samp/pipelined_alu/hw5_unit.v +55 -85
- data/samp/pipelined_alu/hw5_unit_design.rb +51 -0
- data/samp/pipelined_alu/hw5_unit_proto.rb +4 -0
- data/samp/pipelined_alu/hw5_unit_runner.rake +43 -0
- data/samp/pipelined_alu/hw5_unit_spec.rb +64 -0
- data/samp/register_file/LICENSE +20 -0
- data/samp/register_file/README +4 -0
- data/samp/register_file/Rakefile +1 -0
- data/samp/register_file/register_file.v +18 -0
- data/samp/register_file/register_file_design.rb +11 -0
- data/samp/register_file/register_file_proto.rb +11 -0
- data/samp/register_file/register_file_runner.rake +43 -0
- data/samp/register_file/register_file_spec.rb +58 -0
- metadata +78 -66
- data/bin/generate_test.rb +0 -200
- data/bin/generate_test_tpl/bench.rb +0 -89
- data/bin/generate_test_tpl/bench.v +0 -26
- data/bin/generate_test_tpl/design.rb +0 -11
- data/bin/generate_test_tpl/proto.rb +0 -16
- data/bin/generate_test_tpl/runner.rake +0 -42
- data/bin/generate_test_tpl/spec.rb +0 -37
- data/bin/header_to_ruby.rb +0 -27
- data/ref/ruby/classes/Integer.src/M000008.html +0 -25
- data/ref/ruby/classes/Integer.src/M000016.html +0 -25
- data/ref/ruby/classes/RubyVpi.html +0 -199
- data/ref/ruby/classes/RubyVpi.src/M000027.html +0 -121
- data/ref/ruby/classes/VerilogParser/Module/Parameter.html +0 -160
- data/ref/ruby/classes/VerilogParser/Module/Parameter.src/M000007.html +0 -19
- data/ref/ruby/classes/VerilogParser/Module/Port.src/M000003.html +0 -21
- data/ref/ruby/classes/VerilogParser/Module.src/M000002.html +0 -34
- data/ref/ruby/classes/VerilogParser.src/M000001.html +0 -34
- data/ref/ruby/classes/Vpi/Handle.src/M000049.html +0 -69
- data/ref/ruby/classes/Vpi.src/M000028.html +0 -28
- data/ref/ruby/classes/Vpi.src/M000032.html +0 -22
- data/samp/counter/counter_rspec_bench.rb +0 -86
- data/samp/counter/counter_rspec_bench.v +0 -9
- data/samp/counter/counter_rspec_design.rb +0 -8
- data/samp/counter/counter_rspec_proto.rb +0 -13
- data/samp/counter/counter_rspec_runner.rake +0 -52
- data/samp/counter/counter_rspec_spec.rb +0 -39
- data/samp/counter/counter_xunit_bench.rb +0 -86
- data/samp/counter/counter_xunit_design.rb +0 -8
- data/samp/counter/counter_xunit_proto.rb +0 -13
- data/samp/counter/counter_xunit_runner.rake +0 -52
- data/samp/pipelined_alu/hw5_unit_test_bench.rb +0 -86
- data/samp/pipelined_alu/hw5_unit_test_bench.v +0 -14
- data/samp/pipelined_alu/hw5_unit_test_design.rb +0 -61
- data/samp/pipelined_alu/hw5_unit_test_proto.rb +0 -7
- data/samp/pipelined_alu/hw5_unit_test_runner.rake +0 -52
- data/samp/pipelined_alu/hw5_unit_test_spec.rb +0 -68
data/doc/lib/doc_proxy.rb
CHANGED
@@ -2,145 +2,561 @@
|
|
2
2
|
# Copyright 2006 Suraj N. Kurapati
|
3
3
|
# See the file named LICENSE for details.
|
4
4
|
|
5
|
+
$: << File.basename(__FILE__)
|
5
6
|
require 'erb_proxy'
|
6
7
|
require 'doc_format'
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
require 'digest/md5'
|
10
|
+
require 'ostruct'
|
11
|
+
require 'pp'
|
12
|
+
|
13
|
+
class String
|
14
|
+
def digest
|
15
|
+
Digest::MD5.hexdigest self
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Processes ERB templates to produce documentation.
|
20
|
+
# Templates may contain "<xref...>" tags where the ...
|
21
|
+
# represents the target anchor of the cross-reference.
|
11
22
|
class DocProxy < ErbProxy
|
12
|
-
|
13
|
-
|
14
|
-
|
23
|
+
Box = Struct.new(:type, :anchor, :index, :title, :id)
|
24
|
+
BibItem = Struct.new(:anchor, :name)
|
25
|
+
FootNote = Struct.new(:anchor, :name)
|
15
26
|
|
16
|
-
|
27
|
+
GROUP2TYPES = {
|
17
28
|
:admonition => [:tip, :note, :important, :caution, :warning],
|
18
29
|
|
19
|
-
#
|
30
|
+
# see http://www.sagehill.net/docbookxsl/FormalTitles.html
|
20
31
|
:formal => [:figure, :table, :example, :equation, :procedure],
|
32
|
+
|
33
|
+
:latex => [:part, :chapter, :section, :paragraph],
|
21
34
|
}
|
22
35
|
|
23
|
-
attr_reader :
|
36
|
+
attr_reader :nodeTree, :references
|
24
37
|
|
25
38
|
def initialize
|
26
39
|
super
|
27
40
|
|
28
|
-
@
|
29
|
-
@
|
30
|
-
@
|
41
|
+
@boxCipher = Cipher.new
|
42
|
+
@references = []
|
43
|
+
@boxes = Hash.new {|h,k| h[k] = []}
|
44
|
+
@lazyHandlers = {}
|
31
45
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
46
|
+
|
47
|
+
# node hierarcy
|
48
|
+
|
49
|
+
@nodeTree = NodeTree.new
|
50
|
+
|
51
|
+
GROUP2TYPES.each_pair do |group, types|
|
52
|
+
next if group == :latex
|
53
|
+
|
54
|
+
types.each do |type|
|
55
|
+
add_node_handler group, type do |node, content, *args|
|
56
|
+
%{
|
57
|
+
<hr style="display: none"/>
|
58
|
+
|
59
|
+
<div class="#{group}">
|
60
|
+
<div class="#{type}" id="#{node.anchor}">
|
61
|
+
#{
|
62
|
+
if group == :admonition
|
63
|
+
%{<img src="images/tango/#{type}.png" alt="#{type}" class="icon"/>}
|
64
|
+
end
|
65
|
+
}
|
66
|
+
|
67
|
+
<p class="title"><a href="##{node.tocAnchor}">#{type.to_s.capitalize} #{node.number}</a>. #{node.title.to_html}</p>
|
68
|
+
|
69
|
+
#{content.to_html}
|
70
|
+
</div>
|
71
|
+
</div>
|
72
|
+
}
|
73
|
+
end
|
39
74
|
end
|
40
75
|
end
|
41
76
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
77
|
+
add_node_handler :latex, :front_cover do |node, content, *args|
|
78
|
+
%{
|
79
|
+
<hr style="display: none"/>
|
80
|
+
|
81
|
+
<div id="#{node.anchor}" class="front_cover">
|
82
|
+
<h1 class="title"><big>#{node.title.to_html}</big></h1>
|
83
|
+
|
84
|
+
#{content.to_html}
|
85
|
+
|
86
|
+
</div>
|
87
|
+
}
|
88
|
+
end
|
89
|
+
|
90
|
+
add_node_handler :latex, :part do |node, content, *args|
|
91
|
+
%{
|
92
|
+
<hr style="display: none"/>
|
93
|
+
|
94
|
+
<div id="#{node.anchor}" class="part">
|
95
|
+
<h1 class="title">
|
96
|
+
Part <a href="##{node.tocAnchor}">#{node.number}</a>
|
97
|
+
|
98
|
+
<br/><br/>
|
99
|
+
|
100
|
+
<big>#{node.title.to_html}</big>
|
101
|
+
</h1>
|
102
|
+
|
103
|
+
#{content.to_html}
|
104
|
+
|
105
|
+
</div>
|
106
|
+
}
|
107
|
+
end
|
108
|
+
|
109
|
+
add_node_handler :latex, :chapter do |node, content, *args|
|
110
|
+
%{
|
111
|
+
<hr style="display: none"/>
|
112
|
+
|
113
|
+
<div id="#{node.anchor}" class="chapter">
|
114
|
+
<h1 class="title">
|
115
|
+
Chapter <a href="##{node.tocAnchor}">#{node.latexNumber}</a>
|
116
|
+
|
117
|
+
<br/><br/>
|
118
|
+
|
119
|
+
<big>#{node.title}</big>
|
120
|
+
</h1>
|
121
|
+
|
122
|
+
#{content.to_html}
|
123
|
+
</div>
|
124
|
+
}
|
125
|
+
end
|
126
|
+
|
127
|
+
add_node_handler :latex, :section do |node, content, *args|
|
128
|
+
level = [node.depth, 6].min
|
129
|
+
|
130
|
+
%{
|
131
|
+
<hr style="display: none"/>
|
132
|
+
|
133
|
+
<div id="#{node.anchor}" class="section">
|
134
|
+
<h#{level} class="title">
|
135
|
+
<a href="##{node.tocAnchor}">#{node.latexNumber}</a>
|
136
|
+
|
137
|
+
|
138
|
+
|
139
|
+
#{node.title.to_html}
|
140
|
+
</h#{level}>
|
141
|
+
|
142
|
+
#{content.to_html}
|
143
|
+
|
144
|
+
</div>
|
145
|
+
}
|
146
|
+
end
|
147
|
+
|
148
|
+
add_node_handler :latex, :paragraph do |node, content, *args|
|
149
|
+
%{
|
150
|
+
<div id="#{node.anchor}" class="paragraph">
|
151
|
+
<p class="title">#{node.title.to_html}</p>
|
152
|
+
#{content.to_html}
|
153
|
+
</div>
|
154
|
+
}
|
155
|
+
end
|
156
|
+
|
157
|
+
|
158
|
+
@bibCipher = Cipher.new
|
159
|
+
|
160
|
+
# bibliography items
|
161
|
+
add_node_handler :index, :reference do |node, content, *args|
|
162
|
+
%{
|
163
|
+
<div id="#{node.anchor}" class="reference">
|
164
|
+
<table>
|
165
|
+
<tr>
|
166
|
+
<th>[#{node.number}]</th>
|
167
|
+
<td>#{content.to_html}</td>
|
168
|
+
</tr>
|
169
|
+
</table>
|
170
|
+
</div>
|
171
|
+
}
|
172
|
+
end
|
173
|
+
|
174
|
+
# bibliography items
|
175
|
+
add_handler :footnote do |caller, buffer, content, name|
|
176
|
+
anchor = "ref:#{name}".to_html_anchor
|
177
|
+
index = @footnotes.length
|
178
|
+
@footnotes << FootNote.new(anchor, name)
|
179
|
+
|
180
|
+
buffer << @bibCipher.encrypt(
|
181
|
+
[
|
182
|
+
%{<div id="#{anchor}">},
|
183
|
+
%{|_. [#{index}]|#{content}|}.to_html,
|
184
|
+
'</div>',
|
185
|
+
].join
|
186
|
+
)
|
187
|
+
end
|
188
|
+
|
189
|
+
# bibliography citations
|
190
|
+
add_lazy_handler :cite do |target, *args|
|
191
|
+
node = @nodeTree.type2nodes[:reference].find {|n| n.id == target}
|
192
|
+
|
193
|
+
if node
|
194
|
+
words = [
|
195
|
+
%{<a href="##{node.anchor}">Reference #{node.number}</a>},
|
196
|
+
|
197
|
+
# extra information about the citation (page #, etc.)
|
198
|
+
*args.map {|s| s.to_html}
|
47
199
|
]
|
200
|
+
|
201
|
+
"(see #{ words.join(', ') })"
|
202
|
+
else
|
203
|
+
warn "invalid cite to #{target.inspect}"
|
204
|
+
''
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
# cross references
|
209
|
+
add_lazy_handler :xref do |aTarget, aTitle|
|
210
|
+
nodes = @nodeTree.nodes
|
211
|
+
target = nodes.find {|n| n.id == aTarget} || # id has first priority
|
212
|
+
nodes.find {|n| n.anchor == aTarget}
|
213
|
+
|
214
|
+
if target
|
215
|
+
title = aTitle || "#{target.type.to_s.capitalize} #{target.latexNumber || target.number}"
|
216
|
+
%{<a href="##{target.anchor}">#{title.to_html}</a>}
|
217
|
+
else
|
218
|
+
warn "invalid xref to #{aTarget.inspect}"
|
219
|
+
''
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
def add_lazy_handler aHandlerName, &aHandler
|
225
|
+
(class << self; self; end).instance_eval do
|
226
|
+
define_method aHandlerName do |*args|
|
227
|
+
token = "#{aHandlerName}#{args.object_id}".digest
|
228
|
+
@lazyHandlers[token] = [aHandler, args]
|
229
|
+
token
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
# aNodeType:: name of the command that will trigger the handler
|
235
|
+
# aNodeHandler:: handler that will be triggered by the given command
|
236
|
+
def add_node_handler aNodeGroup, aNodeType, &aNodeHandler #:yields: node, content, *args
|
237
|
+
raise ArgumentError unless block_given?
|
238
|
+
|
239
|
+
if @nodeTree.handlers.key? aNodeType
|
240
|
+
raise "node handler #{aNodeType.inspect} already exists"
|
241
|
+
end
|
242
|
+
@nodeTree.handlers[aNodeType] = aNodeHandler
|
243
|
+
|
244
|
+
|
245
|
+
add_handler aNodeType do |caller, buffer, content, nodeInfo, *args|
|
246
|
+
if @nodeTree.caller2node.key? caller
|
247
|
+
node = @nodeTree.caller2node[caller]
|
248
|
+
|
249
|
+
# collect tree traversal information
|
250
|
+
node.timesSeen += 1
|
251
|
+
|
252
|
+
else # first time we are handling this node
|
253
|
+
|
254
|
+
# parse the arguments given to this handler
|
255
|
+
if nodeInfo.respond_to? :to_hash
|
256
|
+
nodeInfo = nodeInfo.to_hash
|
257
|
+
raise ArgumentError unless nodeInfo.key? :title
|
258
|
+
else
|
259
|
+
nodeInfo = {:title => nodeInfo.to_s, :id => args.shift}
|
260
|
+
end
|
261
|
+
|
262
|
+
# register this node as having been seen
|
263
|
+
node = Node.new nodeInfo.merge(
|
264
|
+
# node info
|
265
|
+
:caller => caller,
|
266
|
+
:type => aNodeType,
|
267
|
+
:group => aNodeGroup,
|
268
|
+
:args => args,
|
269
|
+
|
270
|
+
# content info
|
271
|
+
:content => content,
|
272
|
+
:digest => content.digest,
|
273
|
+
:leadingSpace => (buffer =~ /([ \t]*)\Z/ && $1),
|
274
|
+
|
275
|
+
# traversal info
|
276
|
+
:orderSeen => @nodeTree.caller2node.keys.length,
|
277
|
+
:timesSeen => 1
|
278
|
+
)
|
279
|
+
@nodeTree.caller2node[caller] = node
|
48
280
|
end
|
281
|
+
|
282
|
+
buffer << node.digest
|
49
283
|
end
|
50
284
|
end
|
51
285
|
|
52
286
|
# Post-processes the given ERB template result by parsing the document
|
53
287
|
# structure and expanding cross-references, and returns the result.
|
54
288
|
def post_process aResult
|
55
|
-
text = aResult
|
56
|
-
anchors = []
|
289
|
+
text = aResult
|
57
290
|
|
58
|
-
|
59
|
-
#
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
291
|
+
|
292
|
+
# build the node tree
|
293
|
+
@nodeTree.build!
|
294
|
+
toc = @nodeTree.table_of_contents
|
295
|
+
|
296
|
+
|
297
|
+
# convert to HTML
|
298
|
+
File.open('text', 'w') {|f| f << text} if $DEBUG
|
299
|
+
html = text.to_html
|
300
|
+
File.open('html', 'w') {|f| f << html} if $DEBUG
|
301
|
+
|
302
|
+
|
303
|
+
@nodeTree.process_input! html, @innerSpace
|
64
304
|
|
65
305
|
# expand cross-references into links to their targets
|
66
|
-
|
306
|
+
@lazyHandlers.each_pair do |token, (handler, args)|
|
307
|
+
html.gsub! token, handler.call(*args)
|
308
|
+
end
|
67
309
|
|
68
|
-
|
69
|
-
|
70
|
-
target = blocks.find {|b| b.anchor == anchor}
|
310
|
+
# expand all citations
|
311
|
+
# html = @bibCipher.decrypt_all(html)
|
71
312
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
313
|
+
|
314
|
+
[toc, html]
|
315
|
+
end
|
316
|
+
|
317
|
+
|
318
|
+
##-----------------------------------------------------------------------
|
319
|
+
# user API
|
320
|
+
|
321
|
+
# Unindents the inner space by the given amount.
|
322
|
+
def unindent aInnerSpace
|
323
|
+
@innerSpace = aInnerSpace
|
324
|
+
end
|
325
|
+
|
326
|
+
#-----------------------------------------------------------------------
|
327
|
+
|
328
|
+
private
|
329
|
+
|
330
|
+
def expand_includes aFilePath
|
331
|
+
input = File.read(aFilePath)
|
332
|
+
|
333
|
+
input.gsub! %r{<doc_proxy_include *(.*?)>} do
|
334
|
+
expand_includes($1)
|
335
|
+
end
|
336
|
+
|
337
|
+
input
|
338
|
+
end
|
339
|
+
|
340
|
+
#-----------------------------------------------------------------------
|
341
|
+
|
342
|
+
class Node < OpenStruct
|
343
|
+
undef id
|
344
|
+
undef type
|
345
|
+
end
|
346
|
+
|
347
|
+
class Cipher < Hash
|
348
|
+
def encrypt aString
|
349
|
+
digest = aString.digest
|
350
|
+
self[digest] = aString
|
351
|
+
digest
|
352
|
+
end
|
353
|
+
|
354
|
+
def decrypt digest
|
355
|
+
self[digest]
|
356
|
+
end
|
357
|
+
|
358
|
+
# Iteratively decrypts all digest substrings within the given string.
|
359
|
+
def decrypt_all aString
|
360
|
+
temp = self.dup
|
361
|
+
str = aString.dup
|
362
|
+
|
363
|
+
until temp.empty?
|
364
|
+
cipher = temp.find do |(digest, original)|
|
365
|
+
str.gsub! digest, original
|
77
366
|
end
|
367
|
+
|
368
|
+
raise unless cipher
|
369
|
+
temp.delete cipher[0]
|
78
370
|
end
|
79
371
|
|
80
|
-
|
81
|
-
|
82
|
-
|
372
|
+
str
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
class NodeTree < Hash
|
377
|
+
attr_reader :caller2node, :group2nodes, :type2nodes, :cipher, :handlers
|
83
378
|
|
84
|
-
|
85
|
-
|
379
|
+
def initialize
|
380
|
+
@cipher = Cipher.new
|
381
|
+
@handlers = {}
|
382
|
+
@caller2node = {}
|
383
|
+
@type2nodes = Hash.new {|h,k| h[k] = []}
|
384
|
+
@group2nodes = Hash.new {|h,k| h[k] = []}
|
385
|
+
end
|
386
|
+
|
387
|
+
def nodes
|
388
|
+
@caller2node.values
|
389
|
+
end
|
86
390
|
|
87
|
-
|
88
|
-
|
89
|
-
|
391
|
+
# Evaluates the given string which contains node digests.
|
392
|
+
def process_input! aString, aInnerSpace = nil
|
393
|
+
list = nodes
|
394
|
+
|
395
|
+
# let handlers modify node content
|
396
|
+
list.each do |node|
|
397
|
+
src = node.content
|
398
|
+
dst = @handlers[node.type].call(node, src, *node.args)
|
399
|
+
|
400
|
+
if aInnerSpace
|
401
|
+
space = node.leadingSpace + aInnerSpace
|
402
|
+
|
403
|
+
# add leading space if not present. this will ensure that
|
404
|
+
# lines without any leading space are correctly unindented
|
405
|
+
dst.gsub! %r/^[ \t]*/ do
|
406
|
+
if $&.index(space) == 0
|
407
|
+
$&
|
408
|
+
else
|
409
|
+
space + $&
|
410
|
+
end
|
90
411
|
end
|
412
|
+
|
413
|
+
# remove leading space
|
414
|
+
dst.gsub! %r/^#{space}/, ''
|
91
415
|
end
|
416
|
+
|
417
|
+
# XXX: escape single backslashes because they
|
418
|
+
# are removed later on for some reason...
|
419
|
+
dst.gsub! %r/\\/, '\&\&'
|
420
|
+
|
421
|
+
node.content = dst
|
92
422
|
end
|
93
423
|
|
94
|
-
|
95
|
-
|
424
|
+
# replace all node digests with node content
|
425
|
+
until list.empty?
|
426
|
+
target = list.find do |node|
|
427
|
+
aString.gsub! node.digest, node.content
|
428
|
+
end
|
96
429
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
430
|
+
raise unless target
|
431
|
+
list.delete target
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
# Builds this tree from traversal information.
|
436
|
+
def build!
|
437
|
+
# build the tree
|
438
|
+
self.clear
|
439
|
+
children = []
|
440
|
+
lastDepth = 0
|
441
|
+
|
442
|
+
nodes.sort_by {|n| n.orderSeen}.each do |node|
|
443
|
+
currDepth = node.timesSeen
|
109
444
|
|
110
|
-
|
111
|
-
|
445
|
+
# register this node into adjacency list
|
446
|
+
self[node] = [] unless self.key? node
|
112
447
|
|
113
|
-
|
114
|
-
|
448
|
+
if lastDepth > currDepth
|
449
|
+
subnodes = children.select {|n| n.timesSeen > currDepth}
|
450
|
+
self[node].concat subnodes
|
451
|
+
children = children - subnodes
|
452
|
+
end
|
453
|
+
|
454
|
+
children << node
|
455
|
+
lastDepth = currDepth
|
115
456
|
end
|
116
|
-
anchor = unanchor(anchor)
|
117
457
|
|
118
|
-
|
458
|
+
if $DEBUG
|
459
|
+
nodes.each do |node|
|
460
|
+
def node.inspect
|
461
|
+
title.inspect
|
462
|
+
end
|
463
|
+
end
|
464
|
+
pp self
|
465
|
+
end
|
119
466
|
|
120
467
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
]
|
468
|
+
# set depths of all nodes starting from root-level nodes
|
469
|
+
rootNodes = self.keys - self.values.flatten.uniq
|
470
|
+
rootNodes.sort_by {|n| n.orderSeen}.each do |node|
|
471
|
+
set_depth node, 1
|
472
|
+
end
|
473
|
+
|
128
474
|
|
129
|
-
|
130
|
-
|
475
|
+
# fill information for later stages
|
476
|
+
idUsage = Hash.new {|h,k| h[k] = []}
|
477
|
+
|
478
|
+
nodes.each do |node|
|
479
|
+
node.id ||= node.title
|
480
|
+
idUsage[node.id] << node
|
481
|
+
|
482
|
+
# forward and reverse anchors from & back to TOC
|
483
|
+
node.anchor = node.id.to_html_anchor
|
484
|
+
node.tocAnchor = node.object_id.to_s.to_html_anchor
|
485
|
+
end
|
486
|
+
|
487
|
+
idUsage.select {|(k,v)| v.length > 1}.each do |id, nodes|
|
488
|
+
warn "#{nodes.length} nodes have the same identifier: #{id.inspect}"
|
489
|
+
end
|
131
490
|
end
|
132
|
-
end
|
133
491
|
|
134
|
-
|
492
|
+
def table_of_contents
|
493
|
+
toc = '<ul>'
|
494
|
+
prevDepth = 0
|
495
|
+
prevIndex = ''
|
135
496
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
497
|
+
@group2nodes[:latex].each do |node|
|
498
|
+
# generate a LaTeX-style index (section number) for the heading
|
499
|
+
depthDiff = (node.depth - prevDepth).abs
|
500
|
+
|
501
|
+
node.latexNumber =
|
502
|
+
if node.depth > prevDepth
|
503
|
+
toc << '<li><ul>' * depthDiff
|
504
|
+
|
505
|
+
s = prevIndex + ('.1' * depthDiff)
|
506
|
+
s.sub(/^\./, '')
|
141
507
|
|
142
|
-
|
143
|
-
|
144
|
-
|
508
|
+
elsif node.depth < prevDepth
|
509
|
+
toc << '</ul></li>' * depthDiff
|
510
|
+
|
511
|
+
s = prevIndex.sub(/(\.\d+){#{depthDiff}}$/, '')
|
512
|
+
s.next
|
513
|
+
|
514
|
+
else
|
515
|
+
prevIndex.next
|
516
|
+
end
|
517
|
+
|
518
|
+
prevDepth = node.depth
|
519
|
+
prevIndex = node.latexNumber
|
520
|
+
|
521
|
+
|
522
|
+
# generate hyperlink for traveling from TOC to heading
|
523
|
+
toc << %{<li><span class="hide">#{node.latexNumber} </span><a id="#{node.tocAnchor}" href="##{node.anchor}">#{node.title.to_html}</a></li>}
|
524
|
+
end
|
525
|
+
|
526
|
+
if prevIndex.empty?
|
527
|
+
toc = nil # there were no headings
|
528
|
+
else
|
529
|
+
toc << '</ul></li>' * prevDepth
|
530
|
+
toc << '</ul>'
|
531
|
+
|
532
|
+
# collapse redundant list elements
|
533
|
+
while toc.gsub! %r{(<li>.*?)</li><li>(<ul>)}, '\1\2'
|
534
|
+
end
|
535
|
+
|
536
|
+
# collapse unnecessary levels
|
537
|
+
while toc.gsub! %r{(<ul>)<li><ul>(.*)</ul></li>(</ul>)}, '\1\2\3'
|
538
|
+
end
|
539
|
+
end
|
540
|
+
|
541
|
+
toc
|
542
|
+
end
|
543
|
+
|
544
|
+
private
|
545
|
+
|
546
|
+
# recursively sets the depth of the given
|
547
|
+
# node and performs linear node numbering
|
548
|
+
def set_depth aNode, aDepth
|
549
|
+
aNode.depth = aDepth
|
550
|
+
|
551
|
+
# set number for boxes (fig 1, fig 2, etc.)
|
552
|
+
ary = @type2nodes[aNode.type]
|
553
|
+
ary << aNode
|
554
|
+
aNode.number = ary.length
|
555
|
+
@group2nodes[aNode.group] << aNode
|
556
|
+
|
557
|
+
self[aNode].each do |child|
|
558
|
+
set_depth child, aDepth + 1
|
559
|
+
end
|
560
|
+
end
|
145
561
|
end
|
146
562
|
end
|
data/doc/lib/erb_content.rb
CHANGED
@@ -4,13 +4,13 @@
|
|
4
4
|
|
5
5
|
require 'erb'
|
6
6
|
|
7
|
-
# Returns an array containing the current ERB buffer and the content
|
8
|
-
# given block will append to the buffer when it is invoked.
|
7
|
+
# Returns an array containing the current ERB buffer and the content
|
8
|
+
# that the given block will append to the buffer when it is invoked.
|
9
9
|
#
|
10
10
|
# == Example
|
11
|
-
# Suppose your ERB template invoked a method with some arguments
|
12
|
-
# content in a block.
|
13
|
-
# content contained within the block.
|
11
|
+
# Suppose your ERB template invoked a method with some arguments
|
12
|
+
# and some content in a block. You can pass the block to this
|
13
|
+
# method to obtain the content contained within the block.
|
14
14
|
#
|
15
15
|
## template = ERB.new <<-EOS
|
16
16
|
## <% wrap_xml "message" do %>
|
@@ -18,8 +18,8 @@ require 'erb'
|
|
18
18
|
## <% end %>
|
19
19
|
## EOS
|
20
20
|
#
|
21
|
-
# In this case, the ERB template invokes the _wrap_xml_
|
22
|
-
# content within a pair of XML tags.
|
21
|
+
# In this case, the ERB template invokes the _wrap_xml_
|
22
|
+
# method to wrap some content within a pair of XML tags.
|
23
23
|
#
|
24
24
|
## def wrap_xml tag, &block
|
25
25
|
## buffer, content = ERB.buffer_and_content(&block)
|
@@ -49,7 +49,7 @@ def ERB.buffer_and_content
|
|
49
49
|
content = buffer.slice! a..b
|
50
50
|
|
51
51
|
# buffer
|
52
|
-
buffer.slice!
|
52
|
+
buffer.slice! -content.length..-1
|
53
53
|
|
54
54
|
[buffer, content]
|
55
55
|
end
|