nora_mark 0.2beta6 → 0.2beta7
Sign up to get free protection for your applications and to get access to all the features.
- 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) [![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
|
-
|
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
|