pseudohikiparser 0.0.0.11.develop → 0.0.0.12.develop

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5b41d1dc1538c8a205df9d0e3674ce36cfe7a269
4
- data.tar.gz: 4d41b79b26ea37bac306dcb392f9e413dfab0be5
3
+ metadata.gz: ab6d03f5f2b3131e62af81faa6540355f115b489
4
+ data.tar.gz: d95e43ed55af9b8b0ecb6868b7075315e1a8e5e2
5
5
  SHA512:
6
- metadata.gz: ad7e6d96413aebd099166d449b57c83ca4a816130daef33ed962c3d87f02d1fad5afeb1b7aed576034bb600121fe61590ebe0b4ec15d3f4daedcea7bc048f962
7
- data.tar.gz: 0320942f7181a5c045ea2a28d41a932ee0508d6dc5f438958e3e539a05861efd9f5c908d37f05ae8062551df174dfca8e4c5a69c9803b31d70e08dbc55877cd4
6
+ metadata.gz: 66e3bec04f94faa3cbbd21b6e945ad46e23e58d1ffd8b0e36cb1c400e4caee43a4e9ce55e0fdfd70bf5ce6b65a5bf877f979882ae6190f348db5cbdef7cea392
7
+ data.tar.gz: 7a0be29c24383e9ff375404413df96ca209d7c885dc13eec566828c84ad19dd7cbd9a6029e7cbb0cadaa280aa5746dad8c5bf34e0fc5620db99a2bf962c3d1ac
@@ -1,415 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
- # -*- coding: utf-8 -*-
3
2
 
4
- require 'optparse'
5
- require 'erb'
6
- require 'pseudohiki/blockparser'
7
- require 'pseudohiki/htmlformat'
8
- require 'pseudohiki/plaintextformat'
9
- require 'pseudohiki/markdownformat'
10
- require 'htmlelement/htmltemplate'
11
- require 'htmlelement'
12
-
13
- module PseudoHiki
14
- class PageComposer
15
- HEADING_WITH_ID_PAT = /^(!{2,3})\[([A-Za-z][0-9A-Za-z_\-.:]*)\]\s*/o
16
-
17
- PlainFormat = PlainTextFormat.create
18
-
19
- def initialize(options)
20
- @options = options
21
- end
22
-
23
- def formatter
24
- @formatter ||= @options.html_template.new
25
- end
26
-
27
- def to_plain(line)
28
- PlainFormat.format(BlockParser.parse(line.lines.to_a)).to_s.chomp
29
- end
30
-
31
- def create_plain_table_of_contents(lines)
32
- toc_lines = lines.grep(HEADING_WITH_ID_PAT).map do |line|
33
- m = HEADING_WITH_ID_PAT.match(line)
34
- heading_depth = m[1].length
35
- line.sub(/^!+/o, '*'*heading_depth)
36
- end
37
-
38
- @options.formatter.format(BlockParser.parse(toc_lines))
39
- end
40
-
41
- def create_html_table_of_contents(lines)
42
- toc_lines = lines.grep(HEADING_WITH_ID_PAT).map do |line|
43
- m = HEADING_WITH_ID_PAT.match(line)
44
- heading_depth, id = m[1].length, m[2].upcase
45
- "%s[[%s|#%s]]"%['*'*heading_depth, to_plain(line.sub(HEADING_WITH_ID_PAT,'')), id]
46
- end
47
- @options.formatter.format(BlockParser.parse(toc_lines)).tap do |toc|
48
- toc.traverse do |element|
49
- if element.kind_of? HtmlElement and element.tagname == "a"
50
- element["title"] = "toc_item: " + element.children.join.chomp
51
- end
52
- end
53
- end
54
- end
55
-
56
- def create_table_of_contents(lines)
57
- return "" unless @options[:toc]
58
- return create_plain_table_of_contents(lines) unless @options.html_template
59
- create_html_table_of_contents(lines)
60
- end
61
-
62
- def split_main_heading(input_lines)
63
- return "" unless @options[:split_main_heading]
64
- h1_pos = input_lines.find_index {|line| /^![^!]/o =~ line }
65
- return "" unless h1_pos
66
- tree = BlockParser.parse([input_lines.delete_at(h1_pos)])
67
- @options.formatter.format(tree)
68
- end
69
-
70
- def create_plain_main(toc, body, h1)
71
- contents = [body]
72
- contents.unshift toc unless toc.empty?
73
- contents.unshift @options.formatter.format(BlockParser.parse("!!" + @options[:toc])) if @options[:toc]
74
- contents.unshift h1 unless h1.empty?
75
- contents.join($/)
76
- end
77
-
78
- def create_html_main(toc, body, h1)
79
- return nil unless @options[:toc]
80
- toc_container = formatter.create_element("section").tap do |element|
81
- element["id"] = "toc"
82
- element.push formatter.create_element("h2", @options[:toc]) unless @options[:toc].empty?
83
- element.push toc
84
- end
85
- contents_container = formatter.create_element("section").tap do |element|
86
- element["id"] = "contents"
87
- element.push body
88
- end
89
- main = formatter.create_element("section").tap do |element|
90
- element["id"] = "main"
91
- element.push h1 unless h1.empty?
92
- element.push toc_container
93
- element.push contents_container
94
- end
95
- end
96
-
97
- def create_main(toc, body, h1)
98
- return create_plain_main(toc, body, h1) unless @options.html_template
99
- create_html_main(toc, body, h1)
100
- end
101
-
102
- def create_style(path_to_css_file)
103
- style = formatter.create_element("style").tap do |element|
104
- element["type"] = "text/css"
105
- open(File.expand_path(path_to_css_file)) do |css_file|
106
- element.push css_file.read
107
- end
108
- end
109
- end
110
-
111
- def compose_body(input_lines)
112
- tree = BlockParser.parse(input_lines)
113
- @options.formatter.format(tree)
114
- end
115
-
116
- def compose_html(input_lines)
117
- h1 = split_main_heading(input_lines)
118
- css = @options[:css]
119
- toc = create_table_of_contents(input_lines)
120
- body = compose_body(input_lines)
121
- title = @options.title
122
- main = create_main(toc,body, h1)
123
-
124
- if @options[:template]
125
- erb = ERB.new(@options.read_template_file)
126
- html = erb.result(binding)
127
- else
128
- html = @options.create_html_template_with_current_options
129
- html.head.push create_style(@options[:embed_css]) if @options[:embed_css]
130
- html.push main||body
131
- end
132
-
133
- html
134
- end
135
- end
136
-
137
- class OptionManager
138
- include HtmlElement::CHARSET
139
-
140
- PlainVerboseFormat = PlainTextFormat.create(:verbose_mode => true)
141
- MDFormat = MarkDownFormat.create
142
- GFMFormat = MarkDownFormat.create(:gfm_style => true)
143
-
144
- class Formatter < Struct.new(:version, :formatter, :template, :ext, :opt_pat)
145
- end
146
-
147
- VERSIONS = [
148
- ["html4", HtmlFormat, HtmlTemplate, ".html", /^h/io],
149
- ["xhtml1", XhtmlFormat, XhtmlTemplate, ".html", /^x/io],
150
- ["html5", Xhtml5Format, Xhtml5Template, ".html", /^h5/io],
151
- ["plain", PageComposer::PlainFormat, nil, ".plain", /^p/io],
152
- ["plain_verbose", PlainVerboseFormat, nil, ".plain", /^pv/io],
153
- ["markdown", MDFormat, nil, ".md", /^m/io],
154
- ["gfm", GFMFormat, nil, ".md", /^g/io]
155
- ].map {|args| Formatter.new(*args) }
156
-
157
- ENCODING_REGEXP = {
158
- /^u/io => 'utf8',
159
- /^e/io => 'euc-jp',
160
- /^s/io => 'sjis',
161
- /^l[a-zA-Z]*1/io => 'latin1'
162
- }
163
-
164
- BOM = "\xef\xbb\xbf"
165
- BOM.force_encoding("ASCII-8BIT") if BOM.respond_to? :encoding
166
- FILE_HEADER_PAT = /^\/\//
167
-
168
- ENCODING_TO_CHARSET = {
169
- 'utf8' => UTF8,
170
- 'euc-jp' => EUC_JP,
171
- 'sjis' => SJIS,
172
- 'latin1' => LATIN1
173
- }
174
-
175
- attr_accessor :need_output_file, :default_title
176
- attr_reader :input_file_basename
177
-
178
- def self.remove_bom(input=ARGF)
179
- bom = input.read(3)
180
- input.rewind unless BOM == bom
181
- end
182
-
183
- def initialize(options=nil)
184
- @options = options||{
185
- :html_version => VERSIONS[0],
186
- :lang => 'en',
187
- :encoding => 'utf8',
188
- :title => nil,
189
- :css => "default.css",
190
- :embed_css => nil,
191
- :base => nil,
192
- :template => nil,
193
- :output => nil,
194
- :force => false,
195
- :toc => nil,
196
- :split_main_heading => false
197
- }
198
- @written_option_pat = {}
199
- @options.keys.each {|opt| @written_option_pat[opt] = /^\/\/#{opt}:\s*(.*)$/ }
200
- end
201
-
202
- def [](key)
203
- @options[key]
204
- end
205
-
206
- def[]=(key, value)
207
- @options[key] = value
208
- end
209
-
210
- def win32?
211
- true if RUBY_PLATFORM =~ /win/i
212
- end
213
-
214
- def value_given?(value)
215
- value and not value.empty?
216
- end
217
-
218
- def html_template
219
- self[:html_version].template
220
- end
221
-
222
- def formatter
223
- self[:html_version].formatter
224
- end
225
-
226
- def charset
227
- ENCODING_TO_CHARSET[self[:encoding]]
228
- end
229
-
230
- def base
231
- base_dir = self[:base]
232
- if base_dir and base_dir !~ /[\/\\]\.*$/o
233
- base_dir = File.join(base_dir,".")
234
- base_dir = "file:///"+base_dir if base_dir !~ /^\./o and win32?
235
- end
236
- base_dir
237
- end
238
-
239
- def title
240
- self[:title]||@default_title||"-"
241
- end
242
-
243
- def read_template_file
244
- File.read(File.expand_path(self[:template]), :encoding => self.charset)
245
- end
246
-
247
- def set_html_version(version)
248
- VERSIONS.each do |v|
249
- if v.version == version
250
- return self[:html_version] = v
251
- else
252
- self[:html_version] = v if v.opt_pat =~ version
253
- end
254
- end
255
- STDERR.puts "\"#{version}\" is an invalid option for --format-version. \"#{self[:html_version].version}\" is chosen instead."
256
- end
257
-
258
- def set_html_encoding(given_opt)
259
- if ENCODING_REGEXP.values.include? given_opt
260
- self[:encoding] = given_opt
261
- else
262
- ENCODING_REGEXP.each do |pat, encoding|
263
- self[:encoding] = encoding if pat =~ given_opt
264
- end
265
- STDERR.puts "\"#{self[:encoding]}\" is chosen as an encoding system, instead of \"#{given_opt}\"."
266
- end
267
- end
268
-
269
- def set_encoding(given_opt)
270
- return nil unless String.new.respond_to? :encoding
271
- external, internal = given_opt.split(/:/o)
272
- Encoding.default_external = external if external
273
- Encoding.default_interanl = internal if internal
274
- end
275
-
276
- def parse_command_line_options
277
- OptionParser.new("** Convert texts written in a Hiki-like notation into HTML **
278
- USAGE: #{File.basename(__FILE__)} [options]") do |opt|
279
- opt.on("-f [html_version]", "--format-version [=format_version]",
280
- "HTML version to be used. Choose html4, xhtml1, html5, plain, plain_verbose, markdown or gfm (default: #{self[:html_version].version})") do |version|
281
- self.set_html_version(version)
282
- end
283
-
284
- opt.on("-l [lang]", "--lang [=lang]",
285
- "Set the value of charset attributes (default: #{self[:lang]})") do |lang|
286
- self[:lang] = lang if value_given?(lang)
287
- end
288
-
289
- opt.on("-e [encoding]", "--format-encoding [=encoding]",
290
- "Available options: utf8, euc-jp, sjis, latin1 (default: #{self[:encoding]})") do |given_opt|
291
- self.set_html_encoding(given_opt)
292
- end
293
-
294
- opt.on("-E [ex[:in]]", "--encoding [=ex[:in]]",
295
- "Specify the default external and internal character encodings (same as the option of MRI") do |given_opt|
296
- self.set_encoding(given_opt)
297
- end
298
-
299
- #use '-w' to avoid the conflict with the short option for '[-t]emplate'
300
- opt.on("-w [(window) title]", "--title [=title]",
301
- "Set the value of the <title> element (default: the basename of the input file)") do |title|
302
- self[:title] = title if value_given?(title)
303
- end
304
-
305
- opt.on("-c [css]", "--css [=css]",
306
- "Set the path to a css file to be used (default: #{self[:css]})") do |css|
307
- self[:css] = css
308
- end
309
-
310
- opt.on("-C [path_to_css_file]", "--embed-css [=path_to_css_file]",
311
- "Set the path to a css file to embed (default: not to embed)") do |path_to_css_file|
312
- self[:embed_css] = path_to_css_file
313
- end
314
-
315
- opt.on("-b [base]", "--base [=base]",
316
- "Specify the value of href attribute of the <base> element (default: not specified)") do |base_dir|
317
- self[:base] = base_dir if value_given?(base_dir)
318
- end
319
-
320
- opt.on("-t [template]", "--template [=template]",
321
- "Specify a template file written in eruby format with \"<%= body %>\" inside (default: not specified)") do |template|
322
- self[:template] = template if value_given?(template)
323
- end
324
-
325
- opt.on("-o [output]", "--output [=output]",
326
- "Output to the specified file. If no file is given, \"[input_file_basename].html\" will be used.(default: STDOUT)") do |output|
327
- self[:output] = File.expand_path(output) if value_given?(output)
328
- self.need_output_file = true
329
- end
330
-
331
- opt.on("-F", "--force",
332
- "Force to apply command line options.(default: false)") do |force|
333
- self[:force] = force
334
- end
335
-
336
- opt.on("-m [contents-title]", "--table-of-contents [=contents-title]",
337
- "Include the list of h2 and/or h3 headings with ids.(default: nil)") do |toc_title|
338
- self[:toc] = toc_title
339
- end
340
-
341
- opt.on("-s", "--split-main-heading",
342
- "Split the first h1 element") do |should_be_split|
343
- self[:split_main_heading] = should_be_split
344
- end
345
-
346
- opt.parse!
347
- end
348
- end
349
-
350
- def check_argv
351
- case ARGV.length
352
- when 0
353
- if self.need_output_file and not self[:output]
354
- raise "You must specify a file name for output"
355
- end
356
- when 1
357
- self.read_input_filename(ARGV[0])
358
- end
359
- end
360
-
361
- def set_options_from_command_line
362
- parse_command_line_options
363
- check_argv
364
- @default_title = @input_file_basename
365
- end
366
-
367
- def set_options_from_input_file(input_lines)
368
- input_lines.each do |line|
369
- break if FILE_HEADER_PAT !~ line
370
- line = line.chomp
371
- @options.keys.each do |opt|
372
- if @written_option_pat[opt] =~ line and not self[:force]
373
- self[opt] = $1
374
- end
375
- end
376
- end
377
- end
378
-
379
- def create_html_template_with_current_options
380
- return [] unless self.html_template
381
- html = self.html_template.new
382
- html.charset = self.charset
383
- html.language = self[:lang]
384
- html.default_css = self[:css] if self[:css]
385
- html.base = self.base if self[:base]
386
- html.title = self.title
387
- html
388
- end
389
-
390
- def read_input_filename(filename)
391
- @input_file_dir, @input_file_name = File.split(File.expand_path(filename))
392
- @input_file_basename = File.basename(@input_file_name,".*")
393
- end
394
-
395
- def output_filename
396
- return nil unless self.need_output_file
397
- if self[:output]
398
- File.expand_path(self[:output])
399
- else
400
- File.join(@input_file_dir, @input_file_basename + self[:html_version].ext)
401
- end
402
- end
403
-
404
- def open_output
405
- if self.output_filename
406
- open(self.output_filename, "w") {|f| yield f }
407
- else
408
- yield STDOUT
409
- end
410
- end
411
- end
412
- end
3
+ require 'pseudohiki/converter'
413
4
 
414
5
  options = PseudoHiki::OptionManager.new
415
6
  options.set_options_from_command_line