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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 32c71494df02c4ef6701259bd2f7731e2ec14508
4
- data.tar.gz: fb7bceffb5fc2f9d67c6959bd71485862e71bff2
3
+ metadata.gz: 685e26157a454005d4d71337bbe18cac722efa11
4
+ data.tar.gz: a8edea51f0aa148d8e78647b0f36702226c742f0
5
5
  SHA512:
6
- metadata.gz: 2a3a20edf96dba9d41d837dc44009f4b1bb6eb6136476abd08cfaf882bcde8a213ded999647f2a067548b7b3f089e768390399d7e8f69fdccdbb6f4bcdff871b
7
- data.tar.gz: 14cb9c5b77e7e4cdc9f153e91c0c8d2f4ae85a292637dcfa5c55d0982ef5b3adb3faa92e140184f318e33b76c00e1106affabf252c270d38e3d4aeca1e369ca5
6
+ metadata.gz: 5b8daca9efc17ba0da4cb70aa5e6f44960ee6e2b82205e84e690106e765655c75079d49033b929a8f77e0e8db5be4df1216ce1bc0ba602ce4a81f9d9c22802f0
7
+ data.tar.gz: 913060555b63ba9f2aff1e98ef2ee025a64dc442270a70285f9626ea87196be665bac45731c018e251cf9d86fe237844d3ba1c2b53fb8218e6772ddc247345ca
data/README.ja.md CHANGED
@@ -1,7 +1,7 @@
1
1
  PseudoHikiParser
2
2
  ================
3
3
 
4
- PseudoHikiParserは[Hiki](http://hikiwiki.org/en/)に似た記法で書かれたテキストをHTMLその他のファイル形式に変換するコンバータです。
4
+ PseudoHikiParserは[Hiki](https://github.com/hiki/hikidoc)に似た記法で書かれたテキストをHTML・Markdownその他のファイル形式に変換するコンバータです。
5
5
 
6
6
  このツールは次の目的を念頭において作成中です。
7
7
 
@@ -148,6 +148,45 @@ The first paragraph
148
148
 
149
149
  HtmlFormat以外にはXhtmlFormat、Xhtml5Format、PlainTextFormat、MarkDownFormatが用意されています。
150
150
 
151
+ #### WikiNames
152
+
153
+ もしWikiNameを利用したければ、PseudoHiki::AutoLink::[WikiName](https://github.com/nico-hn/PseudoHikiParser/blob/develop/lib/pseudohiki/autolink.rb#L11)クラスのインスタンスをBlockParser.newの引数、もしくはBlockParser.parseの第2引数として渡してやる必要があります。
154
+
155
+ ```ruby
156
+ require 'pseudohiki/blockparser'
157
+ require 'pseudohiki/htmlformat'
158
+ require 'pseudohiki/autolink' # PseudoHiki::AutoLink::WikiName is defined in this file.
159
+
160
+ text = <<TEXT
161
+ a line with an ^EscapedWikiName and a WikiName.
162
+ TEXT
163
+
164
+ puts "--- with default options:"
165
+ wiki_name_link = PseudoHiki::AutoLink::WikiName.new
166
+ tree = PseudoHiki::BlockParser.parse(text, wiki_name_link)
167
+ puts PseudoHiki::XhtmlFormat.format(tree)
168
+
169
+ puts "--- when :escape_wiki_name option is set to true:"
170
+ escape_wiki_name_link = PseudoHiki::AutoLink::WikiName.new({:escape_wiki_name => true})
171
+ escaped_tree = PseudoHiki::BlockParser.parse(text, escape_wiki_name_link)
172
+ puts PseudoHiki::XhtmlFormat.format(escaped_tree)
173
+ ```
174
+
175
+ は次のように出力します。
176
+
177
+ ```
178
+ --- with default options:
179
+ <p>
180
+ a line with an ^<a href="EscapedWikiName">EscapedWikiName</a> and a <a href="WikiName">WikiName</a>.
181
+ </p>
182
+ --- when :escape_wiki_name option is set to true:
183
+ <p>
184
+ a line with an EscapedWikiName and a <a href="WikiName">WikiName</a>.
185
+ </p>
186
+ ```
187
+
188
+ またもしデフォルトの動作が気に入らなければ、AutoLink::[WikiName](https://github.com/nico-hn/PseudoHikiParser/blob/develop/lib/pseudohiki/autolink.rb#L11)を置き換えるクラスあるいはモジュールを用意することもできます。
189
+
151
190
  ### PseudoHiki::Formatクラス
152
191
 
153
192
  PseudoHiki::BlockParser.parseで作られた構文木を使い回す必要がなければ、以下のPseudoHiki::Formatのクラスメソッドも利用可能です。
@@ -176,12 +215,12 @@ TEXT
176
215
  puts PseudoHiki::Format.to_html(hiki_text)
177
216
  ```
178
217
 
179
- ## オリジナルの[Hiki記法](http://rabbit-shocker.org/en/hiki.html)にある機能の実装状況
218
+ ## オリジナルの[Hiki記法](https://github.com/hiki/hikidoc/blob/master/TextFormattingRules.ja.md)にある機能の実装状況
180
219
 
181
220
  * パラグラフ - 使いものになる
182
221
  * リンク
183
- * WikiNames - 未サポート(実装予定なし)
184
- * ページへのリンク - これも未サポート
222
+ * WikiNames - オプションとして提供されているが十分にテストされていない
223
+ * ページへのリンク - 未サポート
185
224
  * 任意のURLへのリンク - 一応使えるはず
186
225
  * 整形済みテキスト - 使いものになる
187
226
  * 文字の修飾 - 一部をサポート
@@ -254,7 +293,7 @@ And {{ and }} sould be rendered as two left curly braces and two right curly bra
254
293
 
255
294
  ```html
256
295
  <a href="http://www.example.org/image.png"><img alt="thumbnail of an image" src="http://www.example.org/image_thumb.png">
257
- </a></p>
296
+ </a>
258
297
  ```
259
298
 
260
299
  ### 実験的な機能
@@ -287,13 +326,87 @@ paragraph
287
326
  </div>
288
327
  ```
289
328
 
329
+ #### セクションの定義
330
+
331
+ ドキュメントの一部を`//@begin[section\_name]`と`//@end[section\_name]`で囲むと、HtmlFormatとその派生クラスではこれらのタグが classまたはid属性の設定された\<div\>あるいは\<section\>要素に変換されます。
332
+
333
+ ```
334
+ !! title
335
+
336
+ paragraph 0
337
+
338
+ //@begin[main-part]
339
+
340
+ !!! main part subtitle 1
341
+
342
+ paragraph 1
343
+
344
+ !!! main part subtitle 2
345
+
346
+ paragraph 2
347
+
348
+ //@end[main-part]
349
+
350
+ //@begin[additional-part]
351
+
352
+ !!! additional part subtitle
353
+
354
+ paragraph 3
355
+
356
+ //@end[additional-part]
357
+
358
+ ```
359
+
360
+ は次のように変換されます。
361
+
362
+ ```html
363
+ <div class="section h2">
364
+ <h2> title
365
+ </h2>
366
+ <p>
367
+ paragraph 0
368
+ </p>
369
+ <div class="section main-part">
370
+ <div class="section h3">
371
+ <h3> main part subtitle 1
372
+ </h3>
373
+ <p>
374
+ paragraph 1
375
+ </p>
376
+ <!-- end of section h3 -->
377
+ </div>
378
+ <div class="section h3">
379
+ <h3> main part subtitle 2
380
+ </h3>
381
+ <p>
382
+ paragraph 2
383
+ </p>
384
+ <!-- end of section h3 -->
385
+ </div>
386
+ <!-- end of section main-part -->
387
+ </div>
388
+ <div class="section additional-part">
389
+ <div class="section h3">
390
+ <h3> additional part subtitle
391
+ </h3>
392
+ <p>
393
+ paragraph 3
394
+ </p>
395
+ <!-- end of section h3 -->
396
+ </div>
397
+ <!-- end of section additional-part -->
398
+ </div>
399
+ <!-- end of section h2 -->
400
+ </div>
401
+ ```
402
+
290
403
  ### 未実装の機能
291
404
 
292
405
  ## Visitorクラス
293
406
 
294
407
  以下のクラスのうちの一部は、部分的にしか実装されていないかテストが十分ではないことにご注意ください。
295
408
 
296
- ### [HtmlFormat](https://github.com/nico-hn/PseudoHikiParser/blob/develop/lib/pseudohiki/htmlformat.rb#L8), [XhtmlFormat](https://github.com/nico-hn/PseudoHikiParser/blob/develop/lib/pseudohiki/htmlformat.rb#L263)
409
+ ### [HtmlFormat](https://github.com/nico-hn/PseudoHikiParser/blob/develop/lib/pseudohiki/htmlformat.rb#L8), [XhtmlFormat](https://github.com/nico-hn/PseudoHikiParser/blob/develop/lib/pseudohiki/htmlformat.rb#L312)
297
410
 
298
411
  これらのクラスのクラスメソッド(HtmlFormat|XhtmlFormat).formatは[HtmlElement](https://github.com/nico-hn/PseudoHikiParser/blob/develop/lib/htmlelement.rb)オブジェクトを木にしたものを返すため、以下の例のように後から手を加えることができます。
299
412
 
@@ -337,11 +450,11 @@ paragraph 2 that contains <a class="pdf" href="http://www.example.org/example.pd
337
450
  </div>
338
451
  ```
339
452
 
340
- ### [Xhtml5Format](https://github.com/nico-hn/PseudoHikiParser/blob/develop/lib/pseudohiki/htmlformat.rb#L268)
453
+ ### [Xhtml5Format](https://github.com/nico-hn/PseudoHikiParser/blob/develop/lib/pseudohiki/htmlformat.rb#L318)
341
454
 
342
455
  HTML5への変換用のVisitorクラスです。
343
456
 
344
- 現時点では\<section\>要素の扱い以外に[XhtmlFormat](https://github.com/nico-hn/PseudoHikiParser/blob/develop/lib/pseudohiki/htmlformat.rb#L263)との違いは余りありません。
457
+ 現時点では\<section\>要素の扱い以外に[XhtmlFormat](https://github.com/nico-hn/PseudoHikiParser/blob/develop/lib/pseudohiki/htmlformat.rb#L312)との違いは余りありません。
345
458
 
346
459
  ### [PlainTextFormat](https://github.com/nico-hn/PseudoHikiParser/blob/develop/lib/pseudohiki/plaintextformat.rb)
347
460
 
@@ -433,3 +546,14 @@ The first paragraph
433
546
  |_cell 1_|cell2 |
434
547
  ```
435
548
 
549
+ #### 制限事項
550
+
551
+ このVisitorクラスではきちんと構成されていないリストを変換できません。リストの項目は階層に従った入れ子になっていなければならず、もし入れ子のレベルに飛びがあると変換結果がおかしくなります。
552
+
553
+ 以下が最初のレベルを飛ばしてしまいきちんと構成されていないリストの例です。
554
+
555
+ ```
556
+ **First item
557
+ **Second item
558
+ ```
559
+
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  PseudoHikiParser
2
2
  ================
3
3
 
4
- PseudoHikiParser is a converter of texts written in a [Hiki](http://hikiwiki.org/en/) like notation, into HTML or other formats.
4
+ PseudoHikiParser is a converter of texts written in a [Hiki](https://github.com/hiki/hikidoc) like notation, into HTML, Markdown or other formats.
5
5
 
6
6
  I am writing this tool with following objectives in mind,
7
7
 
@@ -148,6 +148,45 @@ In the example above, HtmlFormat is a visitor class that converts the parsed tex
148
148
 
149
149
  Other than HtmlFormat, XhtmlFormat, Xhtml5Format, PlainTextFormat and MarkDownFormat are available.
150
150
 
151
+ #### WikiNames
152
+
153
+ If you want to use WikiNames, you have to pass an instance of PseudoHiki::AutoLink::[WikiName](https://github.com/nico-hn/PseudoHikiParser/blob/develop/lib/pseudohiki/autolink.rb#L11) as the argument of BlockParser.new or the second argument of BlockParser.parse.
154
+
155
+ ```ruby
156
+ require 'pseudohiki/blockparser'
157
+ require 'pseudohiki/htmlformat'
158
+ require 'pseudohiki/autolink' # PseudoHiki::AutoLink::WikiName is defined in this file.
159
+
160
+ text = <<TEXT
161
+ a line with an ^EscapedWikiName and a WikiName.
162
+ TEXT
163
+
164
+ puts "--- with default options:"
165
+ wiki_name_link = PseudoHiki::AutoLink::WikiName.new
166
+ tree = PseudoHiki::BlockParser.parse(text, wiki_name_link)
167
+ puts PseudoHiki::XhtmlFormat.format(tree)
168
+
169
+ puts "--- when :escape_wiki_name option is set to true:"
170
+ escape_wiki_name_link = PseudoHiki::AutoLink::WikiName.new({:escape_wiki_name => true})
171
+ escaped_tree = PseudoHiki::BlockParser.parse(text, escape_wiki_name_link)
172
+ puts PseudoHiki::XhtmlFormat.format(escaped_tree)
173
+ ```
174
+
175
+ will print
176
+
177
+ ```
178
+ --- with default options:
179
+ <p>
180
+ a line with an ^<a href="EscapedWikiName">EscapedWikiName</a> and a <a href="WikiName">WikiName</a>.
181
+ </p>
182
+ --- when :escape_wiki_name option is set to true:
183
+ <p>
184
+ a line with an EscapedWikiName and a <a href="WikiName">WikiName</a>.
185
+ </p>
186
+ ```
187
+
188
+ And if you don't like the default behavior, you may prepare a class/module that substitutes AutoLink::[WikiName](https://github.com/nico-hn/PseudoHikiParser/blob/develop/lib/pseudohiki/autolink.rb#L11).
189
+
151
190
  ### class PseudoHiki::Format
152
191
 
153
192
  If you don't need to reuse a tree parsed by PseudoHiki::BlockParser.parse, you can use following class methods of PseudoHiki::Format.
@@ -176,12 +215,12 @@ TEXT
176
215
  puts PseudoHiki::Format.to_html(hiki_text)
177
216
  ```
178
217
 
179
- ## Development status of features from the original [Hiki notation](http://rabbit-shocker.org/en/hiki.html)
218
+ ## Development status of features from the original [Hiki notation](https://github.com/hiki/hikidoc/blob/master/TextFormattingRules.md)
180
219
 
181
220
  * Paragraphs - Usable
182
221
  * Links
183
- * WikiNames - Not supported (and would never be)
184
- * Linking to other Wiki pages - Not supported as well
222
+ * WikiNames - Provided as an option but not tested well
223
+ * Linking to other Wiki pages - Not supported
185
224
  * Linking to an arbitrary URL - Maybe usable
186
225
  * Preformatted text - Usable
187
226
  * Text decoration - Partly supported
@@ -254,12 +293,12 @@ will be rendered as
254
293
 
255
294
  ```html
256
295
  <a href="http://www.example.org/image.png"><img alt="thumbnail of an image" src="http://www.example.org/image_thumb.png">
257
- </a></p>
296
+ </a>
258
297
  ```
259
298
 
260
299
  ### Experimental
261
300
 
262
- The following feature is just experimental and available only in [develop branch](https://github.com/nico-hn/PseudoHikiParser/tree/develop).
301
+ The following features are just experimental and available only in [develop branch](https://github.com/nico-hn/PseudoHikiParser/tree/develop).
263
302
 
264
303
  #### Decorator for blocks
265
304
 
@@ -274,7 +313,7 @@ For example,
274
313
  paragraph
275
314
  ```
276
315
 
277
- will be renderes as
316
+ will be rendered as
278
317
 
279
318
  ```html
280
319
  <div class="class_name">
@@ -287,13 +326,87 @@ paragraph
287
326
  </div>
288
327
  ```
289
328
 
329
+ #### Defining sections
330
+
331
+ When a certain part of a document is enclosed by `//@begin[section\_name]` and `//@end[section\_name]`, HtmlFormat and its subclasses will convert the tags into \<div\> or \<section\> elements with id or class attributes.
332
+
333
+ ```
334
+ !! title
335
+
336
+ paragraph 0
337
+
338
+ //@begin[main-part]
339
+
340
+ !!! main part subtitle 1
341
+
342
+ paragraph 1
343
+
344
+ !!! main part subtitle 2
345
+
346
+ paragraph 2
347
+
348
+ //@end[main-part]
349
+
350
+ //@begin[additional-part]
351
+
352
+ !!! additional part subtitle
353
+
354
+ paragraph 3
355
+
356
+ //@end[additional-part]
357
+
358
+ ```
359
+
360
+ will be rendered as
361
+
362
+ ```html
363
+ <div class="section h2">
364
+ <h2> title
365
+ </h2>
366
+ <p>
367
+ paragraph 0
368
+ </p>
369
+ <div class="section main-part">
370
+ <div class="section h3">
371
+ <h3> main part subtitle 1
372
+ </h3>
373
+ <p>
374
+ paragraph 1
375
+ </p>
376
+ <!-- end of section h3 -->
377
+ </div>
378
+ <div class="section h3">
379
+ <h3> main part subtitle 2
380
+ </h3>
381
+ <p>
382
+ paragraph 2
383
+ </p>
384
+ <!-- end of section h3 -->
385
+ </div>
386
+ <!-- end of section main-part -->
387
+ </div>
388
+ <div class="section additional-part">
389
+ <div class="section h3">
390
+ <h3> additional part subtitle
391
+ </h3>
392
+ <p>
393
+ paragraph 3
394
+ </p>
395
+ <!-- end of section h3 -->
396
+ </div>
397
+ <!-- end of section additional-part -->
398
+ </div>
399
+ <!-- end of section h2 -->
400
+ </div>
401
+ ```
402
+
290
403
  ### Not Implemented Yet
291
404
 
292
405
  ## Visitor classes
293
406
 
294
407
  Please note that some of the following classes are implemented partly or not tested well.
295
408
 
296
- ### [HtmlFormat](https://github.com/nico-hn/PseudoHikiParser/blob/develop/lib/pseudohiki/htmlformat.rb#L8), [XhtmlFormat](https://github.com/nico-hn/PseudoHikiParser/blob/develop/lib/pseudohiki/htmlformat.rb#L263)
409
+ ### [HtmlFormat](https://github.com/nico-hn/PseudoHikiParser/blob/develop/lib/pseudohiki/htmlformat.rb#L8), [XhtmlFormat](https://github.com/nico-hn/PseudoHikiParser/blob/develop/lib/pseudohiki/htmlformat.rb#L312)
297
410
 
298
411
  Their class method (HtmlFormat|XhtmlFormat).format returns a tree of [HtmlElement](https://github.com/nico-hn/PseudoHikiParser/blob/develop/lib/htmlelement.rb) objects, and you can traverse the tree as in the following example.
299
412
 
@@ -337,11 +450,11 @@ paragraph 2 that contains <a class="pdf" href="http://www.example.org/example.pd
337
450
  </div>
338
451
  ```
339
452
 
340
- ### [Xhtml5Format](https://github.com/nico-hn/PseudoHikiParser/blob/develop/lib/pseudohiki/htmlformat.rb#L268)
453
+ ### [Xhtml5Format](https://github.com/nico-hn/PseudoHikiParser/blob/develop/lib/pseudohiki/htmlformat.rb#L318)
341
454
 
342
455
  This visitor is for HTML5.
343
456
 
344
- Currently there aren't many differences with [XhtmlFormat](https://github.com/nico-hn/PseudoHikiParser/blob/develop/lib/pseudohiki/htmlformat.rb#L263) exept for the treatment of \<section\> elements.
457
+ Currently there aren't many differences with [XhtmlFormat](https://github.com/nico-hn/PseudoHikiParser/blob/develop/lib/pseudohiki/htmlformat.rb#L312) except for the handling of \<section\> elements.
345
458
 
346
459
  ### [PlainTextFormat](https://github.com/nico-hn/PseudoHikiParser/blob/develop/lib/pseudohiki/plaintextformat.rb)
347
460
 
@@ -433,3 +546,14 @@ The first paragraph
433
546
  |_cell 1_|cell2 |
434
547
  ```
435
548
 
549
+ #### Limitations
550
+
551
+ You can not convert malformed lists with this visitor class. That means list items must be nested hierarchically and if you skip a level in the sequence of items, the result of coversions will be corrupted.
552
+
553
+ The following is an example of malformed list in which the first level is skipped:
554
+
555
+ ```
556
+ **First item
557
+ **Second item
558
+ ```
559
+
data/lib/htmlelement.rb CHANGED
@@ -24,8 +24,8 @@ class HtmlElement
24
24
  LATIN1 = "ISO-8859-1"
25
25
  end
26
26
 
27
- DOCTYPE = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
28
- "http://www.w3.org/TR/html4/loose.dtd">'.split(/\r?\n/o).join($/)+"#{$/}"
27
+ @doctype = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
28
+ "http://www.w3.org/TR/html4/loose.dtd">'.gsub(/\r?\n/o, $/) + $/
29
29
 
30
30
  ESC = {
31
31
  '&' => '&amp;',
@@ -35,9 +35,9 @@ class HtmlElement
35
35
  }
36
36
 
37
37
  DECODE = ESC.invert
38
- CharEntityPat = /#{DECODE.keys.join("|")}/
39
-
40
- Html5Tags = %w(article section hgroup aside nav menu header footer figure details legend)
38
+ @char_entity_pat = /#{DECODE.keys.join("|")}/
39
+
40
+ HTML5_TAGS = %w(article section hgroup aside nav menu header footer figure details legend)
41
41
 
42
42
  ELEMENT_TYPES = {
43
43
  :BLOCK => %w(html body div table colgroup thead tbody ul ol dl head p pre blockquote style),
@@ -45,40 +45,40 @@ class HtmlElement
45
45
  :LIST_ITEM_TYPE_BLOCK => %w(li col),
46
46
  :EMPTY_BLOCK => %w(img meta link base input hr)
47
47
  }
48
-
48
+
49
49
  ELEMENTS_FORMAT = {
50
- :INLINE => "<%s%s>%s</%s>",
51
- :BLOCK => "<%s%s>#{$/}%s</%s>#{$/}",
52
- :HEADING_TYPE_BLOCK => "<%s%s>%s</%s>#{$/}",
53
- :LIST_ITEM_TYPE_BLOCK => "<%s%s>%s#{$/}",
54
- :EMPTY_BLOCK => "<%s%s>#{$/}"
50
+ :INLINE => "<%1$s%2$s>%3$s</%1$s>",
51
+ :BLOCK => "<%1$s%2$s>#{$/}%3$s</%1$s>#{$/}",
52
+ :HEADING_TYPE_BLOCK => "<%1$s%2$s>%3$s</%1$s>#{$/}",
53
+ :LIST_ITEM_TYPE_BLOCK => "<%1$s%2$s>%3$s#{$/}",
54
+ :EMPTY_BLOCK => "<%1$s%2$s>#{$/}"
55
55
  }
56
56
 
57
57
  attr_reader :tagname
58
58
  attr_accessor :parent, :children
59
59
 
60
60
  def self.doctype(encoding="UTF-8")
61
- self::DOCTYPE%[encoding]
61
+ format(@doctype, encoding)
62
62
  end
63
63
 
64
64
  def self.create(tagname, content=nil, attributes={})
65
- if self::Html5Tags.include? tagname
65
+ if self::HTML5_TAGS.include? tagname
66
66
  attributes["class"] = tagname
67
67
  tagname = "div"
68
68
  end
69
- self.new(tagname, content, attributes)
69
+ new(tagname, content, attributes)
70
70
  end
71
71
 
72
- def HtmlElement.comment(content)
72
+ def self.comment(content)
73
73
  "<!-- #{content} -->#{$/}"
74
74
  end
75
75
 
76
- def HtmlElement.urlencode(str)
77
- str.toutf8.gsub(/[^\w\.\-]/o) {|utf8_char| utf8_char.unpack("C*").map {|b| '%%%02X'%[b] }.join }
76
+ def self.urlencode(str)
77
+ str.toutf8.gsub(/[^\w\.\-]/o) {|utf8_char| utf8_char.unpack("C*").map {|b| format('%%%02X', b) }.join }
78
78
  end
79
79
 
80
- def HtmlElement.urldecode(str)
81
- utf = str.gsub(/%\w\w/) {|ch| [ch[-2,2]].pack('H*') }.toutf8
80
+ def self.urldecode(str)
81
+ utf = str.gsub(/%\w\w/) {|ch| [ch[-2, 2]].pack('H*') }.toutf8
82
82
  return utf.tosjis if $KCODE =~ /^s/io
83
83
  return utf.toeuc if $KCODE =~ /^e/io
84
84
  utf
@@ -93,15 +93,15 @@ class HtmlElement
93
93
  tagformats
94
94
  end
95
95
 
96
- def HtmlElement.escape(str)
96
+ def self.escape(str)
97
97
  str.gsub(/[&"<>]/o) {|pat| ESC[pat] }
98
98
  end
99
99
 
100
- def HtmlElement.decode(str)
101
- str.gsub(CharEntityPat) {|ent| DECODE[ent]}
100
+ def self.decode(str)
101
+ str.gsub(@char_entity_pat) {|ent| DECODE[ent] }
102
102
  end
103
103
 
104
- TagFormats = self.assign_tagformats
104
+ TagFormats = assign_tagformats
105
105
 
106
106
  def initialize(tagname, content=nil, attributes={})
107
107
  @parent = nil
@@ -133,25 +133,25 @@ class HtmlElement
133
133
  def [](attribute)
134
134
  @attributes[attribute]
135
135
  end
136
-
136
+
137
137
  def format_attributes
138
- @attributes.collect do |attr,value|
139
- ' %s="%s"'%[attr,HtmlElement.escape(value.to_s)]
138
+ @attributes.collect do |attr, value|
139
+ " #{attr}=\"#{HtmlElement.escape(value.to_s)}\""
140
140
  end.sort.join
141
141
  end
142
142
  private :format_attributes
143
143
 
144
144
  def add_end_comment_for_div_or_section
145
145
  if @tagname == "div" or @tagname == "section" and @end_comment_not_added
146
- id_or_class = self["id"]||self["class"]
147
- self.push HtmlElement.comment("end of #{id_or_class}") if id_or_class
146
+ id_or_class = self["id"] || self["class"]
147
+ push HtmlElement.comment("end of #{id_or_class}") if id_or_class
148
148
  @end_comment_not_added = false
149
149
  end
150
150
  end
151
151
 
152
152
  def to_s
153
153
  add_end_comment_for_div_or_section
154
- self.class::TagFormats[@tagname]%[@tagname, format_attributes, @children, @tagname]
154
+ format(self.class::TagFormats[@tagname], @tagname, format_attributes, @children)
155
155
  end
156
156
  alias to_str to_s
157
157
 
@@ -160,26 +160,26 @@ class HtmlElement
160
160
  @children.traverse(&block)
161
161
  end
162
162
  end
163
-
163
+
164
164
  class XhtmlElement < HtmlElement
165
- DOCTYPE = '<?xml version="1.0" encoding="%s"?>
165
+ @doctype = '<?xml version="1.0" encoding="%s"?>
166
166
  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
167
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'.split(/\r?\n/o).join($/)+"#{$/}"
167
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'.gsub(/\r?\n/o, $/) + $/
168
168
 
169
- ELEMENTS_FORMAT = self.superclass::ELEMENTS_FORMAT.dup
170
- ELEMENTS_FORMAT[:LIST_ITEM_TYPE_BLOCK] = "<%s%s>%s</%s>#{$/}"
171
- ELEMENTS_FORMAT[:EMPTY_BLOCK] = "<%s%s />#{$/}"
169
+ ELEMENTS_FORMAT = superclass::ELEMENTS_FORMAT.dup
170
+ ELEMENTS_FORMAT[:LIST_ITEM_TYPE_BLOCK] = "<%1$s%2$s>%3$s</%1$s>#{$/}"
171
+ ELEMENTS_FORMAT[:EMPTY_BLOCK] = "<%1$s%2$s />#{$/}"
172
172
 
173
- TagFormats = self.assign_tagformats
173
+ TagFormats = assign_tagformats
174
174
  end
175
175
 
176
176
  class Xhtml5Element < XhtmlElement
177
- DOCTYPE = '<?xml version="1.0" encoding="%s"?>
178
- <!DOCTYPE html>'.split(/\r?\n/o).join($/)+"#{$/}"
177
+ @doctype = '<?xml version="1.0" encoding="%s"?>
178
+ <!DOCTYPE html>'.gsub(/\r?\n/o, $/) + $/
179
179
 
180
- ELEMENT_TYPES = self.superclass::ELEMENT_TYPES.dup
181
- ELEMENT_TYPES[:BLOCK] = self.superclass::ELEMENT_TYPES[:BLOCK] + self.superclass::Html5Tags
182
- Html5Tags = %w(main)
180
+ ELEMENT_TYPES = superclass::ELEMENT_TYPES.dup
181
+ ELEMENT_TYPES[:BLOCK] = superclass::ELEMENT_TYPES[:BLOCK] + superclass::HTML5_TAGS
182
+ HTML5_TAGS = %w(main)
183
183
 
184
- TagFormats = self.assign_tagformats
184
+ TagFormats = assign_tagformats
185
185
  end
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pseudohiki/blockparser'
4
+
5
+ module PseudoHiki
6
+ module AutoLink
7
+ # WIKI_NAME_RE is borrowed from hikidoc
8
+ WIKI_NAME_RE = /\^?\b(?:[A-Z]+[a-z\d]+){2,}\b/
9
+ ESCAPE_CHAR = "^"
10
+
11
+ class WikiName
12
+ @default_options = {
13
+ :url => true,
14
+ :wiki_name => true,
15
+ :escape_wiki_name => true
16
+ }
17
+
18
+ def self.default_options
19
+ @default_options
20
+ end
21
+
22
+ def initialize(options={})
23
+ @options = WikiName.default_options.dup.merge!(options)
24
+ @auto_linker = @options[:url] ? URL : Off
25
+ end
26
+
27
+ def auto_link_url?
28
+ @options[:url]
29
+ end
30
+
31
+ def escaped_wiki_name?(wiki_name)
32
+ @options[:escape_wiki_name] and wiki_name.start_with?(ESCAPE_CHAR)
33
+ end
34
+
35
+ def in_link_tag?(preceding_str)
36
+ URL.in_link_tag?(preceding_str)
37
+ end
38
+
39
+ def add_tag(url)
40
+ if escaped_wiki_name?(url)
41
+ url[1..-1]
42
+ elsif url.start_with?(ESCAPE_CHAR)
43
+ "^[[#{url[1..-1]}]]"
44
+ else
45
+ "[[#{url}]]"
46
+ end
47
+ end
48
+
49
+ def link_wiki_name(line)
50
+ return line if WIKI_NAME_RE !~ line or VERBATIM_LEAF_HEAD_RE =~ line
51
+ line.gsub(WIKI_NAME_RE) {|url| in_link_tag?($`) ? url : add_tag(url) }
52
+ end
53
+
54
+ def link(line)
55
+ line = @auto_linker.link(line)
56
+ @options[:wiki_name] ? link_wiki_name(line) : line
57
+ end
58
+ end
59
+ end
60
+ end