codnar 0.1.64
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/ChangeLog +165 -0
- data/LICENSE +19 -0
- data/README.rdoc +32 -0
- data/Rakefile +66 -0
- data/bin/codnar-split +5 -0
- data/bin/codnar-weave +5 -0
- data/codnar.html +10945 -0
- data/doc/logo.png +0 -0
- data/doc/root.html +22 -0
- data/doc/story.markdown +180 -0
- data/doc/system.markdown +671 -0
- data/lib/codnar.rb +41 -0
- data/lib/codnar/application.rb +92 -0
- data/lib/codnar/cache.rb +61 -0
- data/lib/codnar/data/contents.js +113 -0
- data/lib/codnar/data/control_chunks.js +44 -0
- data/lib/codnar/data/style.css +95 -0
- data/lib/codnar/data/sunlight/README.txt +4 -0
- data/lib/codnar/data/sunlight/css-min.js +1 -0
- data/lib/codnar/data/sunlight/default.css +236 -0
- data/lib/codnar/data/sunlight/javascript-min.js +1 -0
- data/lib/codnar/data/sunlight/min.js +1 -0
- data/lib/codnar/data/sunlight/ruby-min.js +1 -0
- data/lib/codnar/data/yui/README.txt +3 -0
- data/lib/codnar/data/yui/base.css +132 -0
- data/lib/codnar/data/yui/reset.css +142 -0
- data/lib/codnar/formatter.rb +180 -0
- data/lib/codnar/grouper.rb +28 -0
- data/lib/codnar/gvim.rb +132 -0
- data/lib/codnar/hash_extensions.rb +41 -0
- data/lib/codnar/markdown.rb +47 -0
- data/lib/codnar/merger.rb +138 -0
- data/lib/codnar/rake.rb +41 -0
- data/lib/codnar/rake/split_task.rb +71 -0
- data/lib/codnar/rake/weave_task.rb +59 -0
- data/lib/codnar/rdoc.rb +9 -0
- data/lib/codnar/reader.rb +121 -0
- data/lib/codnar/scanner.rb +216 -0
- data/lib/codnar/split.rb +58 -0
- data/lib/codnar/split_configurations.rb +367 -0
- data/lib/codnar/splitter.rb +32 -0
- data/lib/codnar/string_extensions.rb +25 -0
- data/lib/codnar/sunlight.rb +17 -0
- data/lib/codnar/version.rb +8 -0
- data/lib/codnar/weave.rb +58 -0
- data/lib/codnar/weave_configurations.rb +48 -0
- data/lib/codnar/weaver.rb +105 -0
- data/lib/codnar/writer.rb +38 -0
- data/test/cache_computations.rb +41 -0
- data/test/deep_merge.rb +29 -0
- data/test/embed_images.rb +12 -0
- data/test/expand_markdown.rb +27 -0
- data/test/expand_rdoc.rb +20 -0
- data/test/format_code_gvim_configurations.rb +55 -0
- data/test/format_code_sunlight_configurations.rb +37 -0
- data/test/format_comment_configurations.rb +86 -0
- data/test/format_lines.rb +72 -0
- data/test/group_lines.rb +31 -0
- data/test/gvim_highlight_syntax.rb +49 -0
- data/test/identify_chunks.rb +32 -0
- data/test/lib/test_with_configurations.rb +15 -0
- data/test/merge_lines.rb +133 -0
- data/test/rake_tasks.rb +38 -0
- data/test/read_chunks.rb +110 -0
- data/test/run_application.rb +56 -0
- data/test/run_split.rb +38 -0
- data/test/run_weave.rb +75 -0
- data/test/scan_lines.rb +78 -0
- data/test/split_chunk_configurations.rb +55 -0
- data/test/split_code.rb +109 -0
- data/test/split_code_configurations.rb +73 -0
- data/test/split_combined_configurations.rb +114 -0
- data/test/split_complex_comment_configurations.rb +73 -0
- data/test/split_documentation.rb +92 -0
- data/test/split_documentation_configurations.rb +97 -0
- data/test/split_simple_comment_configurations.rb +50 -0
- data/test/sunlight_highlight_syntax.rb +25 -0
- data/test/weave_configurations.rb +144 -0
- data/test/write_chunks.rb +28 -0
- metadata +363 -0
data/lib/codnar/split.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
module Codnar
|
2
|
+
|
3
|
+
# Split application.
|
4
|
+
class Split < Application
|
5
|
+
|
6
|
+
# Run the weaving Codnar application, returning its status.
|
7
|
+
def run
|
8
|
+
super { split }
|
9
|
+
end
|
10
|
+
|
11
|
+
protected
|
12
|
+
|
13
|
+
# Split the specified input file into chunks.
|
14
|
+
def split
|
15
|
+
@configuration = Codnar::Configuration::SPLIT_HTML_DOCUMENTATION if @configuration == {}
|
16
|
+
splitter = Splitter.new(@errors, @configuration)
|
17
|
+
print(splitter.chunks(ARGV[0]).to_yaml)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Parse remaining command-line file arguments.
|
21
|
+
def parse_arguments
|
22
|
+
case ARGV.size
|
23
|
+
when 1 then return
|
24
|
+
when 0 then $stderr.puts("#{$0}: No input file to split")
|
25
|
+
else $stderr.puts("#{$0}: Too many input files to split")
|
26
|
+
end
|
27
|
+
exit(1)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Return the banner line of the help message.
|
31
|
+
def banner
|
32
|
+
return "codnar-split - Split documentation or code files to chunks."
|
33
|
+
end
|
34
|
+
|
35
|
+
# Return the name and description of any final command-line file arguments.
|
36
|
+
def arguments
|
37
|
+
return "FILE", "Documentation or code file to split."
|
38
|
+
end
|
39
|
+
|
40
|
+
# Return a short description of the program.
|
41
|
+
def description
|
42
|
+
return <<-EOF.unindent
|
43
|
+
Split the documentation of file into chunks that are printed in YAML format to
|
44
|
+
the output (to be read by codnar-weave). Many file formats can be split
|
45
|
+
depending on the specified configuration. The default configuration is called
|
46
|
+
SPLIT_HTML_DOCUMENTATION, and it preserves the whole file as a single formatted
|
47
|
+
HTML documentation chunk. This isn't very useful.
|
48
|
+
|
49
|
+
The configuration needs to specify a set of line classification patterns,
|
50
|
+
parsing states and pattern-based transitions between them, the initial state,
|
51
|
+
and expressions for formatting classified lines to HTML. See the Codnar
|
52
|
+
documentation for details.
|
53
|
+
EOF
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,367 @@
|
|
1
|
+
module Codnar
|
2
|
+
|
3
|
+
# A module for all the "built-in" configurations. The names of these
|
4
|
+
# configurations can be passed to the --require option of any Codnar
|
5
|
+
# Application.
|
6
|
+
module Configuration
|
7
|
+
|
8
|
+
# {{{ Documentation "splitting" configurations
|
9
|
+
|
10
|
+
# "Split" a documentation file. All lines are assumed to have the same kind
|
11
|
+
# +doc+ and no indentation is collected. Unless overriden by additional
|
12
|
+
# configuration(s), the lines are assumed to contain formatted HTML, and
|
13
|
+
# are passed as-is to the output.
|
14
|
+
#
|
15
|
+
# This is the default configuration as it performs the minimal amount of
|
16
|
+
# processing on the input. It isn't the most useful configuration.
|
17
|
+
SPLIT_HTML_DOCUMENTATION = {
|
18
|
+
"formatters" => {
|
19
|
+
"doc" => "Formatter.cast_lines(lines, 'html')",
|
20
|
+
},
|
21
|
+
"syntax" => {
|
22
|
+
"patterns" => {
|
23
|
+
"doc" => { "regexp" => "^(.*)$", "groups" => [ "payload" ] },
|
24
|
+
},
|
25
|
+
"states" => {
|
26
|
+
"start" => { "transitions" => [ { "pattern" => "doc" } ] },
|
27
|
+
},
|
28
|
+
},
|
29
|
+
}
|
30
|
+
|
31
|
+
# "Split" a documentation file containing arbitrary text, which is
|
32
|
+
# preserved by escaping it and wrapping it in an HTML pre element.
|
33
|
+
SPLIT_PRE_DOCUMENTATION = SPLIT_HTML_DOCUMENTATION.deep_merge(
|
34
|
+
"formatters" => {
|
35
|
+
"doc" => "Formatter.lines_to_pre_html(lines, :class => :doc)",
|
36
|
+
}
|
37
|
+
)
|
38
|
+
|
39
|
+
# "Split" a documentation file containing pure RDoc documentation.
|
40
|
+
SPLIT_RDOC_DOCUMENTATION = SPLIT_HTML_DOCUMENTATION.deep_merge(
|
41
|
+
"formatters" => {
|
42
|
+
"doc" => "Formatter.markup_lines_to_html(lines, 'RDoc')",
|
43
|
+
"unindented_html" => "Formatter.unindented_lines_to_html(lines)",
|
44
|
+
}
|
45
|
+
)
|
46
|
+
|
47
|
+
# "Split" a documentation file containing pure Markdown documentation.
|
48
|
+
SPLIT_MARKDOWN_DOCUMENTATION = SPLIT_HTML_DOCUMENTATION.deep_merge(
|
49
|
+
"formatters" => {
|
50
|
+
"doc" => "Formatter.markup_lines_to_html(lines, 'Markdown')",
|
51
|
+
"unindented_html" => "Formatter.unindented_lines_to_html(lines)",
|
52
|
+
}
|
53
|
+
)
|
54
|
+
|
55
|
+
# }}}
|
56
|
+
|
57
|
+
# {{{ Source code lines classification configurations
|
58
|
+
|
59
|
+
# Classify all lines as source code of some syntax (kind). This doesn't
|
60
|
+
# distinguish between comment and code lines; to do that, you need to
|
61
|
+
# combine this with comment classification configuration(s). Also, it just
|
62
|
+
# formats the lines in an HTML +pre+ element, without any syntax
|
63
|
+
# highlighting; to do that, you need to combine this with syntax
|
64
|
+
# highlighting formatting configuration(s).
|
65
|
+
CLASSIFY_SOURCE_CODE = lambda do |syntax|
|
66
|
+
return {
|
67
|
+
"formatters" => {
|
68
|
+
"#{syntax}_code" => "Formatter.lines_to_pre_html(lines, :class => :code)",
|
69
|
+
},
|
70
|
+
"syntax" => {
|
71
|
+
"patterns" => {
|
72
|
+
"#{syntax}_code" => { "regexp" => "^(\\s*)(.*)$" },
|
73
|
+
},
|
74
|
+
"states" => {
|
75
|
+
"start" => {
|
76
|
+
"transitions" => [
|
77
|
+
{ "pattern" => "#{syntax}_code" },
|
78
|
+
],
|
79
|
+
},
|
80
|
+
},
|
81
|
+
},
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
# }}}
|
86
|
+
|
87
|
+
# {{{ Nested foreign syntax code islands configurations
|
88
|
+
|
89
|
+
# Allow for comments containing "((( <syntax>" and "))) <syntax>" to
|
90
|
+
# designate nested islands of foreign syntax inside the normal code. The
|
91
|
+
# designator comment lines are always treated as part of the surrounding
|
92
|
+
# code, not as part of the nested foreign syntax code. There is no further
|
93
|
+
# classification of the nested foreign syntax code. Therefore, the nested
|
94
|
+
# code is not examined for begin/end chunk markers. Likewise, the nested
|
95
|
+
# code may not contain deeper nested code using a third syntax.
|
96
|
+
CLASSIFY_NESTED_CODE = lambda do |outer_syntax, inner_syntax|
|
97
|
+
{
|
98
|
+
"syntax" => {
|
99
|
+
"patterns" => {
|
100
|
+
"start_#{inner_syntax}_in_#{outer_syntax}" =>
|
101
|
+
{ "regexp" => "^(\\s*)(.*\\(\\(\\(\\s*#{inner_syntax}.*)$" },
|
102
|
+
"end_#{inner_syntax}_in_#{outer_syntax}" =>
|
103
|
+
{ "regexp" => "^(\\s*)(.*\\)\\)\\)\\s*#{inner_syntax}.*)$" },
|
104
|
+
"#{inner_syntax}_in_#{outer_syntax}" =>
|
105
|
+
{ "regexp" => "^(\\s*)(.*)$" },
|
106
|
+
},
|
107
|
+
"states" => {
|
108
|
+
"start" => {
|
109
|
+
"transitions" => [
|
110
|
+
{ "pattern" => "start_#{inner_syntax}_in_#{outer_syntax}",
|
111
|
+
"kind" => "#{outer_syntax}_code",
|
112
|
+
"next_state" => "#{inner_syntax}_in_#{outer_syntax}" },
|
113
|
+
[],
|
114
|
+
],
|
115
|
+
},
|
116
|
+
"#{inner_syntax}_in_#{outer_syntax}" => {
|
117
|
+
"transitions" => [
|
118
|
+
{ "pattern" => "end_#{inner_syntax}_in_#{outer_syntax}",
|
119
|
+
"kind" => "#{outer_syntax}_code",
|
120
|
+
"next_state" => "start" },
|
121
|
+
{ "pattern" => "#{inner_syntax}_in_#{outer_syntax}",
|
122
|
+
"kind" => "#{inner_syntax}_code" },
|
123
|
+
],
|
124
|
+
},
|
125
|
+
},
|
126
|
+
},
|
127
|
+
}
|
128
|
+
end
|
129
|
+
|
130
|
+
# }}}
|
131
|
+
|
132
|
+
# {{{ Simple comment classification configurations
|
133
|
+
|
134
|
+
# Classify simple comment lines. It accepts a restricted format: each
|
135
|
+
# comment is expected to start with some exact prefix (e.g. "#" for shell
|
136
|
+
# style comments or "//" for C++ style comments). The following space, if
|
137
|
+
# any, is stripped from the payload. As a convenience, comment that starts
|
138
|
+
# with "!" is not taken to start a comment. This both protects the 1st line
|
139
|
+
# of shell scripts ("#!"), and also any other line you wish to avoid being
|
140
|
+
# treated as a comment.
|
141
|
+
#
|
142
|
+
# This configuration is typically complemented by an additional one
|
143
|
+
# specifying how to format the (stripped!) comments; by default they are
|
144
|
+
# just displayed as-is using an HTML +pre+ element, which isn't very
|
145
|
+
# useful.
|
146
|
+
CLASSIFY_SIMPLE_COMMENTS = lambda do |prefix|
|
147
|
+
return Configuration.simple_comments(prefix)
|
148
|
+
end
|
149
|
+
|
150
|
+
# Classify simple shell ("#") comment lines.
|
151
|
+
CLASSIFY_SHELL_COMMENTS = lambda do
|
152
|
+
return Configuration.simple_comments("#")
|
153
|
+
end
|
154
|
+
|
155
|
+
# Classify simple C++ ("//") comment lines.
|
156
|
+
CLASSIFY_CPP_COMMENTS = lambda do
|
157
|
+
return Configuration.simple_comments("//")
|
158
|
+
end
|
159
|
+
|
160
|
+
# Configuration for classifying lines to comments and code based on a
|
161
|
+
# simple prefix (e.g. "#" for shell style comments or "//" for C++ style
|
162
|
+
# comments).
|
163
|
+
def self.simple_comments(prefix)
|
164
|
+
return {
|
165
|
+
"syntax" => {
|
166
|
+
"patterns" => {
|
167
|
+
"comment_#{prefix}" => { "regexp" => "^(\\s*)#{prefix}(?!!)\\s?(.*)$" },
|
168
|
+
},
|
169
|
+
"states" => {
|
170
|
+
"start" => {
|
171
|
+
"transitions" => [
|
172
|
+
{ "pattern" => "comment_#{prefix}", "kind" => "comment" },
|
173
|
+
[]
|
174
|
+
],
|
175
|
+
},
|
176
|
+
},
|
177
|
+
},
|
178
|
+
}
|
179
|
+
end
|
180
|
+
|
181
|
+
# }}}
|
182
|
+
|
183
|
+
# {{{ Complex comment classification configurations
|
184
|
+
|
185
|
+
# Classify complex comment lines. It accepts a restricted format: each
|
186
|
+
# comment is expected to start with some exact prefix (e.g. "/*" for C
|
187
|
+
# style comments or "<!--" for HTML style comments). The following space,
|
188
|
+
# if any, is stripped from the payload. Following lines are also considered
|
189
|
+
# comments; a leading inner line prefix (e.g., " *" for C style comments or
|
190
|
+
# " -" for HTML style comments) with an optional following space are
|
191
|
+
# stripped from the payload. Finally, a line containing some exact suffix
|
192
|
+
# (e.g. "*/" for C style comments, or "-->" for HTML style comments) ends
|
193
|
+
# the comment. A one line comment format is also supported containing the
|
194
|
+
# prefix, the payload, and the suffix. As a convenience, comment that
|
195
|
+
# starts with "!" is not taken to start a comment. This allows protecting
|
196
|
+
# comment block you wish to avoid being classified as a comment.
|
197
|
+
#
|
198
|
+
# This configuration is typically complemented by an additional one
|
199
|
+
# specifying how to format the (stripped!) comments; by default they are
|
200
|
+
# just displayed as-is using an HTML +pre+ element, which isn't very
|
201
|
+
# useful.
|
202
|
+
CLASSIFY_COMPLEX_COMMENTS = lambda do |prefix, inner, suffix|
|
203
|
+
return Configuration.complex_comments(prefix, inner, suffix)
|
204
|
+
end
|
205
|
+
|
206
|
+
# Classify complex C ("/*", " *", " */") style comments.
|
207
|
+
CLASSIFY_C_COMMENTS = lambda do
|
208
|
+
# Since the prefix/inner/suffix passed to the configuration are regexps,
|
209
|
+
# we need to escape special characters such as "*".
|
210
|
+
return Configuration.complex_comments("/\\*", " \\*", " \\*/")
|
211
|
+
end
|
212
|
+
|
213
|
+
# Classify complex HTML ("<!--", " -", "-->") style comments.
|
214
|
+
CLASSIFY_HTML_COMMENTS = lambda do
|
215
|
+
return Configuration.complex_comments("<!--", " -", "-->")
|
216
|
+
end
|
217
|
+
|
218
|
+
# Configuration for classifying lines to comments and code based on a
|
219
|
+
# complex start prefix, inner line prefix and final suffix (e.g., "/*", "
|
220
|
+
# *", " */" for C-style comments or "<!--", " -", "-->" for HTML style
|
221
|
+
# comments).
|
222
|
+
def self.complex_comments(prefix, inner, suffix)
|
223
|
+
return {
|
224
|
+
"syntax" => {
|
225
|
+
"patterns" => {
|
226
|
+
"comment_prefix_#{prefix}" => { "regexp" => "^(\\s*)#{prefix}(?!!)\\s?(.*)$" },
|
227
|
+
"comment_inner_#{inner}" => { "regexp" => "^(\\s*)#{inner}\\s?(.*)$" },
|
228
|
+
"comment_suffix_#{suffix}" => { "regexp" => "^(\\s*)#{suffix}\\s*$" },
|
229
|
+
"comment_line_#{prefix}_#{suffix}" => { "regexp" => "^(\\s*)#{prefix}(?!!)\s?(.*?)\s*#{suffix}\\s*$" },
|
230
|
+
},
|
231
|
+
"states" => {
|
232
|
+
"start" => {
|
233
|
+
"transitions" => [
|
234
|
+
{ "pattern" => "comment_line_#{prefix}_#{suffix}",
|
235
|
+
"kind" => "comment" },
|
236
|
+
{ "pattern" => "comment_prefix_#{prefix}",
|
237
|
+
"kind" => "comment",
|
238
|
+
"next_state" => "comment_#{prefix}" },
|
239
|
+
[],
|
240
|
+
],
|
241
|
+
},
|
242
|
+
"comment_#{prefix}" => {
|
243
|
+
"transitions" => [
|
244
|
+
{ "pattern" => "comment_suffix_#{suffix}",
|
245
|
+
"kind" => "comment",
|
246
|
+
"next_state" => "start" },
|
247
|
+
{ "pattern" => "comment_inner_#{inner}",
|
248
|
+
"kind" => "comment" },
|
249
|
+
],
|
250
|
+
},
|
251
|
+
},
|
252
|
+
},
|
253
|
+
}
|
254
|
+
end
|
255
|
+
|
256
|
+
# }}}
|
257
|
+
|
258
|
+
# {{{ Comment formatting configurations
|
259
|
+
|
260
|
+
# Format comments as HTML pre elements. Is used to complement a
|
261
|
+
# configuration that classifies some lines as +comment+.
|
262
|
+
FORMAT_PRE_COMMENTS = {
|
263
|
+
"formatters" => {
|
264
|
+
"comment" => "Formatter.lines_to_pre_html(lines, :class => :comment)",
|
265
|
+
},
|
266
|
+
}
|
267
|
+
|
268
|
+
# Format comments that use the RDoc notation. Is used to complement a
|
269
|
+
# configuration that classifies some lines as +comment+.
|
270
|
+
FORMAT_RDOC_COMMENTS = {
|
271
|
+
"formatters" => {
|
272
|
+
"comment" => "Formatter.markup_lines_to_html(lines, 'RDoc')",
|
273
|
+
"unindented_html" => "Formatter.unindented_lines_to_html(lines)",
|
274
|
+
},
|
275
|
+
}
|
276
|
+
|
277
|
+
# Format comments that use the Markdown notation. Is used to complement a
|
278
|
+
# configuration that classifies some lines as +comment+.
|
279
|
+
FORMAT_MARKDOWN_COMMENTS = {
|
280
|
+
"formatters" => {
|
281
|
+
"comment" => "Formatter.markup_lines_to_html(lines, 'Markdown')",
|
282
|
+
"unindented_html" => "Formatter.unindented_lines_to_html(lines)",
|
283
|
+
},
|
284
|
+
}
|
285
|
+
|
286
|
+
# }}}
|
287
|
+
|
288
|
+
# {{{ GVim syntax highlighting formatting configurations
|
289
|
+
|
290
|
+
# Format code using GVim's Ruby syntax highlighting, using explicit HTML
|
291
|
+
# constructs. Assumes some previous configuration already classified the
|
292
|
+
# code lines.
|
293
|
+
FORMAT_CODE_GVIM_HTML = lambda do |syntax|
|
294
|
+
return Configuration.gvim_code_format(syntax)
|
295
|
+
end
|
296
|
+
|
297
|
+
# Format code using GVim's Ruby syntax highlighting, using CSS classes
|
298
|
+
# instead of explicit font and color styles. Assumes some previous
|
299
|
+
# configuration already classified the code lines.
|
300
|
+
FORMAT_CODE_GVIM_CSS = lambda do |syntax|
|
301
|
+
return Configuration.gvim_code_format(syntax, "'+:let html_use_css=1'")
|
302
|
+
end
|
303
|
+
|
304
|
+
# Return a configuration for highlighting a specific syntax using GVim.
|
305
|
+
def self.gvim_code_format(syntax, extra_commands = "")
|
306
|
+
return {
|
307
|
+
"formatters" => {
|
308
|
+
"#{syntax}_code" => "GVim.lines_to_html(lines, '#{syntax}', [ #{extra_commands} ])",
|
309
|
+
},
|
310
|
+
}
|
311
|
+
end
|
312
|
+
|
313
|
+
# }}}
|
314
|
+
|
315
|
+
# {{{ Sunlight syntax highlighting formatting configurations
|
316
|
+
|
317
|
+
# Format code using Sunlight's syntax highlighting. This assumes the HTML
|
318
|
+
# will include and invoke Sunlight's Javascript file which does the
|
319
|
+
# highlighting on the fly inside the DOM, instead of pre-computing it when
|
320
|
+
# splitting the file.
|
321
|
+
FORMAT_CODE_SUNLIGHT = lambda do |syntax|
|
322
|
+
return Configuration.sunlight_code_format(syntax)
|
323
|
+
end
|
324
|
+
|
325
|
+
# Return a configuration for highlighting a specific syntax using Sunlight.
|
326
|
+
def self.sunlight_code_format(syntax)
|
327
|
+
return {
|
328
|
+
"formatters" => {
|
329
|
+
"#{syntax}_code" => "Sunlight.lines_to_html(lines, '#{syntax}')",
|
330
|
+
},
|
331
|
+
}
|
332
|
+
end
|
333
|
+
|
334
|
+
# }}}
|
335
|
+
|
336
|
+
# {{{ Chunk splitting configurations
|
337
|
+
|
338
|
+
# Group lines into chunks using VIM-style "{{{"/"}}}" region designations.
|
339
|
+
# Assumes other configurations handle the actual content lines.
|
340
|
+
CHUNK_BY_VIM_REGIONS = {
|
341
|
+
"formatters" => {
|
342
|
+
"begin_chunk" => "[]",
|
343
|
+
"end_chunk" => "[]",
|
344
|
+
"nested_chunk" => "Formatter.nested_chunk_lines_to_html(lines)",
|
345
|
+
},
|
346
|
+
"syntax" => {
|
347
|
+
"patterns" => {
|
348
|
+
"begin_chunk" => { "regexp" => "^(\\s*)\\W*\\{\\{\\{\\s*(.*?)\\s*$" },
|
349
|
+
"end_chunk" => { "regexp" => "^(\\s*)\\W*\\}\\}\\}\\s*(.*?)\\s*$" },
|
350
|
+
},
|
351
|
+
"states" => {
|
352
|
+
"start" => {
|
353
|
+
"transitions" => [
|
354
|
+
{ "pattern" => "begin_chunk" },
|
355
|
+
{ "pattern" => "end_chunk" },
|
356
|
+
[],
|
357
|
+
],
|
358
|
+
},
|
359
|
+
},
|
360
|
+
},
|
361
|
+
}
|
362
|
+
|
363
|
+
# }}}
|
364
|
+
|
365
|
+
end
|
366
|
+
|
367
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Codnar
|
2
|
+
|
3
|
+
# Split disk files into chunks.
|
4
|
+
class Splitter
|
5
|
+
|
6
|
+
# Construct a splitter based on a configuration in the following structure:
|
7
|
+
#
|
8
|
+
# syntax: <syntax>
|
9
|
+
# formatters:
|
10
|
+
# <kind>: <expression>
|
11
|
+
#
|
12
|
+
# Where the syntax is passed as-is to (and expanded in-place by) a Scanner,
|
13
|
+
# and the formatters are passed as-is to a Formatter to convert the chunk's
|
14
|
+
# classified lines into HTML.
|
15
|
+
def initialize(errors, configuration)
|
16
|
+
@errors = errors
|
17
|
+
@configuration = configuration
|
18
|
+
@scanner = Scanner.new(errors, configuration.syntax)
|
19
|
+
@formatter = Formatter.new(errors, configuration.formatters)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Split a disk file into HTML chunks.
|
23
|
+
def chunks(path)
|
24
|
+
lines = @scanner.lines(path)
|
25
|
+
chunks = Merger.chunks(@errors, path, lines)
|
26
|
+
chunks.each { |chunk| chunk.html = @formatter.lines_to_html(chunk.delete("lines")) }
|
27
|
+
return chunks
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|