nora_mark 0.2beta6 → 0.2beta7

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: ade2dd5b4cdd69d794a353b7753554cee5d147d8
4
- data.tar.gz: e98bc05bb7a68cb64de1d10ecd213d6a4891fd1c
3
+ metadata.gz: 5ee7b20c586d15b36f4f461c63b98335e9396088
4
+ data.tar.gz: 3acba3835a8e034cd17068e3ac437f3a3eede844
5
5
  SHA512:
6
- metadata.gz: 9a04a47daf848c44003e0acaa6c69da73e64c8c1aaa4f445ff36f5bd550f7e37297533c04c572bb1f6110deeb0a3492793cfc80d38f35946a65ff6a5079dc5f7
7
- data.tar.gz: 3e009acb8be92588512b73554abd8f54b126e7ba5c57392d503ad0c609c9f1dbd151e0a07b5fad7d45d231cc9214837cbe6662d1c0133f294a8c11fb2517f363
6
+ metadata.gz: 2dff66fe2c8bd19a830fa4f05b89a3c948f7649a00573cf3e885093a4611100d5a4b7c05af96a138c50a6d6f92a0831ca458b5008b8010244f98791858014d76
7
+ data.tar.gz: dad3396c2af1d582ea7b3479e6d6f88b9394cde4cae304269b349ca18da9175c1d891f10e2a0aff689b4467656f96a85cd1b87cd8bc8392db62c01e8fa06c0ea
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ # version 0.2beta7 (NoraMark beta)
2
+
3
+ * new table of contents feature. assign table of contents heading to every heading element (h1-h2 and Markdown style header)
4
+ * new customize feature Transformer based on parse tree operation
5
+ * new markups including Section header
6
+ * command line tool nora2html
7
+ * and many other changes
8
+
1
9
  # version 0.2beta1 (NoraMark beta)
2
10
  * Change name to NoraMark
3
11
 
data/README.md CHANGED
@@ -1,9 +1,10 @@
1
1
  # NoraMark
2
2
  [<img src="https://secure.travis-ci.org/skoji/noramark.png" />](http://travis-ci.org/skoji/noramark) [![Coverage Status](https://coveralls.io/repos/skoji/noramark/badge.png?branch=master)](https://coveralls.io/r/skoji/noramark?branch=master)
3
+ [![Gem Version](https://badge.fury.io/rb/nora_mark.png)](http://badge.fury.io/rb/nora_mark)
3
4
 
4
5
  NoraMark is a simple text markup language. It is designed to create XHTML files for EPUB books. Its default mode is for Japanese text.
5
6
 
6
- **CAUTION This is very early alpha version, so it's not stable at all, even the markup syntax**
7
+ **CAUTION This is very early alpha version, so it's not stable at all, even the markup syntax will change**
7
8
 
8
9
  In non-beta release version, the syntax will be more stable.
9
10
 
@@ -193,7 +194,90 @@ The converted XHTML file
193
194
  </html>
194
195
 
195
196
 
196
- In a near future version, you will be able to add custom commands.
197
+ ## Customize
198
+
199
+ Simple Customization Sample
200
+
201
+ Markup text and the code
202
+ ```ruby
203
+ text =<<EOF
204
+ speak(Alice): Alice is speaking.
205
+ speak(Bob): and this is Bob.
206
+ EOF
207
+
208
+ document = NoraMark::Document.parse(text)
209
+ document.add_transformer(generator: :html) do
210
+ for_node("speak", :modify) do # "speak" is selector for node. :modify is action.
211
+ @node.name = 'p'
212
+ @node.prepend_child inline('span', @node.parameters[0], classes: ['speaker'])
213
+ end
214
+ end
215
+ puts document.html[0]
216
+
217
+ ```
218
+
219
+ Rendered XHTML
220
+ ```
221
+ <?xml version="1.0" encoding="UTF-8"?>
222
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
223
+ <head>
224
+ <title>NoraMark generated document</title>
225
+ </head>
226
+ <body>
227
+ <p><span class='speaker'>Alice</span>Alice is speaking.</p>
228
+ <p><span class='speaker'>Bob</span>and this is Bob.</p>
229
+ </body>
230
+ </html>
231
+ ```
232
+
233
+ Another Example
234
+
235
+ ```
236
+ text = <<EOF
237
+ ---
238
+ lang: ja
239
+ ---
240
+
241
+ =: 見出し
242
+
243
+ パラグラフ。
244
+ パラグラフ。
245
+ EOF
246
+
247
+ document = NoraMark::Document.parse(text)
248
+ document.add_transformer(generator: :html) do
249
+ for_node({:type => :HeadedSection}, :replace) do
250
+ header = block('header',
251
+ block('div',
252
+ block("h#{@node.level}", @node.heading),
253
+ classes: ['hgroup']))
254
+ body = block('div', @node.children, classes:['section-body'])
255
+ block('section', [ header, body ], inherit: true)
256
+ end
257
+ end
258
+
259
+ puts document.html[0]
260
+ ```
261
+
262
+ Result.
263
+ ```
264
+ <?xml version="1.0" encoding="UTF-8"?>
265
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
266
+ <head>
267
+ <title>NoraMark generated document</title>
268
+ </head>
269
+ <body>
270
+ <section><header><div class='hgroup'><h1 id='heading_index_1'>見出し</h1>
271
+ </div>
272
+ </header>
273
+ <div class='section-body'><div class='pgroup'><p>パラグラフ。</p>
274
+ <p>パラグラフ。</p>
275
+ </div>
276
+ </div>
277
+ </section>
278
+ </body>
279
+ </html>
280
+ ```
197
281
 
198
282
  ## Contributing
199
283
 
@@ -0,0 +1,19 @@
1
+ /*
2
+ nora-simple-ja.css
3
+ simple css for NoraMark japanese text
4
+ */
5
+
6
+ p {
7
+ text-indent: 1em;
8
+ margin-top: 0;
9
+ margin-bottom: 0;
10
+ }
11
+
12
+ .noindent {
13
+ text-indent: 0;
14
+ }
15
+
16
+ .pgroup {
17
+ margin-top 1em;
18
+ }
19
+
@@ -1,3 +1,8 @@
1
+ /*
2
+ nora-simple.css
3
+ simple css for NoraMark text
4
+ */
5
+
1
6
  body {
2
7
  font-family: serif, sans-serif;
3
8
  line-height: 1.75;
@@ -6,25 +11,10 @@ body {
6
11
 
7
12
  h1, h2, h3, h4, h5, h6 {
8
13
  font-family: sans-serif;
9
- color: #884444;
10
14
  }
11
15
 
12
16
  dt {
13
17
  font-family: sans-serif;
14
- color: #404040;
15
- }
16
-
17
- p {
18
- text-indent: 1em;
19
- margin-top: 0;
20
- margin-bottom: 0;
21
- }
22
- .noindent {
23
- text-indent: 0;
24
- }
25
-
26
- .pgroup {
27
- margin-top 1em;
28
18
  }
29
19
 
30
20
  pre {
@@ -35,6 +25,7 @@ pre {
35
25
  border: 1px solid #aaaaaa;
36
26
  border-radius: 0.5em;
37
27
  }
28
+
38
29
  pre.code-html {
39
30
  background: #efefef;
40
31
  }
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  lang: ja
3
- stylesheets: nora-simple.css
3
+ stylesheets: [nora-simple.css, nora-simple-ja.css]
4
4
  title: NoraMark Manual
5
5
  ---
6
6
 
@@ -243,8 +243,30 @@ code(変換結果) {//html
243
243
 
244
244
  ====: 番号つきリスト
245
245
 
246
+ pre(原稿) {//
247
+ 1: 数字:ではじまる行は、番号つきリストになる。
248
+ 2: 空行があくまで、リストがつづく。
249
+
250
+ 3: 空行があくと、あらたなリストになる。
251
+ 10: 先頭の数字にかかわらず、1から順に番号がふられる。
252
+ //}
253
+
254
+ code(変換結果) {//html
255
+ <ol><li>数字:ではじまる行は、番号つきリストになる。 </li>
256
+ <li>空行があくまで、リストがつづく。</li>
257
+ </ol>
258
+ <ol><li>空行があくと、あらたなリストになる。</li>
259
+ <li>先頭の数字にかかわらず、1から順に番号がふられる。</li>
260
+ </ol>
261
+ }
262
+ //}
263
+
246
264
  ====: 定義リスト
247
265
 
266
+ =====: 1行の定義
267
+
268
+ =====: 複数行の定義
269
+
248
270
  ===: 見出し
249
271
 
250
272
  ====: 単独の見出し
@@ -3,9 +3,10 @@
3
3
  <head>
4
4
  <title>NoraMark Manual</title>
5
5
  <link rel="stylesheet" type="text/css" href="nora-simple.css" />
6
+ <link rel="stylesheet" type="text/css" href="nora-simple-ja.css" />
6
7
  </head>
7
8
  <body>
8
- <section><h1>NoraMark Manual</h1>
9
+ <section><h1 id='heading_index_1'>NoraMark Manual</h1>
9
10
  <div class='pgroup'><p><strong>(作成中・記述は未完成です。)</strong></p>
10
11
  </div>
11
12
  <div class='pgroup'><p>NoraMarkは、EPUBで利用するXHTMLを生成するためのマークアップとしてデザインされました。次のような特徴があります。</p>
@@ -18,11 +19,11 @@
18
19
  <li>文書構造に対する処理を追加できる</li>
19
20
  <li>パース結果をXMLとして取得できる</li>
20
21
  </ul>
21
- <section><h2>必要なもの</h2>
22
+ <section><h2 id='heading_index_2'>必要なもの</h2>
22
23
  <ul><li>ruby 2.0以上</li>
23
24
  </ul>
24
25
  </section>
25
- <section><h2>インストール方法</h2>
26
+ <section><h2 id='heading_index_3'>インストール方法</h2>
26
27
  <div class='pgroup'><p>Gemfileに次のように書きます</p>
27
28
  </div>
28
29
  <pre><code>gem 'nora_mark' </code></pre>
@@ -33,8 +34,8 @@
33
34
  </div>
34
35
  <pre><code>gem install nora_mark</code></pre>
35
36
  </section>
36
- <section><h2>使い方</h2>
37
- <section><h3>コマンドラインから</h3>
37
+ <section><h2 id='heading_index_4'>使い方</h2>
38
+ <section><h3 id='heading_index_5'>コマンドラインから</h3>
38
39
  <pre><code>$ nora2html &lt; source.nora &gt; output.xhtml</code></pre>
39
40
  <div class='pgroup'><p>入力はutf-8のみ受け付けます。日本語のテキストであれば、kconvオプションでうまくうごくかもしれません。</p>
40
41
  </div>
@@ -42,14 +43,14 @@
42
43
  <div class='pgroup'><p><span class='strong'>nora2htmlは、newpageコマンドを&lt;hr /&gt;タグに置き換え、すべてのページをひとつのxhtmlとして出力します</span></p>
43
44
  </div>
44
45
  </section>
45
- <section><h3>コードから</h3>
46
+ <section><h3 id='heading_index_6'>コードから</h3>
46
47
  <pre class='code-ruby' data-code-language='ruby'><code>require 'nora_mark'
47
48
  document = NoraMark::Document.parse(string_or_io, lang: 'ja')
48
49
  document.html.write_as_files</code></pre>
49
50
  </section>
50
51
  </section>
51
- <section><h2>マークアップ</h2>
52
- <section><h3>通常のテキスト</h3>
52
+ <section><h2 id='heading_index_7'>マークアップ</h2>
53
+ <section><h3 id='heading_index_8'>通常のテキスト</h3>
53
54
  <div class='pgroup'><p>単なるテキストもHTMLに変換されます。</p>
54
55
  </div>
55
56
  <pre>吾輩は猫である。名前はまだ無い。
@@ -75,7 +76,7 @@ Ut enim ad minim veniam, quis nostrud exercitation </pre>
75
76
  <pre class='code-html' data-code-language='html'><code>&lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipisicing elit, &lt;br /&gt;sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. &lt;/p&gt;
76
77
  &lt;p&gt;Ut enim ad minim veniam, quis nostrud exercitation&lt;/p&gt;</code></pre>
77
78
  </section>
78
- <section><h3>明示的なブロック</h3>
79
+ <section><h3 id='heading_index_9'>明示的なブロック</h3>
79
80
  <div class='pgroup'><p>NoraMarkでは、&lt;コマンド&gt; { ではじまり、} のみの行で終わる範囲を明示的なブロックとみなします。</p>
80
81
  </div>
81
82
  <pre>d.column {
@@ -110,7 +111,7 @@ Ut enim ad minim veniam, quis nostrud exercitation </pre>
110
111
  &lt;/div&gt;
111
112
  &lt;/blockquote&gt;</code></pre>
112
113
  </section>
113
- <section><h3>インラインコマンド</h3>
114
+ <section><h3 id='heading_index_10'>インラインコマンド</h3>
114
115
  <div class='pgroup'><p>インラインコマンドは、次の形式をしています。</p>
115
116
  </div>
116
117
  <pre>[&lt;コマンド&gt;{内容}]</pre>
@@ -138,7 +139,7 @@ Ut enim ad minim veniam, quis nostrud exercitation </pre>
138
139
  <pre>[ruby(とんぼ){蜻蛉}]の[ruby(めがね){眼鏡}]はみずいろめがね</pre></dd>
139
140
  </dl>
140
141
  </section>
141
- <section><h3>行コマンド</h3>
142
+ <section><h3 id='heading_index_11'>行コマンド</h3>
142
143
  <div class='pgroup'><p>行コマンドは1行を占有し、次の形式をしています。</p>
143
144
  </div>
144
145
  <pre>&lt;コマンド&gt;:内容</pre>
@@ -158,8 +159,8 @@ Ut enim ad minim veniam, quis nostrud exercitation </pre>
158
159
  <pre>newpage:</pre></dd>
159
160
  </dl>
160
161
  </section>
161
- <section><h3>リスト</h3>
162
- <section><h4>箇条書き</h4>
162
+ <section><h3 id='heading_index_12'>リスト</h3>
163
+ <section><h4 id='heading_index_13'>箇条書き</h4>
163
164
  <pre>*: *:ではじまる行は、箇条書きになる。
164
165
  *: 空行があくまで、箇条書きがつづく。
165
166
  *: 空行があくと、あらたな箇条書きになる。</pre>
@@ -170,27 +171,42 @@ Ut enim ad minim veniam, quis nostrud exercitation </pre>
170
171
  &lt;/ul&gt;
171
172
  }</code></pre>
172
173
  </section>
173
- <section><h4>番号つきリスト</h4>
174
- <section><h4>定義リスト</h4>
175
- <section><h3>見出し</h3>
176
- <section><h4>単独の見出し</h4>
177
- <section><h4>セクションを生成する見出し</h4>
178
- <section><h3>Frontmatter</h3>
179
- <section><h2>カスタマイズ</h2>
180
- <section><h3>生成ルール追加</h3>
174
+ <section><h4 id='heading_index_14'>番号つきリスト</h4>
175
+ <pre>1: 数字:ではじまる行は、番号つきリストになる。
176
+ 2: 空行があくまで、リストがつづく。
177
+ 3: 空行があくと、あらたなリストになる。
178
+ 10: 先頭の数字にかかわらず、1から順に番号がふられる。</pre>
179
+ <pre class='code-html' data-code-language='html'><code>&lt;ol&gt;&lt;li&gt;数字:ではじまる行は、番号つきリストになる。 &lt;/li&gt;
180
+ &lt;li&gt;空行があくまで、リストがつづく。&lt;/li&gt;
181
+ &lt;/ol&gt;
182
+ &lt;ol&gt;&lt;li&gt;空行があくと、あらたなリストになる。&lt;/li&gt;
183
+ &lt;li&gt;先頭の数字にかかわらず、1から順に番号がふられる。&lt;/li&gt;
184
+ &lt;/ol&gt;
185
+ }</code></pre>
186
+ </section>
187
+ <section><h4 id='heading_index_15'>定義リスト</h4>
188
+ <section><h5 id='heading_index_16'>1行の定義</h5>
189
+ </section>
190
+ <section><h5 id='heading_index_17'>複数行の定義</h5>
181
191
  </section>
182
- <section><h3>木構造の操作</h3>
183
- <section><h2>XML生成</h2>
184
192
  </section>
185
193
  </section>
194
+ <section><h3 id='heading_index_18'>見出し</h3>
195
+ <section><h4 id='heading_index_19'>単独の見出し</h4>
186
196
  </section>
197
+ <section><h4 id='heading_index_20'>セクションを生成する見出し</h4>
187
198
  </section>
188
199
  </section>
200
+ <section><h3 id='heading_index_21'>Frontmatter</h3>
189
201
  </section>
190
202
  </section>
203
+ <section><h2 id='heading_index_22'>カスタマイズ</h2>
204
+ <section><h3 id='heading_index_23'>生成ルール追加</h3>
191
205
  </section>
206
+ <section><h3 id='heading_index_24'>木構造の操作</h3>
192
207
  </section>
193
208
  </section>
209
+ <section><h2 id='heading_index_25'>XML生成</h2>
194
210
  </section>
195
211
  </section>
196
212
  </body>
@@ -5,7 +5,7 @@ module NoraMark
5
5
  @generator = generator
6
6
  end
7
7
  def write(node)
8
- node.content.each do |child|
8
+ node.children.each do |child|
9
9
  @generator.to_html child
10
10
  end
11
11
  end
@@ -1,10 +1,9 @@
1
1
  module NoraMark
2
2
  module Html
3
3
  class Context
4
- attr_accessor :title, :head_inserters, :toc, :lang, :stylesheets, :enable_pgroup, :render_parameter
4
+ attr_accessor :title, :head_inserters, :lang, :stylesheets, :enable_pgroup, :render_parameter
5
5
  def initialize(param = {})
6
6
  @head_inserters = []
7
- @toc = []
8
7
  @lang = param[:lang] || 'en'
9
8
  @title = param[:title] || 'NoraMark generated document'
10
9
  @stylesheets = param[:stylesheets] || []
@@ -71,7 +70,6 @@ module NoraMark
71
70
  page << "</head>\n"
72
71
  page << "<body>\n"
73
72
  @pages << page
74
- @toc << title
75
73
  end
76
74
 
77
75
  def end_html
@@ -90,6 +88,9 @@ module NoraMark
90
88
  @pages.last << text
91
89
  end
92
90
 
91
+ def set_toc toc
92
+ @pages.set_toc toc
93
+ end
93
94
  def result
94
95
  if !@pages.last.frozen?
95
96
  end_html
@@ -55,9 +55,16 @@ module NoraMark
55
55
  node.body_empty = true
56
56
  node
57
57
  end),
58
- LineCommand =>
58
+ Block =>
59
59
  WriterSelector.new(self,
60
60
  {
61
+ 'd' => TagWriter.create('div', self),
62
+ 'art' => article_writer,
63
+ 'arti' => article_writer,
64
+ 'article' => article_writer,
65
+ 'sec' => section_writer,
66
+ 'sect' => section_writer,
67
+ 'section' => section_writer,
61
68
  'image' =>
62
69
  TagWriter.create('div', self,
63
70
  node_preprocessor: proc do |node|
@@ -79,17 +86,6 @@ module NoraMark
79
86
  end
80
87
  ),
81
88
 
82
- }),
83
- Block =>
84
- WriterSelector.new(self,
85
- {
86
- 'd' => TagWriter.create('div', self),
87
- 'art' => article_writer,
88
- 'arti' => article_writer,
89
- 'article' => article_writer,
90
- 'sec' => section_writer,
91
- 'sect' => section_writer,
92
- 'section' => section_writer,
93
89
  }),
94
90
  Newpage => newpage_writer,
95
91
  Inline =>
@@ -131,7 +127,7 @@ module NoraMark
131
127
  DLItem =>
132
128
  TagWriter.create('', self, chop_last_space: true, node_preprocessor: proc do |node| node.no_tag = true; node end,
133
129
  write_body_preprocessor: proc do |node|
134
- output "<dt>"; write_array node.parameters[0]; output "</dt>\n"
130
+ output "<dt>"; write_nodeset node.parameters[0]; output "</dt>\n"
135
131
  output "<dd>"; write_children node; output "</dd>\n"
136
132
  :done
137
133
  end),
@@ -142,8 +138,8 @@ module NoraMark
142
138
  #headed-section
143
139
  HeadedSection =>
144
140
  TagWriter.create('section', self, write_body_preprocessor: proc do |node|
145
- output "<h#{node.level}>"
146
- write_array node.heading
141
+ output "<h#{node.level}#{ids_string(node.named_parameters[:heading_id])}>"
142
+ write_nodeset node.heading
147
143
  @generator.context.chop_last_space
148
144
  output "</h#{node.level}>\n"
149
145
  :continue
@@ -169,8 +165,45 @@ module NoraMark
169
165
  }
170
166
  end
171
167
 
168
+ def collect_id_and_headings
169
+ @id_pool = {}
170
+ @headings = []
171
+
172
+ all_nodes = @parsed_result.all_nodes
173
+ all_nodes.each do
174
+ |x|
175
+ x.ids ||= []
176
+ x.ids.each do
177
+ |id|
178
+ if !@id_pool[id].nil?
179
+ warn "duplicate id #{id}"
180
+ end
181
+ @id_pool[id] = x
182
+ end
183
+ @headings << x if (x.kind_of?(Block) && x.name =~ /h[1-6]/) || x.kind_of?(HeadedSection)
184
+ end
185
+ end
186
+ def assign_id_to_headings
187
+ collect_id_and_headings
188
+ count = 1
189
+ @headings.each do
190
+ |heading|
191
+ if heading.ids.size == 0 || heading.kind_of?(HeadedSection)
192
+ begin
193
+ id = "heading_index_#{count}"
194
+ count = count + 1
195
+ end while @id_pool[id]
196
+ heading.kind_of?(HeadedSection) ? (heading.named_parameters[:heading_id] ||= []) << id : heading.ids << id
197
+ end
198
+ end
199
+ end
200
+
172
201
  def convert(parsed_result, render_parameter = {})
173
- children = parsed_result.content
202
+ @parsed_result = parsed_result
203
+
204
+ assign_id_to_headings
205
+
206
+ children = parsed_result.children
174
207
  @context.file_basename = parsed_result.document_name
175
208
  @context.render_parameter = render_parameter
176
209
  if render_parameter[:nonpaged]
@@ -180,21 +213,19 @@ module NoraMark
180
213
  |node|
181
214
  to_html(node)
182
215
  }
216
+ @context.set_toc generate_toc
183
217
  @context.result
184
218
  end
185
219
 
220
+ def generate_toc
221
+ @headings.map do
222
+ |heading|
223
+ { page: heading.ancestors(type: :Page)[0].page_no }.merge heading.heading_info
224
+ end
225
+ end
226
+
186
227
  def to_html(node)
187
- if node.is_a? String
188
- @context << escape_html(node)
189
- elsif node.is_a? Hash
190
- writer = @writers[node[:type]]
191
- if writer.nil?
192
- warn "can't find html generator for \"#{node}\""
193
- @context << escape_html(node[:raw_text])
194
- else
195
- writer.write(node)
196
- end
197
- elsif node.kind_of? Text
228
+ if node.kind_of? Text
198
229
  @context << escape_html(node.content)
199
230
  else
200
231
  writer = @writers[node.class]
@@ -1,50 +1,63 @@
1
1
  require 'securerandom'
2
2
  module NoraMark
3
3
  module Html
4
- class Context
5
- class Pages
6
- attr_reader :created_files
7
- attr_accessor :file_basename
8
- def initialize(sequence_format='%05d')
9
- @sequence_format = sequence_format || '%05d'
10
- @result = []
11
- end
4
+ class Pages
5
+ attr_reader :created_files
6
+ attr_accessor :file_basename
7
+ def initialize(sequence_format='%05d')
8
+ @sequence_format = sequence_format || '%05d'
9
+ @result = []
10
+ end
12
11
 
13
- def last
14
- @result.last[:content]
15
- end
12
+ def last
13
+ @result.last[:content]
14
+ end
16
15
 
17
- def size
18
- @result.size
19
- end
20
-
21
- def <<(page)
22
- seq = @result.size + 1
23
- @result << { content: page, filename: "#{@file_basename}_#{@sequence_format%(seq)}.xhtml" }
24
- end
16
+ def size
17
+ @result.size
18
+ end
19
+
20
+ def <<(page)
21
+ seq = @result.size + 1
22
+ @result << { content: page, filename: filename_for_page(seq)}
23
+ end
25
24
 
26
- def [](num)
27
- page = @result[num]
28
- page.nil? ? nil : page[:content]
29
- end
25
+ def [](num)
26
+ page = @result[num]
27
+ page.nil? ? nil : page[:content]
28
+ end
30
29
 
31
- def pages
32
- @result
33
- end
30
+ def pages
31
+ @result
32
+ end
34
33
 
35
- def write_as_files(directory: nil)
36
- dir = directory || Dir.pwd
37
- Dir.chdir(dir) do
38
- @result.each do
39
- |page|
40
- File.open(page[:filename], 'w+') do
41
- |file|
42
- file << page[:content]
43
- end
34
+ def filename_for_page n
35
+ "#{@file_basename}_#{@sequence_format%(n)}.xhtml"
36
+ end
37
+
38
+ def set_toc toc_data
39
+ @toc = toc_data.map do |toc_line|
40
+ fi = toc_line[:id] ? "##{toc_line[:id]}" : ''
41
+ {link: "#{filename_for_page(toc_line[:page])}#{fi}", level: toc_line[:level], text: toc_line[:text]}
42
+ end
43
+ end
44
+ def toc
45
+ @toc
46
+ end
47
+
48
+ def write_as_files(directory: nil)
49
+ dir = directory || Dir.pwd
50
+ Dir.chdir(dir) do
51
+ @result.each do
52
+ |page|
53
+ File.open(page[:filename], 'w+') do
54
+ |file|
55
+ file << page[:content]
44
56
  end
45
57
  end
46
- end
47
- end
58
+ end
59
+ end
48
60
  end
49
61
  end
50
62
  end
63
+
@@ -9,7 +9,7 @@ module NoraMark
9
9
  Paragraph =>
10
10
  TagWriter.create('p', @generator, chop_last_space: true,
11
11
  node_preprocessor: proc do |node|
12
- first = node.content[0]
12
+ first = node.children[0]
13
13
  if first.kind_of? Text
14
14
  first.content.sub!(/^[[:space:]]+/, '')
15
15
  add_class(node, 'noindent') if first.content =~/^(「|『|()/ # TODO: should be plaggable
@@ -36,8 +36,8 @@ module NoraMark
36
36
  ParagraphGroup =>
37
37
  TagWriter.create("p", @generator,
38
38
  node_preprocessor: proc do |node|
39
- node.content = node.content.inject([]) do |memo, node|
40
- memo << Breakline.new if !memo.last.nil? && memo.last.kind_of?(Paragraph) && node.kind_of?(Paragraph)
39
+ node.children = node.children.inject([]) do |memo, node|
40
+ memo << Breakline.new(memo.last.line_no) if !memo.last.nil? && memo.last.kind_of?(Paragraph) && node.kind_of?(Paragraph)
41
41
  memo << node
42
42
  end
43
43
  node