ron 0.1 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -1,4 +1,8 @@
1
- ron -- the opposite of roff
1
+ ron(7) -- the opposite of roff
2
+ ==============================
3
+
4
+ DESCRIPTION
5
+ -----------
2
6
 
3
7
  Ron is a humane text format and toolchain for
4
8
  creating UNIX man pages -- and things that
@@ -19,17 +23,17 @@ format in more detail.
19
23
  INSTALL
20
24
  -------
21
25
 
22
- The easiest way to install ron is with
23
- rubygems:
26
+ Ron can be installed using rubygems:
24
27
 
25
- $ [sudo] gem install ron -s gems.gemcutter.org
28
+ $ [sudo] gem install ron
26
29
 
27
30
  Or, clone the git repository and install from
28
31
  source:
29
32
 
30
33
  $ git clone git://github.com/rtomayko/ron.git
31
34
  $ cd ron
32
- $ rake install
35
+ $ rake package
36
+ $ [sudo] rake install
33
37
 
34
38
  EXAMPLES
35
39
  --------
@@ -47,7 +51,7 @@ BASIC USAGE
47
51
  -----------
48
52
 
49
53
  To generate a roff man page from the included
50
- markdown.5.ron file and open it in man(1):
54
+ `markdown.5.ron` file and open it in man(1):
51
55
 
52
56
  $ ron -b man/markdown.5.ron
53
57
  building: man/markdown.5
data/Rakefile CHANGED
@@ -11,6 +11,13 @@ Rake::TestTask.new(:test) do |t|
11
11
  t.ruby_opts = ['-rubygems'] if defined? Gem
12
12
  end
13
13
 
14
+ # DOCS =================================================================
15
+
16
+ desc 'Build the manual'
17
+ task 'man' do
18
+ sh "ron -br5 --manual='Ron Manual' --organization='Ryan Tomayko' man/*.ron"
19
+ end
20
+
14
21
  # PACKAGING ============================================================
15
22
 
16
23
  require 'rubygems/specification'
data/bin/ron CHANGED
@@ -1,24 +1,37 @@
1
1
  #!/usr/bin/env ruby
2
- ## Usage: ron [ OPTIONS ] [ FILE ... ]
2
+ ## Usage: ron [ OPTIONS ] [ FILE ]
3
3
  ## ron --build FILE ...
4
4
  ## ron --install FILE ...
5
- ## ron --man FILE
6
- ## Convert ron file to roff or html.
5
+ ## ron --man FILE ...
6
+ ## Convert ron FILE to roff man page or HTML and write to standard
7
+ ## output. With no FILE, ron reads from standard input. The build,
8
+ ## install, and man forms accept multiple FILE arguments.
7
9
  ##
8
- ## Options
9
- ## -b, --build write output to files instead of to stdout
10
- ## -i, --install write manpage to MAN_HOME or system man path
11
- ## -m, --man show man page like man(1)
10
+ ## Modes:
11
+ ## --pipe write to standard output (default behavior)
12
+ ## -b, --build write to files instead of standard output
13
+ ## -i, --install write to file in MAN_HOME or system man path
14
+ ## -m, --man open man page like man(1)
12
15
  ##
13
- ## --roff generate roff/man text; this is the default behavior
14
- ## -5, --html generate HTML
16
+ ## Formats:
17
+ ## --roff generate roff/man text; this is the default behavior
18
+ ## -5, --html generate entire HTML page with layout
19
+ ## -f, --fragment generate HTML fragment instead of entire HTML page
15
20
  ##
16
- ## --help show this help message
21
+ ## Document attributes:
22
+ ## --date=DATE published date in YYYY-MM-DD format;
23
+ ## displayed bottom-center in footer
24
+ ## --manual=NAME name of the manual this document belongs to;
25
+ ## displayed top-center in header
26
+ ## --organization=NAME publishing group, organization, or individual;
27
+ ## displayed bottom-left in footer
28
+ ##
29
+ ## --help show this help message
17
30
  ##
18
- ## See the ron(2)
19
31
  require 'optparse'
20
32
 
21
33
  formats = []
34
+ options = {}
22
35
  build = false
23
36
  install = false
24
37
  man = false
@@ -38,12 +51,22 @@ end
38
51
 
39
52
  # parse command line options
40
53
  ARGV.options do |option|
41
- option.on("--roff") { formats << 'roff' }
42
- option.on("-5", "--html") { formats << 'html' }
54
+ # modes
55
+ option.on("--pipe") { }
43
56
  option.on("-b", "--build") { build = true }
44
57
  option.on("-i", "--install") { install = true }
45
58
  option.on("-m", "--man") { man = true }
46
59
 
60
+ # format options
61
+ option.on("-r", "--roff") { formats << 'roff' }
62
+ option.on("-5", "--html") { formats << 'html' }
63
+ option.on("-f", "--fragment") { formats << 'html_fragment' }
64
+
65
+ # manual attribute options
66
+ [:name, :section, :manual, :organization, :date].each do |option_attr|
67
+ option.on("--#{option_attr}=VALUE") { |val| options[option_attr] = val }
68
+ end
69
+
47
70
  option.on_tail("--help") { usage ; exit }
48
71
  option.parse!
49
72
  end
@@ -55,13 +78,19 @@ elsif ARGV.empty?
55
78
  ARGV.push '-'
56
79
  end
57
80
 
81
+ # turn the --date arg into
82
+ if options[:date]
83
+ options[:date] = Date.strptime(options[:date], '%Y-%m-%d')
84
+ end
85
+
58
86
  formats = ['roff'] if formats.empty?
87
+ formats.delete('html') if formats.include?('html_fragment')
59
88
  pid = nil
60
89
 
61
90
  require 'ron'
62
91
  wr = STDOUT
63
92
  ARGV.each do |file|
64
- doc = Ron.new(file) { file == '-' ? STDIN.read : File.read(file) }
93
+ doc = Ron.new(file, options) { file == '-' ? STDIN.read : File.read(file) }
65
94
 
66
95
  # setup the man pipeline if the --man option was specified
67
96
  if man && !build
@@ -79,11 +108,11 @@ ARGV.each do |file|
79
108
  formats.each do |format|
80
109
  output = doc.convert(format)
81
110
  if build
82
- path = doc.path(format)
111
+ path = doc.path_for(format)
83
112
  info "building: #{path}"
84
- File.open(path, 'wb') { |f| f.write(output) }
113
+ File.open(path, 'wb') { |f| f.puts(output) }
85
114
  else
86
- wr.write(output)
115
+ wr.puts(output)
87
116
  end
88
117
  end
89
118
 
data/lib/ron.rb CHANGED
@@ -3,13 +3,14 @@
3
3
  # install standard UNIX roff(7) formatted manpages or to generate
4
4
  # beautiful HTML manpages.
5
5
  module Ron
6
- VERSION = '0.1'
6
+ VERSION = '0.2'
7
7
 
8
8
  require 'ron/document'
9
9
  require 'ron/roff'
10
10
 
11
- # Create a new Ron::Document for the given ron file.
12
- def self.new(filename, &block)
13
- Document.new(filename, &block)
11
+ # Create a new Ron::Document for the given ron file. See
12
+ # Ron::Document.new for usage information.
13
+ def self.new(filename, attributes={}, &block)
14
+ Document.new(filename, attributes, &block)
14
15
  end
15
16
  end
@@ -1,60 +1,178 @@
1
+ require 'set'
1
2
  require 'nokogiri'
2
3
  require 'rdiscount'
3
4
  require 'ron/roff'
4
5
 
5
6
  module Ron
7
+ # The Document class can be used to load and inspect a ron document
8
+ # and to convert a ron document into other formats, like roff or
9
+ # HTML.
10
+ #
11
+ # Ron files may optionally follow the naming convention:
12
+ # "<name>.<section>.ron". The <name> and <section> are used in
13
+ # generated documentation unless overridden by the information
14
+ # extracted from the document's name section.
6
15
  class Document
7
- VERSION = '0.1'
8
- attr_reader :filename, :data, :basename, :name, :section, :tagline
16
+ attr_reader :path, :data
9
17
 
10
- def initialize(filename, &block)
11
- @filename = filename
18
+ # The man pages name: usually a single word name of
19
+ # a program or filename; displayed along with the section in
20
+ # the left and right portions of the header as well as the bottom
21
+ # right section of the footer.
22
+ attr_accessor :name
23
+
24
+ # The man page's section: a string whose first character
25
+ # is numeric; displayed in parenthesis along with the name.
26
+ attr_accessor :section
27
+
28
+ # Single sentence description of the thing being described
29
+ # by this man page; displayed in the NAME section.
30
+ attr_accessor :tagline
31
+
32
+ # The manual this document belongs to; center displayed in
33
+ # the header.
34
+ attr_accessor :manual
35
+
36
+ # The name of the group, organization, or individual responsible
37
+ # for this document; displayed in the left portion of the footer.
38
+ attr_accessor :organization
39
+
40
+ # The date the document was published; center displayed in
41
+ # the document footer.
42
+ attr_accessor :date
43
+
44
+ # Create a Ron::Document given a path or with the data returned by
45
+ # calling the block. The document is loaded and preprocessed before
46
+ # the intialize method returns. The attributes hash may contain values
47
+ # for any writeable attributes defined on this class.
48
+ def initialize(path=nil, attributes={}, &block)
49
+ @path = path
50
+ @basename = path.to_s =~ /^-?$/ ? nil : File.basename(path)
12
51
  @reader = block || Proc.new { |f| File.read(f) }
13
- @data = @reader.call(filename)
52
+ @data = @reader.call(path)
53
+ @name, @section, @tagline = nil
54
+ @manual, @organization, @date = nil
55
+ @fragment = preprocess
56
+ attributes.each { |attr_name,value| send("#{attr_name}=", value) }
57
+ end
14
58
 
15
- @basename = File.basename(filename)
16
- @name, @section =
17
- if @basename =~ /(\w+)\.(\d\w*)\.ron/
18
- [$1, $2]
19
- else
20
- [@basename[/\w+/], nil]
21
- end
59
+ # Generate a file basename of the form "<name>.<section>.<type>"
60
+ # for the given file extension. Uses the name and section from
61
+ # the source file path but falls back on the name and section
62
+ # defined in the document.
63
+ def basename(type=nil)
64
+ type = nil if ['', 'roff'].include?(type.to_s)
65
+ [path_name || @name, path_section || @section, type].
66
+ compact.join('.')
67
+ end
68
+
69
+ # Construct a path for a file near the source file. Uses the
70
+ # Document#basename method to generate the basename part and
71
+ # appends it to the dirname of the source document.
72
+ def path_for(type=nil)
73
+ if @basename
74
+ File.join(File.dirname(path), basename(type))
75
+ else
76
+ basename(type)
77
+ end
22
78
  end
23
79
 
24
- # Construct a path to a file near the input file.
25
- def path(extension=nil)
26
- extension = nil if ['', 'roff'].include?(extension.to_s)
27
- name = "#{@name}.#{section}"
28
- name = "#{name}.#{extension}" if extension
29
- File.join(File.dirname(filename), name)
80
+ # Returns the <name> part of the path, or nil when no path is
81
+ # available. This is used as the manual page name when the
82
+ # file contents do not include a name section.
83
+ def path_name
84
+ @basename[/^[^.]+/] if @basename
30
85
  end
31
86
 
32
- # Convert the document to :roff or :html
87
+ # Returns the <section> part of the path, or nil when
88
+ # no path is available.
89
+ def path_section
90
+ $1 if @basename.to_s =~ /\.(\d\w*)\./
91
+ end
92
+
93
+ # Returns the manual page name based first on the document's
94
+ # contents and then on the path name.
95
+ def name
96
+ @name || path_name
97
+ end
98
+
99
+ # Truthful when the name was extracted from the name section
100
+ # of the document.
101
+ def name?
102
+ @name
103
+ end
104
+
105
+ # Returns the manual page section based first on the document's
106
+ # contents and then on the path name.
107
+ def section
108
+ @section || path_section
109
+ end
110
+
111
+ # True when the section number was extracted from the name
112
+ # section of the document.
113
+ def section?
114
+ @section
115
+ end
116
+
117
+ # The date the man page was published. If not set explicitly,
118
+ # this is the file's modified time or, if no file is given,
119
+ # the current time.
120
+ def date
121
+ return @date if @date
122
+ return File.mtime(path) if File.exist?(path)
123
+ Time.now
124
+ end
125
+
126
+ # Convert the document to :roff, :html, or :html_fragment and
127
+ # return the result as a string.
33
128
  def convert(format)
34
129
  send "to_#{format}"
35
130
  end
36
131
 
37
- # Convert the document to roff.
132
+ # Convert the document to roff and return the result as a string.
38
133
  def to_roff
39
134
  RoffFilter.new(
40
135
  to_html_fragment,
41
136
  name,
42
137
  section,
43
- tagline
138
+ tagline,
139
+ manual,
140
+ organization,
141
+ date
44
142
  ).to_s
45
143
  end
46
144
 
47
- # Convert the document to HTML and return result
48
- # as a string.
145
+ # Convert the document to HTML and return the result as a string.
49
146
  def to_html
50
147
  layout_filter(to_html_fragment)
51
148
  end
52
149
 
53
- # Convert the document to HTML and return result
150
+ # Convert the document to HTML and return the result
54
151
  # as a string. The HTML does not include <html>, <head>,
55
152
  # or <style> tags.
56
153
  def to_html_fragment
57
- definition_list_filter(markdown_filter(data))
154
+ buf = []
155
+ if name? && section?
156
+ buf << "<h2 id='NAME'>NAME</h2>"
157
+ buf << "<p><code>#{name}</code> -- #{tagline}</p>"
158
+ elsif tagline
159
+ buf << "<h1>#{[name, tagline].compact.join(' -- ')}</h1>"
160
+ end
161
+ buf << @fragment.to_s
162
+ buf.join("\n")
163
+ end
164
+
165
+ protected
166
+ # Parse the document and extract the name, section, and tagline
167
+ # from its contents. This is called while the object is being
168
+ # initialized.
169
+ def preprocess
170
+ [
171
+ :angle_quote_pre_filter,
172
+ :markdown_filter,
173
+ :angle_quote_post_filter,
174
+ :definition_list_filter
175
+ ].inject(data) { |res,filter| send(filter, res) }
58
176
  end
59
177
 
60
178
  # Apply the standard HTML layout template.
@@ -64,31 +182,12 @@ module Ron
64
182
  eval("%Q{#{template}}", binding, template_file)
65
183
  end
66
184
 
67
- # Run markdown on the data and extract name, section, and
68
- # tagline.
69
- def markdown_filter(data)
70
- html = Markdown.new(data).to_html
71
- @tagline, html = html.split("</h1>\n", 2)
72
- @tagline.sub!('<h1>', '')
73
-
74
- # grab name and section from title
75
- if @tagline =~ /([\w_:-]+)\((\d\w*)\) -- (.*)/
76
- @name, @section = $1, $2
77
- @tagline = $3
78
- end
79
-
80
- "<h2 id='NAME'>NAME</h2>\n" +
81
- "<p><code>#{@name}</code> -- #{@tagline}</p>\n" +
82
- html
83
- end
84
-
85
185
  # Convert special format unordered lists to definition lists.
86
186
  def definition_list_filter(html)
87
- doc = Nokogiri::HTML(html)
88
-
187
+ doc = parse_html(html)
89
188
  # process all unordered lists depth-first
90
- doc.xpath('//ul').to_a.reverse.each do |ul|
91
- items = ul.xpath('li')
189
+ doc.search('ul').to_a.reverse.each do |ul|
190
+ items = ul.search('li')
92
191
  next if items.any? { |item| item.text.split("\n", 2).first !~ /:$/ }
93
192
 
94
193
  ul.name = 'dl'
@@ -103,15 +202,88 @@ module Ron
103
202
  term, definition = container.inner_html.split(":\n", 2)
104
203
 
105
204
  dt = item.before("<dt>#{term}</dt>").previous_sibling
106
- dt['class'] = 'flush' if dt.content.length <= 10
205
+ dt['class'] = 'flush' if dt.content.length <= 7
107
206
 
108
207
  item.name = 'dd'
109
208
  container.swap(wrap.sub(/></, ">#{definition}<"))
110
209
  end
111
210
  end
211
+ doc
212
+ end
112
213
 
113
- doc.css('html > body').inner_html
214
+ # Perform angle quote (<THESE>) post filtering.
215
+ def angle_quote_post_filter(html)
216
+ doc = parse_html(html)
217
+ # convert all angle quote vars nested in code blocks
218
+ # back to the original text
219
+ doc.search('code text()').each do |node|
220
+ next unless node.to_s.include?('var&gt;')
221
+ new = node.document.create_text_node(
222
+ node.to_s.
223
+ gsub('&lt;var&gt;', '<').
224
+ gsub("&lt;/var&gt;", '>')
225
+ )
226
+ node.replace(new)
227
+ end
228
+ doc
114
229
  end
115
230
 
231
+ # Run markdown on the data and extract name, section, and
232
+ # tagline.
233
+ def markdown_filter(data)
234
+ html = Markdown.new(data).to_html
235
+ @tagline, html = html.split("</h1>\n", 2)
236
+ if html.nil?
237
+ html = @tagline
238
+ @tagline = nil
239
+ else
240
+ # grab name and section from title
241
+ @tagline.sub!('<h1>', '')
242
+ if @tagline =~ /([\w_.\[\]~+=@:-]+)\s*\((\d\w*)\)\s*--?\s*(.*)/
243
+ @name = $1
244
+ @section = $2
245
+ @tagline = $3
246
+ elsif @tagline =~ /([\w_.\[\]~+=@:-]+)\s+--\s+(.*)/
247
+ @name = $1
248
+ @tagline = $2
249
+ end
250
+ end
251
+
252
+ html.to_s
253
+ end
254
+
255
+ # Convert all <WORD> to <var>WORD</var> but only if WORD
256
+ # isn't an HTML tag.
257
+ def angle_quote_pre_filter(data)
258
+ data.gsub(/\<([^:.\/]+?)\>/) do |match|
259
+ contents = $1
260
+ tag, attrs = contents.split(' ', 2)
261
+ if attrs =~ /\/=/ ||
262
+ HTML.include?(tag.sub(/^\//, '')) ||
263
+ data.include?("</#{tag}>")
264
+ match.to_s
265
+ else
266
+ "<var>#{contents}</var>"
267
+ end
268
+ end
269
+ end
270
+
271
+ HTML = %w[
272
+ a abbr acronym b bdo big br cite code dfn
273
+ em i img input kbd label q samp select
274
+ small span strong sub sup textarea tt var
275
+ address blockquote div dl fieldset form
276
+ h1 h2 h3 h4 h5 h6 hr noscript ol p pre
277
+ table ul
278
+ ].to_set
279
+
280
+ private
281
+ def parse_html(html)
282
+ if html.kind_of?(Nokogiri::HTML::DocumentFragment)
283
+ html
284
+ else
285
+ Nokogiri::HTML.fragment(html.to_s)
286
+ end
287
+ end
116
288
  end
117
289
  end
@@ -1,39 +1,70 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
- <title>#{name}(#{section}) -- #{tagline}</title>
4
+ <meta http-equiv='content-type' value='text/html;charset=utf8'>
5
+ <meta name='generator' value='Ron/v#{Ron::VERSION}'>
6
+ <title>#{name}(#{section})#{tagline ? " -- " + tagline : ''}</title>
5
7
  <style type='text/css'>
6
- body {
8
+ body {margin:0}
9
+ #man, #man code, #man pre, #man tt, #man kbd, #man samp {
7
10
  font-family:consolas,monospace;
8
- font-size:18px;
11
+ font-size:16px;
9
12
  line-height:1.25;
10
- color:#111
11
- }
12
- #man { max-width:42em;text-align:justify;margin:25px }
13
- #man h1, #man h2, #man h3, #man strong, #man code { color:#111 }
14
- #man h1 { text-align:center }
15
- #man h2 { font-size:20px;margin-bottom:0 }
16
- #man h3 { font-size:18px;margin:0 0 0 50px }
17
- #man p, #man ul, #man ol, #man dl, #man pre
18
- { margin:0 0 24px 0; }
19
- #man pre { color:#555;font-size:16px }
20
- #man > p, #man > ul, #man > ol, #man > dl, #man > pre
21
- { margin:0 0 24px 80px; }
22
- #man dt { margin:0;clear:left }
23
- #man dt.flush { float:left;width:105px }
24
- #man dd { margin:0 0 0 105px }
25
- #man code { font-weight:bold; }
26
- #man pre code { font-weight:normal;color:#555 }
27
- #man em { font-style:normal;text-decoration:underline }
13
+ color:#434241;
14
+ background:#fff; }
15
+ #man { max-width:85ex; text-align:justify; margin:0 25px 25px 25px }
16
+ #man h1, #man h2, #man h3 { color:#232221;clear:left }
17
+ #man h1 { font-size:28px; margin:10px 0 30px 0; text-align:center }
18
+ #man h2 { font-size:18px; margin-bottom:2px; margin-top:10px; line-height:1.2; }
19
+ #man h3 { font-size:16px; margin:0 0 0 4ex; }
20
+ #man p, #man ul, #man ol, #man dl, #man pre { margin:0 0 18px 0; }
21
+ #man pre {
22
+ color:#333231;
23
+ background:#edeceb;
24
+ padding:5px 10px;
25
+ border-left:2ex solid #ddd;
26
+ margin-top:-10px;
27
+ margin-bottom:12px; }
28
+ #man > p, #man > ul, #man > ol, #man > dl, #man > pre { margin-left:8ex; }
29
+ #man dt { margin:0; clear:left }
30
+ #man dt.flush { float:left; width:8ex }
31
+ #man dd { margin:0 0 0 9ex }
32
+ #man code, #man strong, #man b { font-weight:bold; color:#131211; }
33
+ #man pre code { font-weight:normal; color:#232221; background:inherit }
34
+ #man em, var, u {
35
+ font-style:normal; color:#333231; border-bottom:1px solid #999; }
36
+ #man h1.man-title { display:none; }
37
+ #man ol.man, #man ol.man li { margin:2px 0 10px 0; padding:0;
38
+ float:left; width:33%; list-style-type:none;
39
+ text-transform:uppercase; font-size:18px; color:#999;
40
+ letter-spacing:1px;}
41
+ #man ol.man { width:100%; }
42
+ #man ol.man li.tl { text-align:left }
43
+ #man ol.man li.tc { text-align:center;letter-spacing:4px }
44
+ #man ol.man li.tr { text-align:right }
45
+ #man ol.man a { color:#999 }
46
+ #man ol.man a:hover { color:#333231 }
28
47
  </style>
29
48
  </head>
30
49
  <body>
31
50
  <div id='man'>
32
51
 
33
- <h1>#{@name}(#{@section})</h1>
52
+ <h1 class='man-title'>#{name}(#{section})</h1>
53
+
54
+ <ol class='head man'>
55
+ <li class='tl'>#{name if section}#{"("+section+")" if name and section}</li>
56
+ <li class='tc'>#{manual}</li>
57
+ <li class='tr'>#{name if section}#{"("+section+")" if name and section}</li>
58
+ </ol>
34
59
 
35
60
  #{html}
36
61
 
62
+ <ol class='foot man'>
63
+ <li class='tl'>#{organization}</li>
64
+ <li class='tc'>#{date.strftime('%B %Y')}</li>
65
+ <li class='tr'>#{name if section}#{"("+section+")" if name and section}</li>
66
+ </ol>
67
+
37
68
  </div>
38
69
  </body>
39
70
  </html>
@@ -16,9 +16,9 @@ module Ron
16
16
 
17
17
  protected
18
18
  def title_heading(name, section, tagline, manual, version, date)
19
- comment "generated with Ron"
19
+ comment "generated with Ron/v#{Ron::VERSION}"
20
20
  comment "http://github.com/rtomayko/ron/"
21
- macro "TH", %["#{escape(name.upcase)}" #{section} "#{date}" "#{version}" "#{manual}"]
21
+ macro "TH", %["#{escape(name.upcase)}" #{section} "#{date.strftime('%B %Y')}" "#{version}" "#{manual}"]
22
22
  end
23
23
 
24
24
  def block_filter(node)
@@ -74,6 +74,22 @@ module Ron
74
74
  end
75
75
  write "\n"
76
76
 
77
+ # ordered/unordered lists
78
+ # when 'ul'
79
+ # # macro "IP", '\(bu'
80
+ # block_filter(node.children)
81
+ # when 'ol'
82
+ # macro "IP", '1.'
83
+ # block_filter(node.children)
84
+ # when 'li'
85
+ # macro "IP" unless prev.nil?
86
+ # if node.search('p').any?
87
+ # block_filter(node.children)
88
+ # else
89
+ # inline_filter(node.children)
90
+ # end
91
+ # write "\n"
92
+
77
93
  else
78
94
  warn "unrecognized block tag: %p", node.name
79
95
  end
@@ -85,14 +101,19 @@ module Ron
85
101
  return
86
102
  end
87
103
 
104
+ prev = node.previous_sibling
105
+ prev = prev.previous_sibling until prev.nil? || prev.element?
106
+
88
107
  case node.name
89
108
  when 'text'
90
- write escape(node.to_s.sub(/\n+$/, ' '))
91
- when 'code', 'b', 'strong'
109
+ text = node.content
110
+ text = text.sub(/^\n+/m, '') if prev && prev.name == 'br'
111
+ write escape(text.sub(/\n+$/, ' '))
112
+ when 'code', 'b', 'strong', 'kbd', 'samp'
92
113
  write '\fB'
93
114
  inline_filter(node.children)
94
115
  write '\fR'
95
- when 'em', 'i', 'u'
116
+ when 'var', 'em', 'i', 'u'
96
117
  write '\fI'
97
118
  inline_filter(node.children)
98
119
  write '\fR'
@@ -1,12 +1,12 @@
1
- ron(1) -- the opposite of roff
2
- ==============================
1
+ ron(1) -- build markdown-based man pages
2
+ ========================================
3
3
 
4
4
  ## SYNOPSIS
5
5
 
6
- `ron` [ _OPTIONS_ ]
7
- `ron` --build _FILE_ ...
8
- `ron` --install _FILE_ ...
9
- `ron` --man _FILE_
6
+ `ron` [ <OPTIONS> ]
7
+ `ron` --build <FILE> ...
8
+ `ron` --install <FILE> ...
9
+ `ron` --man <FILE>
10
10
 
11
11
  ## DESCRIPTION
12
12
 
@@ -15,7 +15,7 @@ ron(1) -- the opposite of roff
15
15
  and install standard UNIX / roff(7) formatted man pages and to
16
16
  generate nicely formatted HTML manual pages.
17
17
 
18
- The `ron` command converts one or more named input <em>FILE</em>s
18
+ The `ron` command converts one or more named input <FILE>s
19
19
  (or standard input when no files are named or the file name `-`
20
20
  is given) from humane man page markup to one or more destination
21
21
  output formats. If no output format is selected explicitly, `ron`
@@ -24,13 +24,13 @@ writes output in roff format.
24
24
  ## FILES
25
25
 
26
26
  The `ron` command expects input to be formatted as ron(5) text.
27
- Source files are typically named '_name_._section_.ron' (e.g.,
28
- `hello.1.ron`). The _name_ and _section_ should match the name
29
- and section defined in _FILE_'s heading.
27
+ Source files are typically named '<NAME>.<SECTION>.ron' (e.g.,
28
+ `hello.1.ron`). The <NAME> and <SECTION> should match the name
29
+ and section defined in <FILE>'s heading.
30
30
 
31
31
  When building roff and/or HTML output files with the `--build`
32
32
  argument, destination filenames are determined by taking the basename
33
- of the input _FILE_ and adding the appropriate file extension (or
33
+ of the input <FILE> and adding the appropriate file extension (or
34
34
  removing the file extension in the case of roff output).
35
35
 
36
36
  For example, the command `ron -b --html --roff hello.1.ron` would
@@ -46,8 +46,8 @@ The following arguments change this behavior:
46
46
  * `-b`, `--build`:
47
47
  Write output directly to files instead of standard output. When
48
48
  the `--roff` option is provided, writes roff output to
49
- _file_._section_. When the `--html` option is provided, writes
50
- output to '_file_._section_.html'.
49
+ <file>.<section>. When the `--html` option is provided, writes
50
+ output to '<file>.<section>.html'.
51
51
 
52
52
  * `-i`, `--install`:
53
53
  Install the roff formatted man page to the local system such
@@ -59,20 +59,42 @@ The following arguments change this behavior:
59
59
  _/usr/local/man_.
60
60
 
61
61
  * `-m`, `--man`:
62
- Display _FILE_ as if man(1) were invoked on the roff output
62
+ Display <FILE>s as if man(1) were invoked on the roff output
63
63
  file. This simulates default man behavior by piping the roff
64
64
  output through groff(1) and the paging program specified by the
65
65
  `MANPAGER` environment variable.
66
66
 
67
- The following options control the output formats generated:
67
+ These options control the format used in generated output:
68
68
 
69
- * `--html`:
70
- Generate HTML output.
71
-
72
- * `--roff`:
69
+ * `-r`, `--roff`:
73
70
  Generate roff output. This is the default behavior when no
74
71
  other format argument is provided.
75
72
 
73
+ * `-5`, `--html`:
74
+ Generate output in HTML format.
75
+
76
+ * `-f`, `--fragment`:
77
+ Generate output in HTML format but only the document
78
+ fragment, not the header, title, or footer.
79
+
80
+ All document attributes displayed in the header and footer areas
81
+ of generated content can be specified with these options:
82
+
83
+ * `--manual`=<MANUAL>:
84
+ The name of the manual this man page belongs to; <MANUAL> is
85
+ prominently displayed top-center in the header area.
86
+
87
+ * `--organization`=<NAME>:
88
+ The name of the group, organization, or individual
89
+ responsible for publishing the document; <NAME> is displayed
90
+ in the bottom-left footer area.
91
+
92
+ * `--date`=<DATE>:
93
+ The document's published date; <DATE> must be formatted
94
+ `YYYY-MM-DD` and is displayed in the bottom-center footer
95
+ area. The <FILE> mtime is used when no <DATE> is given,
96
+ or the current time when no <FILE> is available.
97
+
76
98
  ## EXAMPLES
77
99
 
78
100
  Generate `roff(7)` output on stdout:
@@ -113,7 +135,7 @@ Install the roff man page for a ron file:
113
135
  * `MANHOME`:
114
136
  Location where roff formatted man pages should be installed.
115
137
  Relevant only when the `--installed` argument is provided.
116
- _PATH_ is to the base of a man file hierarchy. e.g.,
138
+ <PATH> is to the base of a man file hierarchy. e.g.,
117
139
  `/usr/local/share/man`, `/home/rtomayko/man`.
118
140
 
119
141
  * `MANPAGER`:
@@ -125,7 +147,8 @@ Install the roff man page for a ron file:
125
147
 
126
148
  ## BUGS
127
149
 
128
- Ron is written in Ruby.
150
+ Ron is written in Ruby. C and/or standalone Perl implementations
151
+ would be preferable for ease of packaging and distribution.
129
152
 
130
153
  ## COPYRIGHT
131
154
 
@@ -99,11 +99,13 @@ uses the following bits of markdown(5) to accomplish this:
99
99
  displayed in in <b>boldface</b>. Note that all text included
100
100
  within `backticks` is displayed literally; other inline markup
101
101
  is not processed.
102
+ * `**double-stars**`:
103
+ Like `backticks` but may contain other inline markup.
102
104
  * `_`_underbars_`_`:
103
105
  User-specified arguments, variables, or user input; typically
104
- displayed in <u>underline</u>.
105
- * `**double stars**`:
106
- Like `backticks` but may contain other inline markup.
106
+ displayed with <u>underline</u>.
107
+ * `<angle-quotes>`:
108
+ Same as _underbars_. This is not compatible with Markdown.
107
109
 
108
110
  Here is grep(1)'s DESCRIPTION section represented in `ron`:
109
111
 
@@ -0,0 +1,149 @@
1
+ ron(7) -- the opposite of roff
2
+ ==============================
3
+
4
+ DESCRIPTION
5
+ -----------
6
+
7
+ Ron is a humane text format and toolchain for
8
+ creating UNIX man pages -- and things that
9
+ appear as man pages from a distance. Use it
10
+ to build and install standard UNIX roff man
11
+ pages or to generate nicely formatted HTML
12
+ manual pages for the web.
13
+
14
+ The ron file format is based on Markdown. In
15
+ fact, ron files are 100% Markdown compatible
16
+ but have a more rigidly defined structure and
17
+ extend Markdown in some ways to provide
18
+ features commonly found in man pages (e.g.,
19
+ definition lists). The ron(5) manual page
20
+ included with this distribution defines the
21
+ format in more detail.
22
+
23
+ INSTALL
24
+ -------
25
+
26
+ Ron can be installed using rubygems:
27
+
28
+ $ [sudo] gem install ron
29
+
30
+ Or, clone the git repository and install from
31
+ source:
32
+
33
+ $ git clone git://github.com/rtomayko/ron.git
34
+ $ cd ron
35
+ $ rake package
36
+ $ [sudo] rake install
37
+
38
+ EXAMPLES
39
+ --------
40
+
41
+ The .ron files located under the repository's
42
+ ./man directory show off a wide range of ron
43
+ capabilities. The HTML versions of these
44
+ files are available at:
45
+
46
+ http://rtomayko.github.com/ron/ron.1.html
47
+ http://rtomayko.github.com/ron/ron.5.html
48
+ http://rtomayko.github.com/ron/markdown.5.html
49
+
50
+ BASIC USAGE
51
+ -----------
52
+
53
+ To generate a roff man page from the included
54
+ `markdown.5.ron` file and open it in man(1):
55
+
56
+ $ ron -b man/markdown.5.ron
57
+ building: man/markdown.5
58
+ $ man man/markdown.5
59
+
60
+ To generate a standalone HTML version:
61
+
62
+ $ ron -b --html man/markdown.5.ron
63
+ building: man/markdown.5.html
64
+ $ open man/markdown.5.html
65
+
66
+ To build roff and HTML versions of all ron
67
+ files:
68
+
69
+ $ ron -b --roff --html man/*.ron
70
+
71
+ If you just want to view a ron file as if it
72
+ were a man page without building any
73
+ intermediate files:
74
+
75
+ $ ron -m man/markdown.5.ron
76
+
77
+ The ron(1) manual page included with this
78
+ distribution includes full documentation on
79
+ ron command line options.
80
+
81
+ RATIONALE
82
+ ---------
83
+
84
+ Some people think UNIX manual pages are a
85
+ poor and outdated form of documentation. I
86
+ disagree.
87
+
88
+ - Man pages typically follow a well defined
89
+ structure that's immediately familiar and
90
+ provides a useful starting point for
91
+ developers documenting new tools,
92
+ libraries, and formats.
93
+
94
+ - Man pages get to the point. Because they're
95
+ written in an inverted style, with a
96
+ SYNOPSIS section followed by additional
97
+ detail, prose, and finally references to
98
+ other sources of information, man pages
99
+ provide the best of both cheat sheet and
100
+ reference style documentation.
101
+
102
+ - Man pages have very limited text formatting
103
+ capabilities. This is a feature. You get
104
+ bold and underline, basically, and they're
105
+ typically applied consistently across man
106
+ pages.
107
+
108
+ - Most man pages use only a single level of
109
+ section hierarchy (although two levels are
110
+ technically supported). Hierarchy destroys
111
+ otherwise good documentation by adding
112
+ unnecessary complexity. Feynman described
113
+ the whole of quantum electro dynamics with
114
+ only two levels of hierarchy. How can you
115
+ possibly need more? Man pages force you to
116
+ keep it simple.
117
+
118
+ - Man pages have a simple referencing syntax;
119
+ e.g., sh(1), fork(2), markdown(5). HTML
120
+ versions can use this to generate links
121
+ between pages.
122
+
123
+ - The classical terminal man page display is
124
+ typographically well thought out. Big bold
125
+ section headings, justified monospaced
126
+ text, nicely indented paragraphs,
127
+ intelligently aligned definition lists, and
128
+ an informational header and footer.
129
+
130
+ All that being said, trying to figure out how
131
+ to create a man page can be a really tedious
132
+ process. The roff/man macro languages are
133
+ highly extensible, fractured between multiple
134
+ dialects, and include a bunch of stuff that's
135
+ entirely irrelevant to modern man page
136
+ creation. It's also horribly ugly compared to
137
+ today's humane text formats or even HTML
138
+ (just sayin').
139
+
140
+ Ron aims to address many of the issues with
141
+ man page creation while preserving the things
142
+ that makes man pages a great form of
143
+ documentation.
144
+
145
+ COPYRIGHT
146
+ ---------
147
+
148
+ Ron is Copyright (C) 2009 Ryan Tomayko
149
+ See the file COPYING for more information.
@@ -3,8 +3,8 @@ Gem::Specification.new do |s|
3
3
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
4
4
 
5
5
  s.name = 'ron'
6
- s.version = '0.1'
7
- s.date = '2009-11-05'
6
+ s.version = '0.2'
7
+ s.date = '2009-11-23'
8
8
 
9
9
  s.description = "The opposite of roff"
10
10
  s.summary = "The opposite of roff"
@@ -25,10 +25,20 @@ Gem::Specification.new do |s|
25
25
  man/markdown.5.ron
26
26
  man/ron.1.ron
27
27
  man/ron.5.ron
28
+ man/ron.7.ron
28
29
  ron.gemspec
30
+ test/angle_bracket_syntax.html
31
+ test/angle_bracket_syntax.ron
32
+ test/basic_document.html
33
+ test/basic_document.ron
34
+ test/custom_title_document.html
35
+ test/custom_title_document.ron
36
+ test/definition_list_syntax.html
37
+ test/definition_list_syntax.ron
29
38
  test/document_test.rb
30
39
  test/ron_test.rb
31
- test/simple.ron
40
+ test/titleless_document.html
41
+ test/titleless_document.ron
32
42
  ]
33
43
  # = MANIFEST =
34
44
 
@@ -0,0 +1,12 @@
1
+ <h2 id='NAME'>NAME</h2>
2
+ <p><code>angle_bracket_syntax</code> -- angle bracket syntax test</p>
3
+ <p>A <var>WORD</var> in angle brackets is converted to <var>WORD</var>,</p>
4
+
5
+ <pre><code>except when &lt;WORD&gt; is
6
+ part of a preformatted
7
+ code block,
8
+ </code></pre>
9
+
10
+ <p>or when <code>&lt;WORD&gt;</code> is enclosed in backticks.</p>
11
+
12
+ <p>or when <var>WORD</var> has a &lt;dot.&gt; or &lt;foo:colon&gt;.</p>
@@ -0,0 +1,12 @@
1
+ angle_bracket_syntax(5) -- angle bracket syntax test
2
+ ====================================================
3
+
4
+ A <WORD> in angle brackets is converted to <var>WORD</var>,
5
+
6
+ except when <WORD> is
7
+ part of a preformatted
8
+ code block,
9
+
10
+ or when `<WORD>` is enclosed in backticks.
11
+
12
+ or when <WORD> has a <dot.> or <foo:colon>.
@@ -0,0 +1,3 @@
1
+ <h2 id='NAME'>NAME</h2>
2
+ <p><code>simple</code> -- a simple ron example</p>
3
+ <p>This document created by ron.</p>
@@ -1,2 +1,4 @@
1
1
  simple(7) -- a simple ron example
2
2
  =================================
3
+
4
+ This document created by ron.
@@ -0,0 +1,3 @@
1
+ <h1>custom_title_document -- This is a custom title</h1>
2
+ <p>It doesn't define the name or section of this manual page and is
3
+ output as a simple <code>&lt;h1&gt;</code> instead of a <code>NAME</code> section.</p>
@@ -0,0 +1,5 @@
1
+ This is a custom title
2
+ ======================
3
+
4
+ It doesn't define the name or section of this manual page and is
5
+ output as a simple `<h1>` instead of a `NAME` section.
@@ -0,0 +1,21 @@
1
+ <h2 id='NAME'>NAME</h2>
2
+ <p><code>defition_list_syntax</code> -- hiya</p>
3
+ <p>Definition lists look like unordered lists:</p>
4
+
5
+ <dl>
6
+ <dt class="flush">term</dt>
7
+ <dd><p>definition</p></dd>
8
+ <dt>another one</dt>
9
+ <dd>
10
+ <p>The definition may span
11
+ multiple lines and even</p>
12
+
13
+ <p>start</p>
14
+
15
+ <p>new paragraphs</p>
16
+ </dd>
17
+ <dt>
18
+ <code>--somearg</code>=<var>VALUE</var>
19
+ </dt>
20
+ <dd><p>We can do that too.</p></dd>
21
+ </dl>
@@ -0,0 +1,18 @@
1
+ defition_list_syntax(5) -- hiya
2
+ ===============================
3
+
4
+ Definition lists look like unordered lists:
5
+
6
+ * term:
7
+ definition
8
+
9
+ * another one:
10
+ The definition may span
11
+ multiple lines and even
12
+
13
+ start
14
+
15
+ new paragraphs
16
+
17
+ * `--somearg`=<VALUE>:
18
+ We can do that too.
@@ -2,34 +2,87 @@ require 'contest'
2
2
  require 'ron/document'
3
3
 
4
4
  class DocumentTest < Test::Unit::TestCase
5
- SIMPLE_FILE = "#{File.dirname(__FILE__)}/simple.ron"
6
- HELLO_DATA = "# hello(1) -- hello world"
5
+ SIMPLE_FILE = "#{File.dirname(__FILE__)}/basic_document.ron"
7
6
 
8
- test "creating with a file" do
7
+ test "new with path" do
9
8
  doc = Ron::Document.new(SIMPLE_FILE)
10
9
  assert_equal File.read(SIMPLE_FILE), doc.data
11
10
  end
12
11
 
13
- test "creating with a string and a file" do
14
- doc = Ron::Document.new('hello.1.ron') { HELLO_DATA }
15
- assert_equal HELLO_DATA, doc.data
12
+ test "new with path and block" do
13
+ doc = Ron::Document.new('hello.1.ron') { "# hello(1) -- hello world" }
14
+ assert_equal "# hello(1) -- hello world", doc.data
16
15
  end
17
16
 
18
- context "Document" do
17
+ test "new with path and block but missing name section" do
18
+ doc = Ron::Document.new('foo.7.ron') { '' }
19
+ assert_equal 'foo', doc.name
20
+ assert_equal '7', doc.section
21
+ end
22
+
23
+ test "new with non conventional path and missing name section" do
24
+ doc = Ron::Document.new('bar.ron') { '' }
25
+ assert_equal 'bar', doc.name
26
+ assert_equal nil, doc.section
27
+ assert_equal "./bar.html", doc.path_for('html')
28
+ assert_equal "./bar", doc.path_for('roff')
29
+ assert_equal "./bar", doc.path_for('')
30
+ assert_equal "./bar", doc.path_for(nil)
31
+ end
32
+
33
+ test "new with path and name section mismatch" do
34
+ doc = Ron::Document.new('foo/rick.7.ron') { "# randy(3) -- I'm confused." }
35
+ assert_equal 'randy', doc.name
36
+ assert_equal 'rick', doc.path_name
37
+ assert_equal '3', doc.section
38
+ assert_equal '7', doc.path_section
39
+ assert_equal 'rick.7', doc.basename
40
+ assert_equal 'foo/rick.7.bar', doc.path_for(:bar)
41
+ end
42
+
43
+ test "new with no path and a name section" do
44
+ doc = Ron::Document.new { "# brandy(5) -- wootderitis" }
45
+ assert_equal nil, doc.path_name
46
+ assert_equal nil, doc.path_section
47
+ assert_equal 'brandy', doc.name
48
+ assert_equal '5', doc.section
49
+ assert_equal 'brandy.5', doc.basename
50
+ assert_equal 'brandy.5.foo', doc.path_for(:foo)
51
+ end
52
+
53
+ context "simple conventionally named document" do
19
54
  setup do
20
- @doc = Ron::Document.new('hello.1.ron') { HELLO_DATA }
55
+ @doc = Ron::Document.new('hello.1.ron') { "# hello(1) -- hello world" }
21
56
  end
22
57
 
23
58
  should "load data" do
24
- assert_equal HELLO_DATA, @doc.data
59
+ assert_equal "# hello(1) -- hello world", @doc.data
25
60
  end
26
61
 
27
- should "extract the name" do
62
+ should "extract the manual page name from the filename or document" do
28
63
  assert_equal 'hello', @doc.name
29
64
  end
30
65
 
31
- should "extract the section" do
66
+ should "extract the manual page section from the filename or document" do
32
67
  assert_equal '1', @doc.section
33
68
  end
69
+
70
+ should "convert to an HTML fragment" do
71
+ assert_equal %[<h2 id='NAME'>NAME</h2>\n<p><code>hello</code> -- hello world</p>\n],
72
+ @doc.to_html_fragment
73
+ end
74
+
75
+ should "convert to HTML with a layout" do
76
+ assert_match %r{^<!DOCTYPE html.*}m, @doc.to_html
77
+ assert_match %[<h2 id='NAME'>NAME</h2>\n<p><code>hello</code> -- hello world</p>],
78
+ @doc.to_html
79
+ end
80
+
81
+ should "construct a path to related documents" do
82
+ assert_equal "./hello.1.html", @doc.path_for(:html)
83
+ assert_equal "./hello.1", @doc.path_for(:roff)
84
+ assert_equal "./hello.1", @doc.path_for('')
85
+ assert_equal "./hello.1", @doc.path_for(nil)
86
+ end
34
87
  end
35
88
  end
@@ -1,21 +1,22 @@
1
1
  require 'contest'
2
+ require 'ron'
2
3
 
3
- # ron command tests
4
4
  class RonTest < Test::Unit::TestCase
5
5
  testdir = File.dirname(__FILE__)
6
6
  bindir = File.dirname(testdir)
7
7
  ENV['PATH'] = "#{bindir}:#{ENV['PATH']}"
8
+ ENV['RUBYLIB'] = $LOAD_PATH.join(':')
8
9
 
9
10
  SIMPLE_FILE = "#{File.dirname(__FILE__)}/simple.ron"
10
11
 
11
12
  test "takes ron text on stdin and produces roff on stdout" do
12
- output = `echo '# hello(1) -- hello world' | ron`
13
+ output = `echo '# hello(1) -- hello world' | ron --date=2009-11-23`
13
14
  lines = output.split("\n")
14
15
  assert_equal 7, lines.size
15
- assert_equal %[.\\" generated with Ron], lines.shift
16
+ assert_equal %[.\\" generated with Ron/v#{Ron::VERSION}], lines.shift
16
17
  assert_equal %[.\\" http://github.com/rtomayko/ron/], lines.shift
17
18
  assert_equal %[.], lines.shift
18
- assert_equal %[.TH "HELLO" 1 "" "" ""], lines.shift
19
+ assert_equal %[.TH "HELLO" 1 "November 2009" "" ""], lines.shift
19
20
  assert_equal %[.], lines.shift
20
21
  assert_equal %[.SH "NAME"], lines.shift
21
22
  assert_equal %[\\fBhello\\fR \\-\\- hello world], lines.shift
@@ -24,6 +25,30 @@ class RonTest < Test::Unit::TestCase
24
25
 
25
26
  test "produces html instead of roff with the --html argument" do
26
27
  output = `echo '# hello(1) -- hello world' | ron --html`
27
- assert_match(/<h2 id="NAME">NAME<\/h2>/, output)
28
+ assert_match(/<h2 id='NAME'>NAME<\/h2>/, output)
29
+ end
30
+
31
+ test "produces html fragment with the --fragment argument" do
32
+ output = `echo '# hello(1) -- hello world' | ron --fragment`
33
+ assert_equal "<h2 id='NAME'>NAME</h2>\n<p><code>hello</code> -- hello world</p>\n",
34
+ output
35
+ end
36
+
37
+ # file based tests
38
+ Dir[testdir + '/*.ron'].each do |source|
39
+ dest = source.sub(/ron$/, 'html')
40
+ wrong = source.sub(/ron$/, "wrong")
41
+ test File.basename(source, '.ron') do
42
+ html = `ron --html --fragment #{source}`
43
+ expected = File.read(dest) rescue ''
44
+ if expected != html
45
+ File.open(wrong, 'wb') { |f| f.write(html) }
46
+ diff = `diff -u #{dest} #{wrong} 2>/dev/null`
47
+ fail "the #{dest} file does not exist" if diff.empty?
48
+ flunk diff
49
+ elsif File.exist?(wrong)
50
+ File.unlink(wrong)
51
+ end
52
+ end
28
53
  end
29
54
  end
@@ -0,0 +1,2 @@
1
+ <p>This is a document without a level 1 heading. It doesn't output
2
+ a <code>NAME</code> section or custom <code>&lt;h1&gt;</code>.</p>
@@ -0,0 +1,2 @@
1
+ This is a document without a level 1 heading. It doesn't output
2
+ a `NAME` section or custom `<h1>`.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ron
3
3
  version: !ruby/object:Gem::Version
4
- version: "0.1"
4
+ version: "0.2"
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Tomayko
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-11-05 00:00:00 -08:00
12
+ date: 2009-11-23 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -63,10 +63,20 @@ files:
63
63
  - man/markdown.5.ron
64
64
  - man/ron.1.ron
65
65
  - man/ron.5.ron
66
+ - man/ron.7.ron
66
67
  - ron.gemspec
68
+ - test/angle_bracket_syntax.html
69
+ - test/angle_bracket_syntax.ron
70
+ - test/basic_document.html
71
+ - test/basic_document.ron
72
+ - test/custom_title_document.html
73
+ - test/custom_title_document.ron
74
+ - test/definition_list_syntax.html
75
+ - test/definition_list_syntax.ron
67
76
  - test/document_test.rb
68
77
  - test/ron_test.rb
69
- - test/simple.ron
78
+ - test/titleless_document.html
79
+ - test/titleless_document.ron
70
80
  has_rdoc: true
71
81
  homepage: http://github.com/rtomayko/ron/
72
82
  licenses: []