codnar 0.1.64
Sign up to get free protection for your applications and to get access to all the features.
- 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
|