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 +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +86 -2
- data/example/nora-simple-ja.css +19 -0
- data/example/nora-simple.css +6 -15
- data/example/noramark-reference-ja.nora +23 -1
- data/example/noramark-reference-ja_00001.xhtml +39 -23
- data/lib/nora_mark/html/abstract_node_writer.rb +1 -1
- data/lib/nora_mark/html/context.rb +4 -3
- data/lib/nora_mark/html/generator.rb +58 -27
- data/lib/nora_mark/html/pages.rb +50 -37
- data/lib/nora_mark/html/paragraph_writer.rb +3 -3
- data/lib/nora_mark/html/tag_writer.rb +8 -7
- data/lib/nora_mark/node.rb +258 -2
- data/lib/nora_mark/node_builder.rb +18 -0
- data/lib/nora_mark/node_set.rb +24 -0
- data/lib/nora_mark/node_util.rb +38 -0
- data/lib/nora_mark/parser.kpeg +72 -57
- data/lib/nora_mark/parser.kpeg.rb +766 -246
- data/lib/nora_mark/transformer.rb +43 -0
- data/lib/nora_mark/version.rb +1 -1
- data/lib/nora_mark.rb +28 -11
- data/spec/nokogiri_test_helper.rb +9 -9
- data/spec/nora_mark_spec.rb +236 -9
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5ee7b20c586d15b36f4f461c63b98335e9396088
|
4
|
+
data.tar.gz: 3acba3835a8e034cd17068e3ac437f3a3eede844
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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) [](https://coveralls.io/r/skoji/noramark?branch=master)
|
3
|
+
[](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
|
-
|
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
|
|
data/example/nora-simple.css
CHANGED
@@ -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 < source.nora > 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コマンドを<hr />タグに置き換え、すべてのページをひとつの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><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, <br />sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. </p>
|
76
77
|
<p>Ut enim ad minim veniam, quis nostrud exercitation</p></code></pre>
|
77
78
|
</section>
|
78
|
-
<section><h3>明示的なブロック</h3>
|
79
|
+
<section><h3 id='heading_index_9'>明示的なブロック</h3>
|
79
80
|
<div class='pgroup'><p>NoraMarkでは、<コマンド> { ではじまり、} のみの行で終わる範囲を明示的なブロックとみなします。</p>
|
80
81
|
</div>
|
81
82
|
<pre>d.column {
|
@@ -110,7 +111,7 @@ Ut enim ad minim veniam, quis nostrud exercitation </pre>
|
|
110
111
|
</div>
|
111
112
|
</blockquote></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>[<コマンド>{内容}]</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><コマンド>:内容</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
|
</ul>
|
171
172
|
}</code></pre>
|
172
173
|
</section>
|
173
|
-
<section><h4>番号つきリスト</h4>
|
174
|
-
<
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
<
|
179
|
-
|
180
|
-
|
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><ol><li>数字:ではじまる行は、番号つきリストになる。 </li>
|
180
|
+
<li>空行があくまで、リストがつづく。</li>
|
181
|
+
</ol>
|
182
|
+
<ol><li>空行があくと、あらたなリストになる。</li>
|
183
|
+
<li>先頭の数字にかかわらず、1から順に番号がふられる。</li>
|
184
|
+
</ol>
|
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>
|
@@ -1,10 +1,9 @@
|
|
1
1
|
module NoraMark
|
2
2
|
module Html
|
3
3
|
class Context
|
4
|
-
attr_accessor :title, :head_inserters, :
|
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
|
-
|
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>";
|
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
|
-
|
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
|
-
|
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.
|
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]
|
data/lib/nora_mark/html/pages.rb
CHANGED
@@ -1,50 +1,63 @@
|
|
1
1
|
require 'securerandom'
|
2
2
|
module NoraMark
|
3
3
|
module Html
|
4
|
-
class
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
14
|
-
|
15
|
-
|
12
|
+
def last
|
13
|
+
@result.last[:content]
|
14
|
+
end
|
16
15
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
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
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
25
|
+
def [](num)
|
26
|
+
page = @result[num]
|
27
|
+
page.nil? ? nil : page[:content]
|
28
|
+
end
|
30
29
|
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
def pages
|
31
|
+
@result
|
32
|
+
end
|
34
33
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
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.
|
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.
|
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
|