pseudohikiparser 0.0.3 → 0.0.4.develop

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,6 +4,7 @@
4
4
  require 'optparse'
5
5
  require 'erb'
6
6
  require 'pseudohiki/blockparser'
7
+ require 'pseudohiki/autolink'
7
8
  require 'pseudohiki/htmlformat'
8
9
  require 'pseudohiki/plaintextformat'
9
10
  require 'pseudohiki/markdownformat'
@@ -19,9 +20,13 @@ module PseudoHiki
19
20
 
20
21
  def initialize(options)
21
22
  @options = options
22
- @is_toc_item_pat = Proc.new do |node|
23
+ @is_toc_item_pat = proc_for_is_toc_item_pat
24
+ end
25
+
26
+ def proc_for_is_toc_item_pat
27
+ proc do |node|
23
28
  node.kind_of?(PseudoHiki::BlockParser::HeadingLeaf) and
24
- (2..3).include? node.nominal_level and
29
+ (2..3).include? node.level and
25
30
  node.node_id
26
31
  end
27
32
  end
@@ -40,18 +45,14 @@ module PseudoHiki
40
45
 
41
46
  def create_plain_table_of_contents(tree)
42
47
  toc_lines = collect_nodes_for_table_of_contents(tree).map do |toc_node|
43
- ('*' * toc_node.nominal_level) + to_plain(toc_node)
48
+ ('*' * toc_node.level) + to_plain(toc_node)
44
49
  end
45
50
 
46
51
  @options.formatter.format(BlockParser.parse(toc_lines))
47
52
  end
48
53
 
49
54
  def create_html_table_of_contents(tree)
50
- toc_lines = collect_nodes_for_table_of_contents(tree).map do |toc_node|
51
- "%s[[%s|#%s]]"%['*'*toc_node.nominal_level, to_plain(toc_node).lstrip, toc_node.node_id.upcase]
52
- end
53
-
54
- @options.formatter.format(BlockParser.parse(toc_lines)).tap do |toc|
55
+ @options.formatter.format(create_html_toc_tree(tree)).tap do |toc|
55
56
  toc.traverse do |element|
56
57
  if element.kind_of? HtmlElement and element.tagname == "a"
57
58
  element["title"] = "toc_item: " + element.children.join.chomp
@@ -60,13 +61,26 @@ module PseudoHiki
60
61
  end
61
62
  end
62
63
 
64
+ def create_html_toc_tree(tree, newline=nil)
65
+ toc_lines = collect_nodes_for_table_of_contents(tree).map do |line|
66
+ format("%s[[%s|#%s]]#{newline}",
67
+ '*' * line.level,
68
+ to_plain(line).lstrip,
69
+ line.node_id.upcase)
70
+ end
71
+ BlockParser.parse(toc_lines)
72
+ end
73
+
63
74
  def gfm_id(heading_node)
64
- MarkDownFormat.convert_to_gfm_id_format(to_plain(heading_node).strip)
75
+ MarkDownFormat.convert_into_gfm_id_format(to_plain(heading_node).strip)
65
76
  end
66
77
 
67
78
  def create_gfm_table_of_contents(tree)
68
79
  toc_lines = collect_nodes_for_table_of_contents(tree).map do |toc_node|
69
- "%s[[%s|#%s]]#{$/}"%['*'*toc_node.nominal_level, to_plain(toc_node).strip, gfm_id(toc_node)]
80
+ format("%s[[%s|#%s]]#{$/}",
81
+ '*' * toc_node.level,
82
+ to_plain(toc_node).strip,
83
+ gfm_id(toc_node))
70
84
  end
71
85
 
72
86
  @options.formatter.format(BlockParser.parse(toc_lines))
@@ -74,7 +88,8 @@ module PseudoHiki
74
88
 
75
89
  def create_table_of_contents(tree)
76
90
  return "" unless @options[:toc]
77
- return create_gfm_table_of_contents(tree) if @options[:html_version].version == "gfm"
91
+ gfm_chosen = @options[:html_version].version == "gfm"
92
+ return create_gfm_table_of_contents(tree) if gfm_chosen
78
93
  return create_plain_table_of_contents(tree) unless @options.html_template
79
94
  create_html_table_of_contents(tree)
80
95
  end
@@ -90,27 +105,37 @@ module PseudoHiki
90
105
  def create_plain_main(toc, body, h1)
91
106
  contents = [body]
92
107
  contents.unshift toc unless toc.empty?
93
- contents.unshift @options.formatter.format(BlockParser.parse("!!" + @options[:toc])) if @options[:toc]
108
+ if title = @options[:toc]
109
+ toc_title = @options.formatter.format(BlockParser.parse("!!" + title))
110
+ contents.unshift toc_title
111
+ end
94
112
  contents.unshift h1 unless h1.empty?
95
113
  contents.join($/)
96
114
  end
97
115
 
98
116
  def create_html_main(toc, body, h1)
99
117
  return nil unless @options[:toc]
100
- toc_container = formatter.create_element("section").tap do |element|
101
- element["id"] = "toc"
102
- element.push formatter.create_element("h2", @options[:toc]) unless @options[:toc].empty?
103
- element.push toc
104
- end
105
- contents_container = formatter.create_element("section").tap do |element|
106
- element["id"] = "contents"
107
- element.push body
108
- end
109
118
  main = formatter.create_element("section").tap do |element|
110
119
  element["id"] = "main"
111
120
  element.push h1 unless h1.empty?
112
- element.push toc_container
113
- element.push contents_container
121
+ element.push create_html_toc_container(toc)
122
+ element.push create_html_contents_container(body)
123
+ end
124
+ end
125
+
126
+ def create_html_toc_container(toc)
127
+ formatter.create_element("section").tap do |elm|
128
+ elm["id"] = "toc"
129
+ title = @options[:toc]
130
+ elm.push formatter.create_element("h2", title) unless title.empty?
131
+ elm.push toc
132
+ end
133
+ end
134
+
135
+ def create_html_contents_container(body)
136
+ formatter.create_element("section").tap do |elm|
137
+ elm["id"] = "contents"
138
+ elm.push body
114
139
  end
115
140
  end
116
141
 
@@ -140,14 +165,17 @@ module PseudoHiki
140
165
  body = compose_body(tree)
141
166
  title = @options.title
142
167
  main = create_main(toc, body, h1)
168
+ choose_template(main, body, binding)
169
+ end
143
170
 
171
+ def choose_template(main, body, current_binding)
144
172
  if @options[:template]
145
- erb = ERB.new(@options.read_template_file)
146
- html = erb.result(binding)
173
+ html = ERB.new(@options.read_template_file).result(current_binding)
147
174
  else
148
175
  html = @options.create_html_template_with_current_options
149
- html.head.push create_style(@options[:embed_css]) if @options[:embed_css]
150
- html.push main||body
176
+ embed_css = @options[:embed_css]
177
+ html.head.push create_style(embed_css) if embed_css
178
+ html.push main || body
151
179
  end
152
180
 
153
181
  html
@@ -161,8 +189,7 @@ module PseudoHiki
161
189
  MDFormat = MarkDownFormat.create
162
190
  GFMFormat = MarkDownFormat.create(:gfm_style => true)
163
191
 
164
- class Formatter < Struct.new(:version, :formatter, :template, :ext, :opt_pat)
165
- end
192
+ Formatter = Struct.new(:version, :formatter, :template, :ext, :opt_pat)
166
193
 
167
194
  VERSIONS = [
168
195
  ["html4", HtmlFormat, HtmlTemplate, ".html", /^h/io],
@@ -192,6 +219,21 @@ module PseudoHiki
192
219
  'latin1' => LATIN1
193
220
  }
194
221
 
222
+ @default_options = {
223
+ :html_version => VERSIONS[0],
224
+ :lang => 'en',
225
+ :encoding => 'utf8',
226
+ :title => nil,
227
+ :css => "default.css",
228
+ :embed_css => nil,
229
+ :base => nil,
230
+ :template => nil,
231
+ :output => nil,
232
+ :force => false,
233
+ :toc => nil,
234
+ :split_main_heading => false
235
+ }
236
+
195
237
  attr_accessor :need_output_file, :default_title
196
238
  attr_reader :input_file_basename
197
239
 
@@ -200,23 +242,16 @@ module PseudoHiki
200
242
  input.rewind unless BOM == bom
201
243
  end
202
244
 
245
+ def self.default_options
246
+ @default_options.dup
247
+ end
248
+
203
249
  def initialize(options=nil)
204
- @options = options||{
205
- :html_version => VERSIONS[0],
206
- :lang => 'en',
207
- :encoding => 'utf8',
208
- :title => nil,
209
- :css => "default.css",
210
- :embed_css => nil,
211
- :base => nil,
212
- :template => nil,
213
- :output => nil,
214
- :force => false,
215
- :toc => nil,
216
- :split_main_heading => false
217
- }
250
+ @options = options || self.class.default_options
218
251
  @written_option_pat = {}
219
- @options.keys.each {|opt| @written_option_pat[opt] = /^\/\/#{opt}:\s*(.*)$/ }
252
+ @options.keys.each do |opt|
253
+ @written_option_pat[opt] = /^\/\/#{opt}:\s*(.*)$/
254
+ end
220
255
  end
221
256
 
222
257
  def [](key)
@@ -250,18 +285,18 @@ module PseudoHiki
250
285
  def base
251
286
  base_dir = self[:base]
252
287
  if base_dir and base_dir !~ /[\/\\]\.*$/o
253
- base_dir = File.join(base_dir,".")
254
- base_dir = "file:///"+base_dir if base_dir !~ /^\./o and win32?
288
+ base_dir = File.join(base_dir, ".")
289
+ base_dir = "file:///" + base_dir if base_dir !~ /^\./o and win32?
255
290
  end
256
291
  base_dir
257
292
  end
258
293
 
259
294
  def title
260
- self[:title]||@default_title||"-"
295
+ self[:title] || @default_title || "-"
261
296
  end
262
297
 
263
298
  def read_template_file
264
- File.read(File.expand_path(self[:template]), :encoding => self.charset)
299
+ File.read(File.expand_path(self[:template]), :encoding => charset)
265
300
  end
266
301
 
267
302
  def set_html_version(version)
@@ -272,7 +307,8 @@ module PseudoHiki
272
307
  self[:html_version] = v if v.opt_pat =~ version
273
308
  end
274
309
  end
275
- STDERR.puts "\"#{version}\" is an invalid option for --format-version. \"#{self[:html_version].version}\" is chosen instead."
310
+ STDERR.puts "\"#{version}\" is an invalid option for --format-version. \
311
+ \"#{self[:html_version].version}\" is chosen instead."
276
312
  end
277
313
 
278
314
  def set_html_encoding(given_opt)
@@ -282,7 +318,8 @@ module PseudoHiki
282
318
  ENCODING_REGEXP.each do |pat, encoding|
283
319
  self[:encoding] = encoding if pat =~ given_opt
284
320
  end
285
- STDERR.puts "\"#{self[:encoding]}\" is chosen as an encoding system, instead of \"#{given_opt}\"."
321
+ STDERR.puts "\"#{self[:encoding]}\" is chosen as an encoding system, \
322
+ instead of \"#{given_opt}\"."
286
323
  end
287
324
  end
288
325
 
@@ -294,67 +331,80 @@ module PseudoHiki
294
331
  end
295
332
 
296
333
  def parse_command_line_options
297
- OptionParser.new("** Convert texts written in a Hiki-like notation into HTML **
298
- USAGE: #{File.basename(__FILE__)} [options]") do |opt|
334
+ OptionParser.new("USAGE: #{File.basename($0)} [OPTION]... [FILE]...
335
+ Convert texts written in a Hiki-like notation into another format.") do |opt|
299
336
  opt.on("-f [html_version]", "--format-version [=format_version]",
300
- "HTML version to be used. Choose html4, xhtml1, html5, plain, plain_verbose, markdown or gfm (default: #{self[:html_version].version})") do |version|
301
- self.set_html_version(version)
337
+ "Choose a formart for the output. Available options: \
338
+ html4, xhtml1, html5, plain, plain_verbose, markdown or gfm \
339
+ (default: #{self[:html_version].version})") do |version|
340
+ set_html_version(version)
302
341
  end
303
342
 
304
343
  opt.on("-l [lang]", "--lang [=lang]",
305
- "Set the value of charset attributes (default: #{self[:lang]})") do |lang|
344
+ "Set the value of charset attributes \
345
+ (default: #{self[:lang]})") do |lang|
306
346
  self[:lang] = lang if value_given?(lang)
307
347
  end
308
348
 
309
349
  opt.on("-e [encoding]", "--format-encoding [=encoding]",
310
- "Available options: utf8, euc-jp, sjis, latin1 (default: #{self[:encoding]})") do |given_opt|
311
- self.set_html_encoding(given_opt)
350
+ "Available options: utf8, euc-jp, sjis, latin1 \
351
+ (default: #{self[:encoding]})") do |given_opt|
352
+ set_html_encoding(given_opt)
312
353
  end
313
354
 
314
355
  opt.on("-E [ex[:in]]", "--encoding [=ex[:in]]",
315
- "Specify the default external and internal character encodings (same as the option of MRI") do |given_opt|
316
- self.set_encoding(given_opt)
356
+ "Specify the default external and internal character encodings \
357
+ (same as the option of MRI") do |given_opt|
358
+ set_encoding(given_opt)
317
359
  end
318
360
 
319
- #use '-w' to avoid the conflict with the short option for '[-t]emplate'
361
+ # use '-w' to avoid the conflict with the short option for '[-t]emplate'
320
362
  opt.on("-w [(window) title]", "--title [=title]",
321
- "Set the value of the <title> element (default: the basename of the input file)") do |title|
363
+ "Set the value of the <title> element \
364
+ (default: the basename of the input file)") do |title|
322
365
  self[:title] = title if value_given?(title)
323
366
  end
324
367
 
325
368
  opt.on("-c [css]", "--css [=css]",
326
- "Set the path to a css file to be used (default: #{self[:css]})") do |css|
369
+ "Set the path to a css file to be used \
370
+ (default: #{self[:css]})") do |css|
327
371
  self[:css] = css
328
372
  end
329
373
 
330
374
  opt.on("-C [path_to_css_file]", "--embed-css [=path_to_css_file]",
331
- "Set the path to a css file to embed (default: not to embed)") do |path_to_css_file|
375
+ "Set the path to a css file to embed \
376
+ (default: not to embed)") do |path_to_css_file|
332
377
  self[:embed_css] = path_to_css_file
333
378
  end
334
379
 
335
380
  opt.on("-b [base]", "--base [=base]",
336
- "Specify the value of href attribute of the <base> element (default: not specified)") do |base_dir|
381
+ "Specify the value of href attribute of the <base> element \
382
+ (default: not specified)") do |base_dir|
337
383
  self[:base] = base_dir if value_given?(base_dir)
338
384
  end
339
385
 
340
386
  opt.on("-t [template]", "--template [=template]",
341
- "Specify a template file written in eruby format with \"<%= body %>\" inside (default: not specified)") do |template|
387
+ "Specify a template file in eruby format with \"<%= body %>\" \
388
+ inside (default: not specified)") do |template|
342
389
  self[:template] = template if value_given?(template)
343
390
  end
344
391
 
345
392
  opt.on("-o [output]", "--output [=output]",
346
- "Output to the specified file. If no file is given, \"[input_file_basename].html\" will be used.(default: STDOUT)") do |output|
393
+ "Output to the specified file. If no file is given, \
394
+ \"[input_file_basename].html\" will be used.(default: STDOUT)") do |output|
347
395
  self[:output] = File.expand_path(output) if value_given?(output)
348
- self.need_output_file = true
396
+ @need_output_file = true
349
397
  end
350
398
 
351
399
  opt.on("-F", "--force",
352
- "Force to apply command line options.(default: false)") do |force|
400
+ "Force to apply command line options. \
401
+ (default: false)") do |force|
353
402
  self[:force] = force
354
403
  end
355
404
 
356
405
  opt.on("-m [contents-title]", "--table-of-contents [=contents-title]",
357
- "Include the list of h2 and/or h3 headings with ids.(default: nil)") do |toc_title|
406
+ "Include the list of h2 and/or h3 headings with ids. \
407
+ (default: nil)") do |toc_title|
358
408
  self[:toc] = toc_title
359
409
  end
360
410
 
@@ -363,6 +413,14 @@ USAGE: #{File.basename(__FILE__)} [options]") do |opt|
363
413
  self[:split_main_heading] = should_be_split
364
414
  end
365
415
 
416
+ opt.on("-W", "--with-wikiname",
417
+ "Use WikiNames") do |with_wikiname|
418
+ if with_wikiname
419
+ auto_linker = PseudoHiki::AutoLink::WikiName.new
420
+ PseudoHiki::BlockParser.auto_linker = auto_linker
421
+ end
422
+ end
423
+
366
424
  opt.parse!
367
425
  end
368
426
  end
@@ -370,11 +428,11 @@ USAGE: #{File.basename(__FILE__)} [options]") do |opt|
370
428
  def check_argv
371
429
  case ARGV.length
372
430
  when 0
373
- if self.need_output_file and not self[:output]
431
+ if @need_output_file and not self[:output]
374
432
  raise "You must specify a file name for output"
375
433
  end
376
434
  when 1
377
- self.read_input_filename(ARGV[0])
435
+ read_input_filename(ARGV[0])
378
436
  end
379
437
  end
380
438
 
@@ -396,33 +454,34 @@ USAGE: #{File.basename(__FILE__)} [options]") do |opt|
396
454
  end
397
455
 
398
456
  def create_html_template_with_current_options
399
- return [] unless self.html_template
400
- html = self.html_template.new
401
- html.charset = self.charset
457
+ return [] unless html_template
458
+ html = html_template.new
459
+ html.charset = charset
402
460
  html.language = self[:lang]
403
461
  html.default_css = self[:css] if self[:css]
404
- html.base = self.base if self[:base]
405
- html.title = self.title
462
+ html.base = base if self[:base]
463
+ html.title = title
406
464
  html
407
465
  end
408
466
 
409
467
  def read_input_filename(filename)
410
468
  @input_file_dir, @input_file_name = File.split(File.expand_path(filename))
411
- @input_file_basename = File.basename(@input_file_name,".*")
469
+ @input_file_basename = File.basename(@input_file_name, ".*")
412
470
  end
413
471
 
414
472
  def output_filename
415
- return nil unless self.need_output_file
473
+ return nil unless @need_output_file
416
474
  if self[:output]
417
475
  File.expand_path(self[:output])
418
476
  else
419
- File.join(@input_file_dir, @input_file_basename + self[:html_version].ext)
477
+ ext = self[:html_version].ext
478
+ File.join(@input_file_dir, @input_file_basename + ext)
420
479
  end
421
480
  end
422
481
 
423
482
  def open_output
424
- if self.output_filename
425
- open(self.output_filename, "w") {|f| yield f }
483
+ if output_filename
484
+ open(output_filename, "w") {|f| yield f }
426
485
  else
427
486
  yield STDOUT
428
487
  end