codnar 0.1.68 → 0.1.73
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 +17 -0
- data/codnar.html +1368 -527
- data/doc/system.markdown +56 -15
- data/lib/codnar.rb +6 -0
- data/lib/codnar/configuration/code.rb +87 -0
- data/lib/codnar/configuration/comments.rb +234 -0
- data/lib/codnar/configuration/documentation.rb +65 -0
- data/lib/codnar/configuration/highlighting.rb +107 -0
- data/lib/codnar/data/contents.js +2 -1
- data/lib/codnar/haddock.rb +72 -0
- data/lib/codnar/rake/split_task.rb +6 -0
- data/lib/codnar/scanner.rb +34 -11
- data/lib/codnar/split_configurations.rb +4 -382
- data/lib/codnar/string_extensions.rb +4 -3
- data/lib/codnar/version.rb +1 -1
- data/test/expand_haddock.rb +23 -0
- data/test/expand_rdoc.rb +2 -2
- data/test/format_comment_configurations.rb +1 -1
- data/test/run_weave.rb +2 -3
- data/test/split_code.rb +1 -1
- data/test/split_combined_configurations.rb +1 -1
- data/test/{split_complex_comment_configurations.rb → split_delimited_comment_configurations.rb} +11 -11
- data/test/split_denoted_comment_configurations.rb +62 -0
- data/test/split_documentation.rb +1 -1
- data/test/split_documentation_configurations.rb +1 -1
- metadata +16 -7
@@ -0,0 +1,65 @@
|
|
1
|
+
module Codnar
|
2
|
+
|
3
|
+
module Configuration
|
4
|
+
|
5
|
+
# Configurations for "splitting" documentation files.
|
6
|
+
module Documentation
|
7
|
+
|
8
|
+
# "Split" a documentation file. All lines are assumed to have the same kind
|
9
|
+
# +doc+ and no indentation is collected. Unless overriden by additional
|
10
|
+
# configuration(s), the lines are assumed to contain formatted HTML, and
|
11
|
+
# are passed as-is to the output.
|
12
|
+
#
|
13
|
+
# This is the default configuration as it performs the minimal amount of
|
14
|
+
# processing on the input. It isn't the most useful configuration.
|
15
|
+
SPLIT_HTML_DOCUMENTATION = {
|
16
|
+
"formatters" => {
|
17
|
+
"doc" => "Formatter.cast_lines(lines, 'html')",
|
18
|
+
},
|
19
|
+
"syntax" => {
|
20
|
+
"patterns" => {
|
21
|
+
"doc" => { "regexp" => "^(.*)$", "groups" => [ "payload" ] },
|
22
|
+
},
|
23
|
+
"states" => {
|
24
|
+
"start" => { "transitions" => [ { "pattern" => "doc" } ] },
|
25
|
+
},
|
26
|
+
},
|
27
|
+
}
|
28
|
+
|
29
|
+
# "Split" a documentation file containing arbitrary text, which is
|
30
|
+
# preserved by escaping it and wrapping it in an HTML pre element.
|
31
|
+
SPLIT_PRE_DOCUMENTATION = SPLIT_HTML_DOCUMENTATION.deep_merge(
|
32
|
+
"formatters" => {
|
33
|
+
"doc" => "Formatter.lines_to_pre_html(lines, :class => :doc)",
|
34
|
+
}
|
35
|
+
)
|
36
|
+
|
37
|
+
# "Split" a documentation file containing pure RDoc documentation.
|
38
|
+
SPLIT_RDOC_DOCUMENTATION = SPLIT_HTML_DOCUMENTATION.deep_merge(
|
39
|
+
"formatters" => {
|
40
|
+
"doc" => "Formatter.markup_lines_to_html(lines, Codnar::RDoc, 'rdoc')",
|
41
|
+
"unindented_html" => "Formatter.unindented_lines_to_html(lines)",
|
42
|
+
}
|
43
|
+
)
|
44
|
+
|
45
|
+
# "Split" a documentation file containing pure Markdown documentation.
|
46
|
+
SPLIT_MARKDOWN_DOCUMENTATION = SPLIT_HTML_DOCUMENTATION.deep_merge(
|
47
|
+
"formatters" => {
|
48
|
+
"doc" => "Formatter.markup_lines_to_html(lines, Codnar::Markdown, 'markdown')",
|
49
|
+
"unindented_html" => "Formatter.unindented_lines_to_html(lines)",
|
50
|
+
}
|
51
|
+
)
|
52
|
+
|
53
|
+
# "Split" a documentation file containing a GraphViz diagram.
|
54
|
+
SPLIT_GRAPHVIZ_DOCUMENTATION = SPLIT_HTML_DOCUMENTATION.deep_merge(
|
55
|
+
"formatters" => {
|
56
|
+
"doc" => "Formatter.markup_lines_to_html(lines, Codnar::GraphViz, 'graphviz')",
|
57
|
+
"unindented_html" => "Formatter.unindented_lines_to_html(lines)",
|
58
|
+
}
|
59
|
+
)
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module Codnar
|
2
|
+
|
3
|
+
module Configuration
|
4
|
+
|
5
|
+
# Configurations for highlighting source code lines.
|
6
|
+
module Highlighting
|
7
|
+
|
8
|
+
# {{{ GVim syntax highlighting formatting configurations
|
9
|
+
|
10
|
+
# Format code using GVim's syntax highlighting, using explicit HTML
|
11
|
+
# constructs. Assumes some previous configuration already classified the
|
12
|
+
# code lines.
|
13
|
+
FORMAT_CODE_GVIM_HTML = lambda do |syntax|
|
14
|
+
return Highlighting.klass_code_format('GVim', syntax, "[]")
|
15
|
+
end
|
16
|
+
|
17
|
+
# Format code using GVim's syntax highlighting, using CSS classes instead
|
18
|
+
# of explicit font and color styles. Assumes some previous configuration
|
19
|
+
# already classified the code lines.
|
20
|
+
FORMAT_CODE_GVIM_CSS = lambda do |syntax|
|
21
|
+
return Highlighting.klass_code_format('GVim', syntax, "[ '+:let html_use_css=1' ]")
|
22
|
+
end
|
23
|
+
|
24
|
+
# Return a configuration for highlighting a specific syntax using GVim.
|
25
|
+
def self.klass_code_format(klass, syntax, options)
|
26
|
+
return {
|
27
|
+
"formatters" => {
|
28
|
+
"#{syntax}_code" => "#{klass}.lines_to_html(lines, '#{syntax}', #{options})",
|
29
|
+
},
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
# }}}
|
34
|
+
|
35
|
+
# {{{ CodeRay syntax highlighting formatting configurations
|
36
|
+
|
37
|
+
# Format code using CodeRay's syntax highlighting, using explicit HTML
|
38
|
+
# constructs. Assumes some previous configuration already classified the
|
39
|
+
# code lines.
|
40
|
+
FORMAT_CODE_CODERAY_HTML = lambda do |syntax|
|
41
|
+
return Highlighting.klass_code_format('CodeRay', syntax, "{}")
|
42
|
+
end
|
43
|
+
|
44
|
+
# Format code using CodeRay's syntax highlighting, using CSS classes
|
45
|
+
# instead of explicit font and color styles. Assumes some previous
|
46
|
+
# configuration already classified the code lines.
|
47
|
+
FORMAT_CODE_CODERAY_CSS = lambda do |syntax|
|
48
|
+
return Highlighting.klass_code_format('CodeRay', syntax, "{ :css => :class }")
|
49
|
+
end
|
50
|
+
|
51
|
+
# }}}
|
52
|
+
|
53
|
+
# {{{ Sunlight syntax highlighting formatting configurations
|
54
|
+
|
55
|
+
# Format code using Sunlight's syntax highlighting. This assumes the HTML
|
56
|
+
# will include and invoke Sunlight's Javascript file which does the
|
57
|
+
# highlighting on the fly inside the DOM, instead of pre-computing it when
|
58
|
+
# splitting the file.
|
59
|
+
FORMAT_CODE_SUNLIGHT = lambda do |syntax|
|
60
|
+
return Highlighting.sunlight_code_format(syntax)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Return a configuration for highlighting a specific syntax using Sunlight.
|
64
|
+
def self.sunlight_code_format(syntax)
|
65
|
+
return {
|
66
|
+
"formatters" => {
|
67
|
+
"#{syntax}_code" => "Sunlight.lines_to_html(lines, '#{syntax}')",
|
68
|
+
},
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
# }}}
|
73
|
+
|
74
|
+
# {{{ Chunk splitting configurations
|
75
|
+
|
76
|
+
# Group lines into chunks using VIM-style "{{{"/"}}}" region designations.
|
77
|
+
# Assumes other configurations handle the actual content lines.
|
78
|
+
CHUNK_BY_VIM_REGIONS = {
|
79
|
+
"formatters" => {
|
80
|
+
"begin_chunk" => "[]",
|
81
|
+
"end_chunk" => "[]",
|
82
|
+
"nested_chunk" => "Formatter.nested_chunk_lines_to_html(lines)",
|
83
|
+
},
|
84
|
+
"syntax" => {
|
85
|
+
"patterns" => {
|
86
|
+
"begin_chunk" => { "regexp" => "^(\\s*)\\W*\\{\\{\\{\\s*(.*?)\\s*$" },
|
87
|
+
"end_chunk" => { "regexp" => "^(\\s*)\\W*\\}\\}\\}\\s*(.*?)\\s*$" },
|
88
|
+
},
|
89
|
+
"states" => {
|
90
|
+
"start" => {
|
91
|
+
"transitions" => [
|
92
|
+
{ "pattern" => "begin_chunk" },
|
93
|
+
{ "pattern" => "end_chunk" },
|
94
|
+
[],
|
95
|
+
],
|
96
|
+
},
|
97
|
+
},
|
98
|
+
},
|
99
|
+
}
|
100
|
+
|
101
|
+
# }}}
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
data/lib/codnar/data/contents.js
CHANGED
@@ -30,7 +30,8 @@ function contents_lists() {
|
|
30
30
|
var container;
|
31
31
|
var indices = [];
|
32
32
|
var h_elements = all_h_elements();
|
33
|
-
for (var e in h_elements)
|
33
|
+
/* Using "for (var e in h_elements)" is too sensitive to other libraries */
|
34
|
+
for (var e = 0; e < h_elements.length; e++) {
|
34
35
|
h = h_elements[e];
|
35
36
|
var level = h.tagName.substring(1, 2) - 1;
|
36
37
|
container = pop_container(container, indices, level);
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Codnar
|
2
|
+
|
3
|
+
# Convert Haddoc to HTML.
|
4
|
+
class Haddock
|
5
|
+
|
6
|
+
# Process a Haddock String and return the resulting HTML.
|
7
|
+
def self.to_html(haddock)
|
8
|
+
with_temporary_directory do |path|
|
9
|
+
write_temporary_file(path, haddock)
|
10
|
+
run_haddock(path)
|
11
|
+
html = read_html_file(path)
|
12
|
+
clean_html(html)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
|
18
|
+
# Run a block using a temporary directory, that is then removed. TODO: This
|
19
|
+
# should be in some more generic place.
|
20
|
+
def self.with_temporary_directory
|
21
|
+
path = create_temporary_directory
|
22
|
+
result = yield path
|
23
|
+
FileUtils.rm_rf(path)
|
24
|
+
return result
|
25
|
+
end
|
26
|
+
|
27
|
+
# Create a temporary directory to run Haddock in.
|
28
|
+
def self.create_temporary_directory
|
29
|
+
file = Tempfile.open("dir", ".")
|
30
|
+
path = file.path
|
31
|
+
File.delete(path)
|
32
|
+
Dir.mkdir(path)
|
33
|
+
return path
|
34
|
+
end
|
35
|
+
|
36
|
+
# Minimal header to insert before the Haddock String to trick Haddock into
|
37
|
+
# generating HTML from it.
|
38
|
+
HADDOCK_HEADER = <<-EOF.unindent
|
39
|
+
module Wrapper where
|
40
|
+
-- $doc
|
41
|
+
EOF
|
42
|
+
|
43
|
+
# Write the Haddock String into a wrapper Haskell file so we'll be able to
|
44
|
+
# run Haddock to generate HTML from it.
|
45
|
+
def self.write_temporary_file(path, haddock)
|
46
|
+
File.open(path + "/wrapper.hs", "w") do |file|
|
47
|
+
file.write(HADDOCK_HEADER)
|
48
|
+
file.write("-- " + haddock.gsub("\n", "\n-- "))
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Run Haddock to convert the wrapper Haskell file into HTML documentation.
|
53
|
+
def self.run_haddock(path)
|
54
|
+
system("cd #{path} && haddock --html wrapper.hs > haddock.out 2>&1")
|
55
|
+
end
|
56
|
+
|
57
|
+
# Read the HTML generated by Haddock.
|
58
|
+
def self.read_html_file(path)
|
59
|
+
return File.read(path + "/Wrapper.html")
|
60
|
+
end
|
61
|
+
|
62
|
+
# Extract the clean generated HTML from Haddock's output.
|
63
|
+
def self.clean_html(html)
|
64
|
+
html.gsub!("\r\n", "\n")
|
65
|
+
html.sub!(/.*<div class="doc">/m, '')
|
66
|
+
html.sub!(/<\/div><\/div><\/div><div id="footer">.*/m, "\n")
|
67
|
+
return html
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
@@ -57,6 +57,12 @@ module Codnar
|
|
57
57
|
::Rake::Task.define_task(:clean => "clean_codnar")
|
58
58
|
end
|
59
59
|
|
60
|
+
# For some reason, <tt>include ::Rake::DSL</tt> doesn't give us this and
|
61
|
+
# life is too short...
|
62
|
+
def self.desc(description)
|
63
|
+
::Rake.application.last_description = description
|
64
|
+
end
|
65
|
+
|
60
66
|
# Connect the task for splitting a single source file to the common task
|
61
67
|
# of splitting all source files.
|
62
68
|
def self.connect_common_tasks(output)
|
data/lib/codnar/scanner.rb
CHANGED
@@ -34,7 +34,9 @@ module Codnar
|
|
34
34
|
# - The pattern groups field can be ommitted or contain +nil+ if it is
|
35
35
|
# equal to [ "indentation", "payload" ].
|
36
36
|
# - The kind field of a transition can be ommitted; by default it is
|
37
|
-
# assumed to be identical to the pattern kind.
|
37
|
+
# assumed to be identical to the pattern kind. If it ends up +nil+, this
|
38
|
+
# indicates that there's no kind assigned by the pattern, and the current
|
39
|
+
# line should be classified again by the next state.
|
38
40
|
# - The next state of a transition can be ommitted; by default it is
|
39
41
|
# assumed to be identical to the containing state.
|
40
42
|
# - The start state can be ommitted; by default it is assumed to be named
|
@@ -113,11 +115,21 @@ module Codnar
|
|
113
115
|
|
114
116
|
# {{{ Scanner state shorthands
|
115
117
|
|
118
|
+
# A pattern that matches any line and extracts no data; is meant to be used
|
119
|
+
# for catch-all transitions that transfer the scanning to a different
|
120
|
+
# state. It is used if no explicit pattern is specified in a transition
|
121
|
+
# (that is, you can think of this as the +nil+ pattern).
|
122
|
+
CATCH_ALL_PATTERN = {
|
123
|
+
"kind" => nil,
|
124
|
+
"groups" => [],
|
125
|
+
"regexp" => //
|
126
|
+
}
|
127
|
+
|
116
128
|
# Expand all the shorthands used in the state.
|
117
129
|
def expand_state_shorthands(name, state)
|
118
130
|
fill_name(name, state, "State")
|
119
131
|
state.transitions.each do |transition|
|
120
|
-
pattern = transition.pattern = lookup(@syntax.patterns, "pattern", transition.pattern)
|
132
|
+
pattern = transition.pattern = lookup(@syntax.patterns, "pattern", transition.pattern || CATCH_ALL_PATTERN)
|
121
133
|
transition.kind ||= pattern.andand.kind
|
122
134
|
transition.next_state = lookup(@syntax.states, "state", transition.next_state || state)
|
123
135
|
end
|
@@ -146,10 +158,21 @@ module Codnar
|
|
146
158
|
|
147
159
|
# Scan the next file line.
|
148
160
|
def scan_line(line)
|
161
|
+
until state_classified_line(line)
|
162
|
+
# Do nothing
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
# Scan the current line using the current state transitions. Return true if
|
167
|
+
# the line was classified, of false if we need to try and classify it again
|
168
|
+
# using the updated (next) state.
|
169
|
+
def state_classified_line(line)
|
149
170
|
@state.transitions.each do |transition|
|
150
|
-
|
171
|
+
match = transition.pattern.andand.regexp.andand.match(line) if transition.next_state
|
172
|
+
return classify_matching_line(line, transition, match) if match
|
151
173
|
end
|
152
|
-
|
174
|
+
classify_error_line(line, @state.name)
|
175
|
+
return true
|
153
176
|
end
|
154
177
|
|
155
178
|
# }}}
|
@@ -157,15 +180,15 @@ module Codnar
|
|
157
180
|
# {{{ Scanner line processing
|
158
181
|
|
159
182
|
# Handle a file line, only if it matches the pattern.
|
160
|
-
def classify_matching_line(line, transition)
|
161
|
-
|
162
|
-
|
163
|
-
|
183
|
+
def classify_matching_line(line, transition, match)
|
184
|
+
@state = transition.next_state
|
185
|
+
kind = transition.kind
|
186
|
+
return false unless kind # A +nil+ kind indicates the next state will classify the line.
|
187
|
+
@lines << Scanner.extracted_groups(match, transition.pattern.groups || []).update({
|
164
188
|
"line" => line,
|
165
|
-
"kind" =>
|
189
|
+
"kind" => kind,
|
166
190
|
"number" => @errors.line_number
|
167
191
|
})
|
168
|
-
@state = transition.next_state
|
169
192
|
return true
|
170
193
|
end
|
171
194
|
|
@@ -181,7 +204,7 @@ module Codnar
|
|
181
204
|
end
|
182
205
|
|
183
206
|
# Handle a file line that couldn't be classified.
|
184
|
-
def
|
207
|
+
def classify_error_line(line, state_name)
|
185
208
|
@lines << {
|
186
209
|
"line" => line,
|
187
210
|
"indentation" => line.indentation,
|
@@ -5,388 +5,10 @@ module Codnar
|
|
5
5
|
# Application.
|
6
6
|
module Configuration
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
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, Codnar::RDoc, '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, Codnar::Markdown, 'markdown')",
|
51
|
-
"unindented_html" => "Formatter.unindented_lines_to_html(lines)",
|
52
|
-
}
|
53
|
-
)
|
54
|
-
|
55
|
-
# "Split" a documentation file containing a GraphViz diagram.
|
56
|
-
SPLIT_GRAPHVIZ_DOCUMENTATION = SPLIT_HTML_DOCUMENTATION.deep_merge(
|
57
|
-
"formatters" => {
|
58
|
-
"doc" => "Formatter.markup_lines_to_html(lines, Codnar::GraphViz, 'graphviz')",
|
59
|
-
"unindented_html" => "Formatter.unindented_lines_to_html(lines)",
|
60
|
-
}
|
61
|
-
)
|
62
|
-
|
63
|
-
# }}}
|
64
|
-
|
65
|
-
# {{{ Source code lines classification configurations
|
66
|
-
|
67
|
-
# Classify all lines as source code of some syntax (kind). This doesn't
|
68
|
-
# distinguish between comment and code lines; to do that, you need to
|
69
|
-
# combine this with comment classification configuration(s). Also, it just
|
70
|
-
# formats the lines in an HTML +pre+ element, without any syntax
|
71
|
-
# highlighting; to do that, you need to combine this with syntax
|
72
|
-
# highlighting formatting configuration(s).
|
73
|
-
CLASSIFY_SOURCE_CODE = lambda do |syntax|
|
74
|
-
return {
|
75
|
-
"formatters" => {
|
76
|
-
"#{syntax}_code" => "Formatter.lines_to_pre_html(lines, :class => :code)",
|
77
|
-
},
|
78
|
-
"syntax" => {
|
79
|
-
"patterns" => {
|
80
|
-
"#{syntax}_code" => { "regexp" => "^(\\s*)(.*)$" },
|
81
|
-
},
|
82
|
-
"states" => {
|
83
|
-
"start" => {
|
84
|
-
"transitions" => [
|
85
|
-
{ "pattern" => "#{syntax}_code" },
|
86
|
-
],
|
87
|
-
},
|
88
|
-
},
|
89
|
-
},
|
90
|
-
}
|
91
|
-
end
|
92
|
-
|
93
|
-
# }}}
|
94
|
-
|
95
|
-
# {{{ Nested foreign syntax code islands configurations
|
96
|
-
|
97
|
-
# Allow for comments containing "((( <syntax>" and "))) <syntax>" to
|
98
|
-
# designate nested islands of foreign syntax inside the normal code. The
|
99
|
-
# designator comment lines are always treated as part of the surrounding
|
100
|
-
# code, not as part of the nested foreign syntax code. There is no further
|
101
|
-
# classification of the nested foreign syntax code. Therefore, the nested
|
102
|
-
# code is not examined for begin/end chunk markers. Likewise, the nested
|
103
|
-
# code may not contain deeper nested code using a third syntax.
|
104
|
-
CLASSIFY_NESTED_CODE = lambda do |outer_syntax, inner_syntax|
|
105
|
-
{
|
106
|
-
"syntax" => {
|
107
|
-
"patterns" => {
|
108
|
-
"start_#{inner_syntax}_in_#{outer_syntax}" =>
|
109
|
-
{ "regexp" => "^(\\s*)(.*\\(\\(\\(\\s*#{inner_syntax}.*)$" },
|
110
|
-
"end_#{inner_syntax}_in_#{outer_syntax}" =>
|
111
|
-
{ "regexp" => "^(\\s*)(.*\\)\\)\\)\\s*#{inner_syntax}.*)$" },
|
112
|
-
"#{inner_syntax}_in_#{outer_syntax}" =>
|
113
|
-
{ "regexp" => "^(\\s*)(.*)$" },
|
114
|
-
},
|
115
|
-
"states" => {
|
116
|
-
"start" => {
|
117
|
-
"transitions" => [
|
118
|
-
{ "pattern" => "start_#{inner_syntax}_in_#{outer_syntax}",
|
119
|
-
"kind" => "#{outer_syntax}_code",
|
120
|
-
"next_state" => "#{inner_syntax}_in_#{outer_syntax}" },
|
121
|
-
[],
|
122
|
-
],
|
123
|
-
},
|
124
|
-
"#{inner_syntax}_in_#{outer_syntax}" => {
|
125
|
-
"transitions" => [
|
126
|
-
{ "pattern" => "end_#{inner_syntax}_in_#{outer_syntax}",
|
127
|
-
"kind" => "#{outer_syntax}_code",
|
128
|
-
"next_state" => "start" },
|
129
|
-
{ "pattern" => "#{inner_syntax}_in_#{outer_syntax}",
|
130
|
-
"kind" => "#{inner_syntax}_code" },
|
131
|
-
],
|
132
|
-
},
|
133
|
-
},
|
134
|
-
},
|
135
|
-
}
|
136
|
-
end
|
137
|
-
|
138
|
-
# }}}
|
139
|
-
|
140
|
-
# {{{ Simple comment classification configurations
|
141
|
-
|
142
|
-
# Classify simple comment lines. It accepts a restricted format: each
|
143
|
-
# comment is expected to start with some exact prefix (e.g. "#" for shell
|
144
|
-
# style comments or "//" for C++ style comments). The following space, if
|
145
|
-
# any, is stripped from the payload. As a convenience, comment that starts
|
146
|
-
# with "!" is not taken to start a comment. This both protects the 1st line
|
147
|
-
# of shell scripts ("#!"), and also any other line you wish to avoid being
|
148
|
-
# treated as a comment.
|
149
|
-
#
|
150
|
-
# This configuration is typically complemented by an additional one
|
151
|
-
# specifying how to format the (stripped!) comments; by default they are
|
152
|
-
# just displayed as-is using an HTML +pre+ element, which isn't very
|
153
|
-
# useful.
|
154
|
-
CLASSIFY_SIMPLE_COMMENTS = lambda do |prefix|
|
155
|
-
return Configuration.simple_comments(prefix)
|
156
|
-
end
|
157
|
-
|
158
|
-
# Classify simple shell ("#") comment lines.
|
159
|
-
CLASSIFY_SHELL_COMMENTS = lambda do
|
160
|
-
return Configuration.simple_comments("#")
|
161
|
-
end
|
162
|
-
|
163
|
-
# Classify simple C++ ("//") comment lines.
|
164
|
-
CLASSIFY_CPP_COMMENTS = lambda do
|
165
|
-
return Configuration.simple_comments("//")
|
166
|
-
end
|
167
|
-
|
168
|
-
# Configuration for classifying lines to comments and code based on a
|
169
|
-
# simple prefix (e.g. "#" for shell style comments or "//" for C++ style
|
170
|
-
# comments).
|
171
|
-
def self.simple_comments(prefix)
|
172
|
-
return {
|
173
|
-
"syntax" => {
|
174
|
-
"patterns" => {
|
175
|
-
"comment_#{prefix}" => { "regexp" => "^(\\s*)#{prefix}(?!!)\\s?(.*)$" },
|
176
|
-
},
|
177
|
-
"states" => {
|
178
|
-
"start" => {
|
179
|
-
"transitions" => [
|
180
|
-
{ "pattern" => "comment_#{prefix}", "kind" => "comment" },
|
181
|
-
[]
|
182
|
-
],
|
183
|
-
},
|
184
|
-
},
|
185
|
-
},
|
186
|
-
}
|
187
|
-
end
|
188
|
-
|
189
|
-
# }}}
|
190
|
-
|
191
|
-
# {{{ Complex comment classification configurations
|
192
|
-
|
193
|
-
# Classify complex comment lines. It accepts a restricted format: each
|
194
|
-
# comment is expected to start with some exact prefix (e.g. "/*" for C
|
195
|
-
# style comments or "<!--" for HTML style comments). The following space,
|
196
|
-
# if any, is stripped from the payload. Following lines are also considered
|
197
|
-
# comments; a leading inner line prefix (e.g., " *" for C style comments or
|
198
|
-
# " -" for HTML style comments) with an optional following space are
|
199
|
-
# stripped from the payload. Finally, a line containing some exact suffix
|
200
|
-
# (e.g. "*/" for C style comments, or "-->" for HTML style comments) ends
|
201
|
-
# the comment. A one line comment format is also supported containing the
|
202
|
-
# prefix, the payload, and the suffix. As a convenience, comment that
|
203
|
-
# starts with "!" is not taken to start a comment. This allows protecting
|
204
|
-
# comment block you wish to avoid being classified as a comment.
|
205
|
-
#
|
206
|
-
# This configuration is typically complemented by an additional one
|
207
|
-
# specifying how to format the (stripped!) comments; by default they are
|
208
|
-
# just displayed as-is using an HTML +pre+ element, which isn't very
|
209
|
-
# useful.
|
210
|
-
CLASSIFY_COMPLEX_COMMENTS = lambda do |prefix, inner, suffix|
|
211
|
-
return Configuration.complex_comments(prefix, inner, suffix)
|
212
|
-
end
|
213
|
-
|
214
|
-
# Classify complex C ("/*", " *", " */") style comments.
|
215
|
-
CLASSIFY_C_COMMENTS = lambda do
|
216
|
-
# Since the prefix/inner/suffix passed to the configuration are regexps,
|
217
|
-
# we need to escape special characters such as "*".
|
218
|
-
return Configuration.complex_comments("/\\*", " \\*", " \\*/")
|
219
|
-
end
|
220
|
-
|
221
|
-
# Classify complex HTML ("<!--", " -", "-->") style comments.
|
222
|
-
CLASSIFY_HTML_COMMENTS = lambda do
|
223
|
-
return Configuration.complex_comments("<!--", " -", "-->")
|
224
|
-
end
|
225
|
-
|
226
|
-
# Configuration for classifying lines to comments and code based on a
|
227
|
-
# complex start prefix, inner line prefix and final suffix (e.g., "/*", "
|
228
|
-
# *", " */" for C-style comments or "<!--", " -", "-->" for HTML style
|
229
|
-
# comments).
|
230
|
-
def self.complex_comments(prefix, inner, suffix)
|
231
|
-
return {
|
232
|
-
"syntax" => {
|
233
|
-
"patterns" => {
|
234
|
-
"comment_prefix_#{prefix}" => { "regexp" => "^(\\s*)#{prefix}(?!!)\\s?(.*)$" },
|
235
|
-
"comment_inner_#{inner}" => { "regexp" => "^(\\s*)#{inner}\\s?(.*)$" },
|
236
|
-
"comment_suffix_#{suffix}" => { "regexp" => "^(\\s*)#{suffix}\\s*$" },
|
237
|
-
"comment_line_#{prefix}_#{suffix}" => { "regexp" => "^(\\s*)#{prefix}(?!!)\s?(.*?)\s*#{suffix}\\s*$" },
|
238
|
-
},
|
239
|
-
"states" => {
|
240
|
-
"start" => {
|
241
|
-
"transitions" => [
|
242
|
-
{ "pattern" => "comment_line_#{prefix}_#{suffix}",
|
243
|
-
"kind" => "comment" },
|
244
|
-
{ "pattern" => "comment_prefix_#{prefix}",
|
245
|
-
"kind" => "comment",
|
246
|
-
"next_state" => "comment_#{prefix}" },
|
247
|
-
[],
|
248
|
-
],
|
249
|
-
},
|
250
|
-
"comment_#{prefix}" => {
|
251
|
-
"transitions" => [
|
252
|
-
{ "pattern" => "comment_suffix_#{suffix}",
|
253
|
-
"kind" => "comment",
|
254
|
-
"next_state" => "start" },
|
255
|
-
{ "pattern" => "comment_inner_#{inner}",
|
256
|
-
"kind" => "comment" },
|
257
|
-
],
|
258
|
-
},
|
259
|
-
},
|
260
|
-
},
|
261
|
-
}
|
262
|
-
end
|
263
|
-
|
264
|
-
# }}}
|
265
|
-
|
266
|
-
# {{{ Comment formatting configurations
|
267
|
-
|
268
|
-
# Format comments as HTML pre elements. Is used to complement a
|
269
|
-
# configuration that classifies some lines as +comment+.
|
270
|
-
FORMAT_PRE_COMMENTS = {
|
271
|
-
"formatters" => {
|
272
|
-
"comment" => "Formatter.lines_to_pre_html(lines, :class => :comment)",
|
273
|
-
},
|
274
|
-
}
|
275
|
-
|
276
|
-
# Format comments that use the RDoc notation. Is used to complement a
|
277
|
-
# configuration that classifies some lines as +comment+.
|
278
|
-
FORMAT_RDOC_COMMENTS = {
|
279
|
-
"formatters" => {
|
280
|
-
"comment" => "Formatter.markup_lines_to_html(lines, Codnar::RDoc, 'rdoc')",
|
281
|
-
"unindented_html" => "Formatter.unindented_lines_to_html(lines)",
|
282
|
-
},
|
283
|
-
}
|
284
|
-
|
285
|
-
# Format comments that use the Markdown notation. Is used to complement a
|
286
|
-
# configuration that classifies some lines as +comment+.
|
287
|
-
FORMAT_MARKDOWN_COMMENTS = {
|
288
|
-
"formatters" => {
|
289
|
-
"comment" => "Formatter.markup_lines_to_html(lines, Markdown, 'markdown')",
|
290
|
-
"unindented_html" => "Formatter.unindented_lines_to_html(lines)",
|
291
|
-
},
|
292
|
-
}
|
293
|
-
|
294
|
-
# }}}
|
295
|
-
|
296
|
-
# {{{ GVim syntax highlighting formatting configurations
|
297
|
-
|
298
|
-
# Format code using GVim's syntax highlighting, using explicit HTML
|
299
|
-
# constructs. Assumes some previous configuration already classified the
|
300
|
-
# code lines.
|
301
|
-
FORMAT_CODE_GVIM_HTML = lambda do |syntax|
|
302
|
-
return Configuration.klass_code_format('GVim', syntax, "[]")
|
303
|
-
end
|
304
|
-
|
305
|
-
# Format code using GVim's syntax highlighting, using CSS classes instead
|
306
|
-
# of explicit font and color styles. Assumes some previous configuration
|
307
|
-
# already classified the code lines.
|
308
|
-
FORMAT_CODE_GVIM_CSS = lambda do |syntax|
|
309
|
-
return Configuration.klass_code_format('GVim', syntax, "[ '+:let html_use_css=1' ]")
|
310
|
-
end
|
311
|
-
|
312
|
-
# Return a configuration for highlighting a specific syntax using GVim.
|
313
|
-
def self.klass_code_format(klass, syntax, options)
|
314
|
-
return {
|
315
|
-
"formatters" => {
|
316
|
-
"#{syntax}_code" => "#{klass}.lines_to_html(lines, '#{syntax}', #{options})",
|
317
|
-
},
|
318
|
-
}
|
319
|
-
end
|
320
|
-
|
321
|
-
# }}}
|
322
|
-
|
323
|
-
# {{{ CodeRay syntax highlighting formatting configurations
|
324
|
-
|
325
|
-
# Format code using CodeRay's syntax highlighting, using explicit HTML
|
326
|
-
# constructs. Assumes some previous configuration already classified the
|
327
|
-
# code lines.
|
328
|
-
FORMAT_CODE_CODERAY_HTML = lambda do |syntax|
|
329
|
-
return Configuration.klass_code_format('CodeRay', syntax, "{}")
|
330
|
-
end
|
331
|
-
|
332
|
-
# Format code using CodeRay's syntax highlighting, using CSS classes
|
333
|
-
# instead of explicit font and color styles. Assumes some previous
|
334
|
-
# configuration already classified the code lines.
|
335
|
-
FORMAT_CODE_CODERAY_CSS = lambda do |syntax|
|
336
|
-
return Configuration.klass_code_format('CodeRay', syntax, "{ :css => :class }")
|
337
|
-
end
|
338
|
-
|
339
|
-
# }}}
|
340
|
-
|
341
|
-
# {{{ Sunlight syntax highlighting formatting configurations
|
342
|
-
|
343
|
-
# Format code using Sunlight's syntax highlighting. This assumes the HTML
|
344
|
-
# will include and invoke Sunlight's Javascript file which does the
|
345
|
-
# highlighting on the fly inside the DOM, instead of pre-computing it when
|
346
|
-
# splitting the file.
|
347
|
-
FORMAT_CODE_SUNLIGHT = lambda do |syntax|
|
348
|
-
return Configuration.sunlight_code_format(syntax)
|
349
|
-
end
|
350
|
-
|
351
|
-
# Return a configuration for highlighting a specific syntax using Sunlight.
|
352
|
-
def self.sunlight_code_format(syntax)
|
353
|
-
return {
|
354
|
-
"formatters" => {
|
355
|
-
"#{syntax}_code" => "Sunlight.lines_to_html(lines, '#{syntax}')",
|
356
|
-
},
|
357
|
-
}
|
358
|
-
end
|
359
|
-
|
360
|
-
# }}}
|
361
|
-
|
362
|
-
# {{{ Chunk splitting configurations
|
363
|
-
|
364
|
-
# Group lines into chunks using VIM-style "{{{"/"}}}" region designations.
|
365
|
-
# Assumes other configurations handle the actual content lines.
|
366
|
-
CHUNK_BY_VIM_REGIONS = {
|
367
|
-
"formatters" => {
|
368
|
-
"begin_chunk" => "[]",
|
369
|
-
"end_chunk" => "[]",
|
370
|
-
"nested_chunk" => "Formatter.nested_chunk_lines_to_html(lines)",
|
371
|
-
},
|
372
|
-
"syntax" => {
|
373
|
-
"patterns" => {
|
374
|
-
"begin_chunk" => { "regexp" => "^(\\s*)\\W*\\{\\{\\{\\s*(.*?)\\s*$" },
|
375
|
-
"end_chunk" => { "regexp" => "^(\\s*)\\W*\\}\\}\\}\\s*(.*?)\\s*$" },
|
376
|
-
},
|
377
|
-
"states" => {
|
378
|
-
"start" => {
|
379
|
-
"transitions" => [
|
380
|
-
{ "pattern" => "begin_chunk" },
|
381
|
-
{ "pattern" => "end_chunk" },
|
382
|
-
[],
|
383
|
-
],
|
384
|
-
},
|
385
|
-
},
|
386
|
-
},
|
387
|
-
}
|
388
|
-
|
389
|
-
# }}}
|
8
|
+
include Documentation
|
9
|
+
include Code
|
10
|
+
include Comments
|
11
|
+
include Highlighting
|
390
12
|
|
391
13
|
end
|
392
14
|
|