hoe-manns 1.0.0

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.
Files changed (67) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data/.autotest +25 -0
  4. data/.gemnasium.yml +5 -0
  5. data/.idea/hoe-manns.iml +91 -0
  6. data/.idea/misc.xml +14 -0
  7. data/.idea/modules.xml +8 -0
  8. data/.idea/vcs.xml +6 -0
  9. data/.idea/workspace.xml +795 -0
  10. data/.index +173 -0
  11. data/.rspec +2 -0
  12. data/.rubocop.yml +39 -0
  13. data/.scrutinizer.yml +17 -0
  14. data/.travis.yml +28 -0
  15. data/CODE_OF_CONDUCT.md +17 -0
  16. data/CONTRIBUTING.md +33 -0
  17. data/Gemfile +37 -0
  18. data/Gemfile.lock +186 -0
  19. data/History.rdoc +7 -0
  20. data/LICENSE.rdoc +24 -0
  21. data/Manifest.txt +62 -0
  22. data/README.rdoc +114 -0
  23. data/Rakefile +104 -0
  24. data/VERSION +1 -0
  25. data/config.reek +111 -0
  26. data/etc/hoe-manns.cfg +1 -0
  27. data/lib/hoe/manns.rb +128 -0
  28. data/manual/layouts/default.erb +87 -0
  29. data/manual/lib/api-filter.rb +96 -0
  30. data/manual/lib/editorial-filter.rb +59 -0
  31. data/manual/lib/examples-filter.rb +230 -0
  32. data/manual/lib/links-filter.rb +111 -0
  33. data/manual/resources/css/manual.css +764 -0
  34. data/manual/resources/css/reset.css +112 -0
  35. data/manual/resources/fonts/GraublauWeb.otf +0 -0
  36. data/manual/resources/fonts/GraublauWebBold.otf +0 -0
  37. data/manual/resources/fonts/Inconsolata.otf +0 -0
  38. data/manual/resources/images/arrow_225_small.png +0 -0
  39. data/manual/resources/images/arrow_315_small.png +0 -0
  40. data/manual/resources/images/arrow_skip.png +0 -0
  41. data/manual/resources/images/cc-by.png +0 -0
  42. data/manual/resources/images/dialog-error.png +0 -0
  43. data/manual/resources/images/dialog-information.png +0 -0
  44. data/manual/resources/images/dialog-warning.png +0 -0
  45. data/manual/resources/images/emblem-important.png +0 -0
  46. data/manual/resources/images/help.png +0 -0
  47. data/manual/resources/images/information.png +0 -0
  48. data/manual/resources/images/magnifier.png +0 -0
  49. data/manual/resources/images/magnifier_left.png +0 -0
  50. data/manual/resources/images/page_white_code.png +0 -0
  51. data/manual/resources/images/page_white_copy.png +0 -0
  52. data/manual/resources/images/printer.png +0 -0
  53. data/manual/resources/images/question.png +0 -0
  54. data/manual/resources/images/scripts_code.png +0 -0
  55. data/manual/resources/images/wrap.png +0 -0
  56. data/manual/resources/images/wrapping.png +0 -0
  57. data/manual/resources/js/jquery-1.4.4.min.js +167 -0
  58. data/manual/resources/js/manual.js +30 -0
  59. data/manual/resources/js/sh.js +580 -0
  60. data/manual/resources/swf/clipboard.swf +0 -0
  61. data/manual/src/apidocs.page +17 -0
  62. data/manual/src/index.page +70 -0
  63. data/test/manns_spec.rb +54 -0
  64. data/test/spec_helper.rb +16 -0
  65. data.tar.gz.sig +0 -0
  66. metadata +542 -0
  67. metadata.gz.sig +0 -0
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # A manual filter to highlight content that needs editorial help.
4
+ #
5
+ # Authors:
6
+ # * Michael Granger <ged@FaerieMUD.org>
7
+ #
8
+ #
9
+
10
+
11
+
12
+ ### A filter for making editorial marks in manual content.
13
+ ###
14
+ ### Editorial marks are XML processing instructions. There are several available types of
15
+ ### marks:
16
+ ###
17
+ ### <?ed "This is an editor's note." ?>
18
+ ### <?ed verify:"this content needs checking or verification" ?>
19
+ ###
20
+ class Hoe::ManualGen::EditorialFilter < Hoe::ManualGen::PageFilter
21
+
22
+ # PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
23
+ LinkPI = %r{
24
+ <\?
25
+ ed # Instruction Target
26
+ \s+
27
+ (\w+?) # type of editorial mark [$1]
28
+ :? # optional colon
29
+ "
30
+ (.*?) # content that should be edited [$2]
31
+ "
32
+ \s*
33
+ \?>
34
+ }x
35
+
36
+
37
+ ######
38
+ public
39
+ ######
40
+
41
+ ### Process the given +source+ for <?ed ... ?> processing-instructions
42
+ def process( source, page, metadata )
43
+ return source.gsub( LinkPI ) do |match|
44
+ # Grab the tag values
45
+ mark_type = $1
46
+ content = $2
47
+
48
+ self.generate_mark( page, mark_type, content )
49
+ end
50
+ end
51
+
52
+
53
+ ### Create an HTML fragment from the parsed LinkPI.
54
+ def generate_mark( current_page, mark_type, content )
55
+ return "%%(editorial %s-mark)%s%%" % [ mark_type, content ]
56
+ end
57
+
58
+
59
+ end
@@ -0,0 +1,230 @@
1
+ #!/usr/bin/ruby
2
+ #encoding: utf-8
3
+ #
4
+ # A collection of standard filters for the manual generation tasklib.
5
+ #
6
+ # Authors:
7
+ # Michael Granger <ged@FaerieMUD.org>
8
+ #
9
+ #
10
+
11
+ # Dependencies deferred until #initialize
12
+
13
+
14
+
15
+ ### A filter for inline example code or command-line sessions -- does
16
+ ### syntax-checking for some languages and captioning.
17
+ ###
18
+ ### Examples are enclosed in XML processing instructions like so:
19
+ ###
20
+ ### <?example {language: ruby, testable: true, caption: "A fine example"} ?>
21
+ ### a = 1
22
+ ### puts a
23
+ ### <?end example ?>
24
+ ###
25
+ ### This will be pulled out into a preformatted section in the HTML,
26
+ ### highlighted as Ruby source, checked for valid syntax, and annotated with
27
+ ### the specified caption. Valid keys in the example PI are:
28
+ ###
29
+ ### language::
30
+ ### Specifies which (machine) language the example is in.
31
+ ### testable::
32
+ ### If set and there is a testing function for the given language, run it and append
33
+ ### any errors to the output.
34
+ ### caption::
35
+ ### A small blurb to put below the pulled-out example in the HTML.
36
+ class Hoe::ManualGen::ExamplesFilter < Hoe::ManualGen::PageFilter
37
+
38
+ DEFAULTS = {
39
+ :language => :ruby,
40
+ :line_numbers => :inline,
41
+ :tab_width => 4,
42
+ :hint => :debug,
43
+ :testable => false,
44
+ }
45
+
46
+ # PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
47
+ ExamplePI = %r{
48
+ <\?
49
+ example # Instruction Target
50
+ (?: # Optional instruction body
51
+ \s+
52
+ ((?: # [$1]
53
+ [^?]* # Run of anything but a question mark
54
+ | # -or-
55
+ \?(?!>) # question mark not followed by a closing angle bracket
56
+ )*)
57
+ )?
58
+ \?>
59
+ }x
60
+
61
+ EndPI = %r{ <\? end (?: \s+ example )? \s* \?> }x
62
+
63
+
64
+ ### Defer loading of dependenies until the filter is loaded
65
+ def initialize( *args )
66
+ require 'pathname'
67
+ require 'strscan'
68
+ require 'yaml'
69
+ require 'rcodetools/xmpfilter'
70
+ require 'digest/md5'
71
+ require 'tmpdir'
72
+ require 'erb'
73
+ end
74
+
75
+
76
+ ######
77
+ public
78
+ ######
79
+
80
+ ### Process the given +source+ for <?example ... ?> processing-instructions, calling out
81
+ def process( source, page, metadata )
82
+ scanner = StringScanner.new( source )
83
+
84
+ buffer = ''
85
+ until scanner.eos?
86
+ startpos = scanner.pos
87
+
88
+ # If we find an example
89
+ if scanner.skip_until( ExamplePI )
90
+ contents = ''
91
+
92
+ # Append the interstitial content to the buffer
93
+ if ( scanner.pos - startpos > scanner.matched.length )
94
+ offset = scanner.pos - scanner.matched.length - 1
95
+ buffer << scanner.string[ startpos..offset ]
96
+ end
97
+
98
+ # Append everything up to it to the buffer and save the contents of
99
+ # the tag
100
+ params = scanner[1]
101
+
102
+ # Now find the end of the example or complain
103
+ contentpos = scanner.pos
104
+ scanner.skip_until( EndPI ) or
105
+ raise "Unterminated example at line %d" %
106
+ [ scanner.string[0..scanner.pos].count("\n") ]
107
+
108
+ # Now build the example and append to the buffer
109
+ if ( scanner.pos - contentpos > scanner.matched.length )
110
+ offset = scanner.pos - scanner.matched.length - 1
111
+ contents = scanner.string[ contentpos..offset ]
112
+ end
113
+
114
+ trace "Processing with params: %p, contents: %p" % [ params, contents ]
115
+ buffer << self.process_example( params, contents, page )
116
+ else
117
+ break
118
+ end
119
+
120
+ end
121
+ buffer << scanner.rest
122
+ scanner.terminate
123
+
124
+ return buffer
125
+ end
126
+
127
+
128
+ ### Filter out 'example' macros, doing syntax highlighting, and running
129
+ ### 'testable' examples through a validation process appropriate to the
130
+ ### language the example is in.
131
+ def process_example( params, body, page )
132
+ options = self.parse_options( params )
133
+ caption = options.delete( :caption )
134
+ content = ''
135
+ lang = options.delete( :language ).to_s
136
+
137
+ # Test it if it's testable
138
+ if options[:testable]
139
+ content = test_content( body, lang, page )
140
+ else
141
+ content = body
142
+ end
143
+
144
+ # Strip trailing blank lines and syntax-highlight
145
+ content = highlight( content.strip, options, lang )
146
+ caption = %{<div class="caption">} + caption.to_s + %{</div>} if caption
147
+
148
+ return %{<notextile><div class="example #{lang}-example">%s%s</div></notextile>} %
149
+ [content, caption || '']
150
+ end
151
+
152
+
153
+ ### Parse an options hash for filtering from the given +args+, which can either
154
+ ### be a plain String, in which case it is assumed to be the name of the language the example
155
+ ### is in, or a Hash of configuration options.
156
+ def parse_options( args )
157
+ args = "{ #{args} }" unless args.strip[0] == ?{
158
+ args = YAML.load( args )
159
+
160
+ # Convert to Symbol keys and value
161
+ args.keys.each do |k|
162
+ newval = args.delete( k )
163
+ next if newval.nil? || (newval.respond_to?(:size) && newval.size == 0)
164
+ args[ k.to_sym ] = newval.respond_to?( :to_sym ) ? newval.to_sym : newval
165
+ end
166
+ return DEFAULTS.merge( args )
167
+ end
168
+
169
+
170
+ ### Test the given +content+ with a rule specific to the given +language+.
171
+ def test_content( body, language, page )
172
+ case language.to_sym
173
+ when :ruby
174
+ return self.test_ruby_content( body, page )
175
+
176
+ when :yaml
177
+ return self.test_yaml_content( body, page )
178
+
179
+ else
180
+ return body
181
+ end
182
+ end
183
+
184
+
185
+ ### Test the specified Ruby content for valid syntax
186
+ def test_ruby_content( source, page )
187
+ # $stderr.puts "Testing ruby content..."
188
+ libdir = Pathname.new( __FILE__ ).dirname.parent.parent.parent + 'lib'
189
+ extdir = Pathname.new( __FILE__ ).dirname.parent.parent.parent + 'ext'
190
+
191
+ options = Rcodetools::XMPFilter::INITIALIZE_OPTS.dup
192
+ options[:include_paths] |= [ libdir.to_s, extdir.to_s ]
193
+ options[:width] = 60
194
+
195
+ if page.config['example_prelude']
196
+ prelude = page.config['example_prelude']
197
+ trace " prepending prelude:\n#{prelude}"
198
+ source = prelude.strip + "\n" + source.strip
199
+ else
200
+ trace " no prelude; page config is: %p" % [ page.config ]
201
+ end
202
+
203
+ rval = Rcodetools::XMPFilter.run( source, options )
204
+
205
+ trace "test output: ", rval
206
+ return rval.join
207
+ rescue Exception => err
208
+ return "%s while testing: %s\n %s" %
209
+ [ err.class.name, err.message, err.backtrace.join("\n ") ]
210
+ end
211
+
212
+
213
+ ### Test the specified YAML content for valid syntax
214
+ def test_yaml_content( source, metadata )
215
+ YAML.load( source )
216
+ rescue YAML::Error => err
217
+ return "# Invalid YAML: " + err.message + "\n" + source
218
+ else
219
+ return source
220
+ end
221
+
222
+
223
+ ### Highlights the given +content+ in language +lang+.
224
+ def highlight( content, options, lang )
225
+ source = ERB::Util.html_escape( content )
226
+ return %Q{\n\n<pre class="brush:#{lang}">#{source}</pre>\n\n}
227
+ end
228
+
229
+ end
230
+
@@ -0,0 +1,111 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # A manual filter to generate links from the page catalog.
4
+ #
5
+ # Authors:
6
+ # * Michael Granger <ged@FaerieMUD.org>
7
+ # * Mahlon E. Smith <mahlon@martini.nu>
8
+ #
9
+ #
10
+
11
+
12
+ ### A filter for generating links from the page catalog. This allows you to refer to other pages
13
+ ### in the source and have them automatically updated as the structure of the manual changes.
14
+ ###
15
+ ### Links are XML processing instructions. Pages can be referenced in one of several ways:
16
+ ###
17
+ ### <?link Page Title ?>
18
+ ### <?link "click here":Page Title ?>
19
+ ### <?link Page Title #section_id ?>
20
+ ### <?link "click here":Page Title#section_id ?>
21
+ ###
22
+ ### This first form links to a page by title. Link text defaults to the page title unless an
23
+ ### optional quoted string is prepended. If you want to link to an anchor inside the page, include
24
+ ### its ID with a hash mark after the title.
25
+ ###
26
+ ### <?link path/to/Catalog.page ?>
27
+ ### <?link "click here":path/to/Catalog.page ?>
28
+ ### <?link path/to/Catalog.page#section_id ?>
29
+ ### <?link "click here":path/to/Catalog.page#section_id ?>
30
+ ###
31
+ ### The second form links to a page by its path relative to the base manual source directory.
32
+ ### Again, the link text defaults to the page title, or can be overriden via a prepended string,
33
+ ### and you can link into a page with an appended ID.
34
+ class Hoe::ManualGen::LinksFilter < Hoe::ManualGen::PageFilter
35
+
36
+ # PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
37
+ LinkPI = %r{
38
+ <\?
39
+ link # Instruction Target
40
+ \s+
41
+ (?:"
42
+ (.*?) # Optional link text [$1]
43
+ ":)?
44
+ (.*?) # Title or path [$2]
45
+ \s*
46
+ (\#\w+)? # Fragment [$3]
47
+ \s+
48
+ \?>
49
+ }x
50
+
51
+
52
+ ######
53
+ public
54
+ ######
55
+
56
+ ### Process the given +source+ for <?link ... ?> processing-instructions, calling out
57
+ def process( source, page, metadata )
58
+ return source.gsub( LinkPI ) do |match|
59
+ # Grab the tag values
60
+ link_text = $1
61
+ reference = $2
62
+ fragment = $3
63
+
64
+ self.generate_link( page, reference, link_text, fragment )
65
+ end
66
+ end
67
+
68
+
69
+ ### Create an HTML link fragment from the parsed LinkPI.
70
+ def generate_link( current_page, reference, link_text=nil, fragment=nil )
71
+
72
+ if other_page = self.find_linked_page( current_page, reference )
73
+ href_path = other_page.sourcefile.relative_path_from( current_page.sourcefile.dirname )
74
+ href = href_path.to_s.gsub( '.page', '.html' )
75
+
76
+ if link_text
77
+ return %{<a href="#{href}#{fragment}">#{link_text}</a>}
78
+ else
79
+ return %{<a href="#{href}#{fragment}">#{other_page.title}</a>}
80
+ end
81
+ else
82
+ link_text ||= reference
83
+ error_message = "Could not find a link for reference '%s'" % [ reference ]
84
+ $stderr.puts( error_message )
85
+ return %{<a href="#" title="#{error_message}" class="broken-link">#{link_text}</a>}
86
+ end
87
+ end
88
+
89
+
90
+ ### Lookup a page +reference+ in the catalog. +reference+ can be either a
91
+ ### path to the .page file, relative to the manual root path, or a page title.
92
+ ### Returns a matching Page object, or nil if no match is found.
93
+ def find_linked_page( current_page, reference )
94
+
95
+ catalog = current_page.catalog
96
+
97
+ # Lookup by page path
98
+ if reference =~ /\.page$/
99
+ return catalog.uri_index[ reference ]
100
+
101
+ # Lookup by page title
102
+ else
103
+ return catalog.title_index[ reference ]
104
+ end
105
+ end
106
+ end
107
+
108
+
109
+
110
+
111
+