nora_mark 0.2beta7 → 0.2beta8
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/.travis.yml +1 -1
- data/README.md +149 -73
- data/Rakefile +1 -3
- data/bin/nora2html +1 -1
- data/emacs-mode/noramark-mode.el +497 -0
- data/example/koujin.nora +13 -0
- data/example/nora-simple.css +27 -2
- data/example/noramark-reference-ja.nora +446 -64
- data/example/noramark-reference-ja_00001.xhtml +485 -85
- data/lib/nora_mark.rb +5 -67
- data/lib/nora_mark/document.rb +89 -0
- data/lib/nora_mark/extensions.rb +26 -0
- data/lib/nora_mark/html/context.rb +2 -3
- data/lib/nora_mark/html/default_transformer.rb +151 -0
- data/lib/nora_mark/html/generator.rb +25 -149
- data/lib/nora_mark/html/paragraph_writer.rb +4 -4
- data/lib/nora_mark/html/tag_writer.rb +13 -10
- data/lib/nora_mark/node.rb +196 -72
- data/lib/nora_mark/node_set.rb +13 -0
- data/lib/nora_mark/node_util.rb +29 -16
- data/lib/nora_mark/parser.kpeg +210 -74
- data/lib/nora_mark/parser.kpeg.rb +1353 -401
- data/lib/nora_mark/parser.rb +1 -1
- data/lib/nora_mark/transformer.rb +35 -10
- data/lib/nora_mark/version.rb +1 -1
- data/nora_mark.gemspec +3 -2
- data/spec/node_spec.rb +280 -0
- data/spec/nora_mark_spec.rb +1189 -1025
- data/spec/spec_helper.rb +2 -0
- data/spec/transformer_spec.rb +37 -0
- metadata +27 -6
- data/lib/nora_mark/html/writer_selector.rb +0 -24
- data/lib/nora_mark/node_builder.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b3c7634c3b142ce5a88d05603a3c1e3511a629e5
|
4
|
+
data.tar.gz: f8f28a75f465ba76b21fd54afd7c65c75c16b733
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8748711f3848e9bb9cfbbf9d2629d30ed43d434c1e9259dfe9b16e0fd47c0fd10606df33070ef97b5e22e5dce114635e5fbe879be344af37cd6da8a7a176d233
|
7
|
+
data.tar.gz: d27e161322269ea36b1bf6475cde05a1dce20551be6f59311a8777229e70051b40ef576b11ba15c75450a5e0018f2a57cde5690c0aae286cba02dd9da77e4e02
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,9 @@
|
|
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
|
+
[](https://gemnasium.com/skoji/noramark)
|
3
4
|
[](http://badge.fury.io/rb/nora_mark)
|
4
5
|
|
5
|
-
NoraMark is a simple text markup language. It is designed to create XHTML files for EPUB books.
|
6
|
+
NoraMark is a simple and customizable text markup language. It is designed to create XHTML files for EPUB books.
|
6
7
|
|
7
8
|
**CAUTION This is very early alpha version, so it's not stable at all, even the markup syntax will change**
|
8
9
|
|
@@ -44,12 +45,12 @@ I am planning to release nora2epub and other external tools.
|
|
44
45
|
|
45
46
|
## Markup
|
46
47
|
|
47
|
-
An example of markup text (text is in
|
48
|
+
An example of markup text (text is in English, but the paragraph style is Japanese)
|
48
49
|
|
49
|
-
|
50
|
-
|
50
|
+
// line begins with // is a comment.
|
51
|
+
// you don't need to indent noramark text.
|
51
52
|
|
52
|
-
|
53
|
+
// page/document metadata in YAML frontmatter
|
53
54
|
---
|
54
55
|
lang: ja
|
55
56
|
title: test title
|
@@ -65,43 +66,40 @@ An example of markup text (text is in english, but the paragraph style is japane
|
|
65
66
|
|
66
67
|
d.column {
|
67
68
|
This block will produce div.column.
|
68
|
-
Inline commands like [link(http://github.com/skoji/nora_mark/){this}] and [
|
69
|
+
Inline commands like [link(http://github.com/skoji/nora_mark/){this}] and [sp.strong{this}] is available.
|
69
70
|
}
|
70
71
|
}
|
71
72
|
|
72
73
|
The converted XHTML file
|
73
74
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
75
|
+
```
|
76
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
77
|
+
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
|
78
|
+
<head>
|
79
|
+
<title>test title</title>
|
78
80
|
<link rel="stylesheet" type="text/css" href="css/normalize.css" />
|
79
81
|
<link rel="stylesheet" type="text/css" href="css/main.css" />
|
80
|
-
|
81
|
-
|
82
|
-
<article>
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
<div class='pgroup'>
|
93
|
-
<p>This block will produce div.column.</p>
|
94
|
-
<p>Inline commands like <a href='http://github.com/skoji/nora_mark/'>this</a> and <span class='strong'>this</span> is available.</p>
|
95
|
-
</div>
|
96
|
-
</div>
|
82
|
+
</head>
|
83
|
+
<body>
|
84
|
+
<article><h1 id='heading_index_1'>header 1</h1>
|
85
|
+
<div class='pgroup'><p>article comes here.</p>
|
86
|
+
<p>linebreak will produce paragraph.</p>
|
87
|
+
</div>
|
88
|
+
<div class='pgroup'><p>blank line will procude div.pgroup.</p>
|
89
|
+
</div>
|
90
|
+
<div class='column'><div class='pgroup'><p>This block will produce div.column.</p>
|
91
|
+
<p>Inline commands like <a href='http://github.com/skoji/nora_mark/'>this</a> and <span class='strong'>this</span> is available.</p>
|
92
|
+
</div>
|
93
|
+
</div>
|
97
94
|
</article>
|
98
|
-
|
99
|
-
|
95
|
+
</body>
|
96
|
+
</html>
|
97
|
+
```
|
100
98
|
|
101
99
|
Another example of markup text in non-japanese (paragraph style is default)
|
102
100
|
|
103
|
-
|
104
|
-
|
101
|
+
// line begins with // is a comment.
|
102
|
+
// you don't need to indent noramark text.
|
105
103
|
|
106
104
|
---
|
107
105
|
lang: en
|
@@ -118,35 +116,37 @@ Another example of markup text in non-japanese (paragraph style is default)
|
|
118
116
|
|
119
117
|
d.column {
|
120
118
|
This block will produce div.column.
|
121
|
-
Inline commands like [link(http://github.com/skoji/nora_mark/){this}] and [
|
119
|
+
Inline commands like [link(http://github.com/skoji/nora_mark/){this}] and [sp.strong{this}] is available.
|
122
120
|
}
|
123
121
|
}
|
124
122
|
|
125
123
|
The converted XHTML file
|
126
124
|
|
127
|
-
|
128
|
-
|
129
|
-
|
125
|
+
```
|
126
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
127
|
+
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
128
|
+
<head>
|
130
129
|
<title> test title</title>
|
131
130
|
<link rel="stylesheet" type="text/css" href="css/normalize.css" />
|
132
131
|
<link rel="stylesheet" type="text/css" href="css/main.css" />
|
133
|
-
|
134
|
-
|
132
|
+
</head>
|
133
|
+
<body>
|
135
134
|
<article>
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
135
|
+
<h1>header 1</h1>
|
136
|
+
<p>article comes here.<br />linebreak will produce paragraph.</p>
|
137
|
+
<p>blank line will produce paragraph</p>
|
138
|
+
<div class='column'>
|
139
|
+
<p>This block will produce div.column.<br />Inline commands like <a href='http://github.com/skoji/nora_mark/'>this</a> and <span class='strong'>this</span> is available.</p>
|
140
|
+
</div>
|
142
141
|
</article>
|
143
|
-
|
144
|
-
|
142
|
+
</body>
|
143
|
+
</html>
|
144
|
+
```
|
145
145
|
|
146
146
|
|
147
147
|
Another example of markup text
|
148
148
|
|
149
|
-
|
149
|
+
// Markdown-ish heading will creates section
|
150
150
|
|
151
151
|
---
|
152
152
|
lang: ja
|
@@ -154,49 +154,107 @@ Another example of markup text
|
|
154
154
|
stylesheets: css/normalize.css, css/main.css
|
155
155
|
---
|
156
156
|
|
157
|
-
|
157
|
+
# this is the first heading
|
158
158
|
|
159
159
|
This line is in a section.
|
160
160
|
This line is in a section.
|
161
161
|
|
162
|
-
|
162
|
+
## this is the second heading
|
163
163
|
|
164
164
|
This section is nested.
|
165
165
|
|
166
|
-
|
166
|
+
# this is the third heading
|
167
167
|
|
168
168
|
will terminate lower level section
|
169
169
|
|
170
170
|
The converted XHTML file
|
171
171
|
|
172
|
-
|
173
|
-
|
174
|
-
|
172
|
+
```
|
173
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
174
|
+
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="en">
|
175
|
+
<head>
|
175
176
|
<title>test title</title>
|
176
177
|
<link rel="stylesheet" type="text/css" href="css/normalize.css" />
|
177
178
|
<link rel="stylesheet" type="text/css" href="css/main.css" />
|
178
|
-
|
179
|
-
|
179
|
+
</head>
|
180
|
+
<body>
|
180
181
|
<section><h1>this is the first heading</h1>
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
182
|
+
<div class='pgroup'><p>This line is in a section.</p>
|
183
|
+
<p>This line is in a section.</p>
|
184
|
+
</div>
|
185
|
+
<section><h2>this is the second heading</h2>
|
186
|
+
<div class='pgroup'><p>This section is nested.</p>
|
187
|
+
</div>
|
188
|
+
</section>
|
188
189
|
</section>
|
189
190
|
<section><h1>this is the third heading</h1>
|
190
|
-
|
191
|
-
|
191
|
+
<div class='pgroup'><p>will terminate lower level section</p>
|
192
|
+
</div>
|
192
193
|
</section>
|
193
|
-
|
194
|
-
|
194
|
+
</body>
|
195
|
+
</html>
|
196
|
+
```
|
197
|
+
Yet another example of markup text.
|
195
198
|
|
199
|
+
// Markdown-ish heading with explicit setion boundary
|
200
|
+
|
201
|
+
---
|
202
|
+
lang: ja
|
203
|
+
title: test title
|
204
|
+
stylesheets: css/normalize.css, css/main.css
|
205
|
+
---
|
206
|
+
|
207
|
+
# this is the first heading
|
208
|
+
|
209
|
+
This line is in a section.
|
210
|
+
This line is in a section.
|
211
|
+
|
212
|
+
## this is the second heading with explicit boundary {
|
213
|
+
|
214
|
+
This section is nested.
|
215
|
+
|
216
|
+
}
|
217
|
+
|
218
|
+
Here is in the first section again.
|
219
|
+
|
220
|
+
# this is the third heading
|
221
|
+
|
222
|
+
will terminate same level section
|
223
|
+
|
224
|
+
The converted XHTML file
|
225
|
+
|
226
|
+
```
|
227
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
228
|
+
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
|
229
|
+
<head>
|
230
|
+
<title>test title</title>
|
231
|
+
<link rel="stylesheet" type="text/css" href="css/normalize.css, css/main.css" />
|
232
|
+
</head>
|
233
|
+
<body>
|
234
|
+
<section><h1 id='heading_index_1'>this is the first heading</h1>
|
235
|
+
<div class='pgroup'><p>This line is in a section.</p>
|
236
|
+
<p>This line is in a section.</p>
|
237
|
+
</div>
|
238
|
+
<section><h2 id='heading_index_2'>this is the second heading with explicit boundary</h2>
|
239
|
+
<div class='pgroup'><p>This section is nested.</p>
|
240
|
+
</div>
|
241
|
+
</section>
|
242
|
+
<div class='pgroup'><p>Here is in the first section again.</p>
|
243
|
+
</div>
|
244
|
+
</section>
|
245
|
+
<section><h1 id='heading_index_3'>this is the third heading</h1>
|
246
|
+
<div class='pgroup'><p>will terminate same level section.</p>
|
247
|
+
</div>
|
248
|
+
</section>
|
249
|
+
</body>
|
250
|
+
</html>
|
251
|
+
```
|
196
252
|
|
197
253
|
## Customize
|
198
254
|
|
199
|
-
|
255
|
+
You can define your own markup by transforming parse tree.
|
256
|
+
|
257
|
+
### Simple Customization Sample
|
200
258
|
|
201
259
|
Markup text and the code
|
202
260
|
```ruby
|
@@ -207,13 +265,12 @@ EOF
|
|
207
265
|
|
208
266
|
document = NoraMark::Document.parse(text)
|
209
267
|
document.add_transformer(generator: :html) do
|
210
|
-
|
268
|
+
modify "speak" do # "speak" is selector for node. :modify is action.
|
211
269
|
@node.name = 'p'
|
212
270
|
@node.prepend_child inline('span', @node.parameters[0], classes: ['speaker'])
|
213
271
|
end
|
214
272
|
end
|
215
273
|
puts document.html[0]
|
216
|
-
|
217
274
|
```
|
218
275
|
|
219
276
|
Rendered XHTML
|
@@ -230,15 +287,15 @@ Rendered XHTML
|
|
230
287
|
</html>
|
231
288
|
```
|
232
289
|
|
233
|
-
Another Example
|
290
|
+
### Another Example
|
234
291
|
|
235
|
-
```
|
292
|
+
```ruby
|
236
293
|
text = <<EOF
|
237
294
|
---
|
238
295
|
lang: ja
|
239
296
|
---
|
240
|
-
|
241
|
-
|
297
|
+
|
298
|
+
# 見出し
|
242
299
|
|
243
300
|
パラグラフ。
|
244
301
|
パラグラフ。
|
@@ -246,7 +303,7 @@ EOF
|
|
246
303
|
|
247
304
|
document = NoraMark::Document.parse(text)
|
248
305
|
document.add_transformer(generator: :html) do
|
249
|
-
|
306
|
+
replace({:type => :HeadedSection}) do
|
250
307
|
header = block('header',
|
251
308
|
block('div',
|
252
309
|
block("h#{@node.level}", @node.heading),
|
@@ -278,6 +335,25 @@ Result.
|
|
278
335
|
</body>
|
279
336
|
</html>
|
280
337
|
```
|
338
|
+
### HTML generator default transformer
|
339
|
+
|
340
|
+
[HTML generator default transformer](https://github.com/skoji/noramark/blob/master/lib/nora_mark/html/default_transformer.rb) is a good example of transformer.
|
341
|
+
|
342
|
+
## noramark-mode.el
|
343
|
+
|
344
|
+
Experimental implementation of noramark major mode is available here. It provides font-lock for NoraMark syntax and supports outline-minor-mode for the present.
|
345
|
+
|
346
|
+
https://github.com/skoji/noramark/blob/master/emacs-mode/noramark-mode.el
|
347
|
+
|
348
|
+
1. Download the file
|
349
|
+
2. Place it somewhere in the load-path
|
350
|
+
2. Edit your `~/.emacs.d/init.el` like this
|
351
|
+
|
352
|
+
```emacs-lisp
|
353
|
+
(require 'noramark-mode)
|
354
|
+
(setq auto-mode-alist (cons '("\\.nora$" . noramark-mode) auto-mode-alist))
|
355
|
+
(setq auto-mode-alist (cons '("-nora\\.txt$" . noramark-mode) auto-mode-alist))
|
356
|
+
```
|
281
357
|
|
282
358
|
## Contributing
|
283
359
|
|
data/Rakefile
CHANGED
@@ -7,8 +7,6 @@ rule(/\.kpeg\.rb/ => proc {|task_name| task_name.sub(/kpeg\.rb$/, 'kpeg')}) do
|
|
7
7
|
system "kpeg -f #{t.prerequisites[0]}"
|
8
8
|
end
|
9
9
|
|
10
|
-
RSpec::Core::RakeTask.new(:spec)
|
10
|
+
RSpec::Core::RakeTask.new(:spec => ["lib/nora_mark/parser.kpeg.rb"])
|
11
11
|
|
12
|
-
desc "run rspec"
|
13
|
-
task :test => ["lib/nora_mark/parser.kpeg.rb", :spec]
|
14
12
|
|
data/bin/nora2html
CHANGED
@@ -9,7 +9,7 @@ opt.on('--kconv') {
|
|
9
9
|
}
|
10
10
|
|
11
11
|
args = opt.parse(ARGV)
|
12
|
-
input =
|
12
|
+
input = ARGF.read
|
13
13
|
input = Kconv.toutf8(input) if auto_convert_encode
|
14
14
|
|
15
15
|
puts NoraMark::Document::parse(input).render_parameter(nonpaged: true).html[0]
|
@@ -0,0 +1,497 @@
|
|
1
|
+
;; experiment: noramark mode
|
2
|
+
(require 'outline)
|
3
|
+
|
4
|
+
(defconst noramark-mode-version "0.1"
|
5
|
+
"NoraMark mode version number.")
|
6
|
+
|
7
|
+
;;; Customizable Variables ====================================================
|
8
|
+
|
9
|
+
(defvar noramark-mode-hook nil
|
10
|
+
"Hook run when entering NoraMark mode.")
|
11
|
+
|
12
|
+
(defgroup noramark nil
|
13
|
+
"Major mode for editing text files in NoraMark format."
|
14
|
+
:prefix "noramark-"
|
15
|
+
:group 'noramark)
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
;;; Font Lock =================================================================
|
20
|
+
|
21
|
+
(require 'font-lock)
|
22
|
+
|
23
|
+
(defvar noramark-header-face 'noramark-header-face
|
24
|
+
"Face name to use as a base for header.")
|
25
|
+
|
26
|
+
(defvar noramark-inline-code-face 'noramark-inline-code-face
|
27
|
+
"Face name to use for inline code.")
|
28
|
+
|
29
|
+
(defvar noramark-list-face 'noramark-list-face
|
30
|
+
"Face name to use for list markers.")
|
31
|
+
|
32
|
+
(defvar noramark-pre-face 'noramark-pre-face
|
33
|
+
"Face name to use for preformatted text.")
|
34
|
+
|
35
|
+
(defvar noramark-language-keyword-face 'noramark-language-keyword-face
|
36
|
+
"Face name to use for programming language identifiers.")
|
37
|
+
|
38
|
+
(defvar noramark-link-face 'noramark-link-face
|
39
|
+
"Face name to use for links.")
|
40
|
+
|
41
|
+
(defvar noramark-keyword-face 'noramark-keyword-face
|
42
|
+
"Face name to use for noramark keywords.")
|
43
|
+
|
44
|
+
(defvar noramark-frontmatter-face 'noramark-frontmatter-face
|
45
|
+
"Face name to use for noramark frontmatter.")
|
46
|
+
|
47
|
+
(defvar noramark-command-face 'noramark-command-face
|
48
|
+
"Face name to use for noramark command.")
|
49
|
+
|
50
|
+
(defgroup noramark-faces nil
|
51
|
+
"Faces used in NoraMark Mode"
|
52
|
+
:group 'noramark
|
53
|
+
:group 'faces)
|
54
|
+
|
55
|
+
(defface noramark-header-face
|
56
|
+
'((t (:inherit font-lock-function-name-face :weight bold)))
|
57
|
+
"Base face for headers."
|
58
|
+
:group 'noramark-faces)
|
59
|
+
|
60
|
+
(defface noramark-command-face
|
61
|
+
'((t (:inherit font-lock-comment-face)))
|
62
|
+
"command face."
|
63
|
+
:group 'noramark-faces)
|
64
|
+
|
65
|
+
(defface noramark-inline-code-face
|
66
|
+
'((t (:inherit font-lock-constant-face)))
|
67
|
+
"Face for inline code."
|
68
|
+
:group 'noramark-faces)
|
69
|
+
|
70
|
+
(defface noramark-list-face
|
71
|
+
'((t (:inherit font-lock-keyword-face :weight bold)))
|
72
|
+
"Face for list item markers."
|
73
|
+
:group 'noramark-faces)
|
74
|
+
|
75
|
+
(defface noramark-pre-face
|
76
|
+
'((t (:inherit font-lock-constant-face)))
|
77
|
+
"Face for preformatted text."
|
78
|
+
:group 'noramark-faces)
|
79
|
+
|
80
|
+
(defface noramark-language-keyword-face
|
81
|
+
'((t (:inherit font-lock-type-face)))
|
82
|
+
"Face for programming language identifiers."
|
83
|
+
:group 'noramark-faces)
|
84
|
+
|
85
|
+
(defface noramark-link-face
|
86
|
+
'((t (:inherit font-lock-keyword-face)))
|
87
|
+
"Face for links."
|
88
|
+
:group 'noramark-faces)
|
89
|
+
|
90
|
+
(defface noramark-keyword-face
|
91
|
+
'((t (:inherit font-lock-keyword-face)))
|
92
|
+
"Face for keyword."
|
93
|
+
:group 'noramark-faces)
|
94
|
+
|
95
|
+
(defface noramark-frontmatter-face
|
96
|
+
'((t (:inherit font-lock-comment-face)))
|
97
|
+
"Face for frontmatter."
|
98
|
+
:group 'noramark-faces)
|
99
|
+
|
100
|
+
(defconst noramark-regex-command-param
|
101
|
+
"\\(\\(\\#[[:alpha:][:digit:]-_]+\\)*\\)\\(\\(\\.[[:alpha:][:digit:]-_]+\\)*\\)\\((.*?)\\)?\\(\\[.*\\]\\)?"
|
102
|
+
"Regular expression for #id.class(parameter)[namedparameter]
|
103
|
+
Group 1 matchs the id.
|
104
|
+
Group 3 matchs the class
|
105
|
+
Group 5 matches the parameter.
|
106
|
+
Group 6 matches the named parameter.")
|
107
|
+
|
108
|
+
(defconst noramark-regex-pre-head
|
109
|
+
(concat "^[[:space:]]*\\(pre\\|code\\)" noramark-regex-command-param "[[:space:]]*\\({\\)[[:space:]]*?\n")
|
110
|
+
"Regular expression for pre or code head block like pre.class(param) {")
|
111
|
+
|
112
|
+
(defconst noramark-regex-pre-tail
|
113
|
+
"^[[:space:]]*\\(}\\)[[:space:]]*$")
|
114
|
+
|
115
|
+
|
116
|
+
(defconst noramark-regex-pre-c-head
|
117
|
+
(concat "^[[:space:]]*\\(pre\\|code\\)" noramark-regex-command-param "[[:space:]]*\\({//\\)\\([A-Za-z-_]*?\\)?[[:space:]]*?\n")
|
118
|
+
"Regular expression for pre or code head block like code.class(param) {//language ")
|
119
|
+
|
120
|
+
(defconst noramark-regex-pre-c-tail
|
121
|
+
"^[[:space:]]*\\(//}\\)[[:space:]]*$")
|
122
|
+
|
123
|
+
(defconst noramark-regex-fence-head
|
124
|
+
"^\\(```\\)\\([A-Za-z0-9-_]+\\)?\\((.*?)\\)?\\(\\[.*?\\]\\)?[[:space:]]*$")
|
125
|
+
|
126
|
+
(defconst noramark-regex-fence-tail
|
127
|
+
"^\\(```\\)[[:space:]]*$")
|
128
|
+
|
129
|
+
(defconst noramark-regex-header
|
130
|
+
"^[ \t]*\\(#+\\).*$"
|
131
|
+
"Regexp identifying NoraMark headers.")
|
132
|
+
|
133
|
+
(defconst noramark-regex-frontmatter
|
134
|
+
"^\\(---\\)[[:space:]]*?$"
|
135
|
+
"Regular expression for frontmatter separator.")
|
136
|
+
|
137
|
+
(defconst noramark-regex-code
|
138
|
+
"\\(\\`\\|[^\\]\\)\\(\\(`+\\)\\(\\(.\\)*?[^`]\\)\\3\\)\\([^`]\\|\\'\\)"
|
139
|
+
"Regular expression for matching inline code fragments.")
|
140
|
+
|
141
|
+
(defvar noramark-mode-font-lock-keywords-basic
|
142
|
+
(list
|
143
|
+
; frontmatter
|
144
|
+
(cons 'noramark-match-frontmatter
|
145
|
+
'((1 'font-lock-keyword-face)
|
146
|
+
(2 'font-lock-comment-face nil t)
|
147
|
+
(3 'font-lock-keyword-face)))
|
148
|
+
; fence
|
149
|
+
(cons 'noramark-match-fence
|
150
|
+
'((1 'noramark-command-face)
|
151
|
+
(2 'font-lock-keyword-face nil t) ; language
|
152
|
+
(3 'font-lock-string-face nil t) ; param
|
153
|
+
(4 'font-lock-string-face nil t) ; named param
|
154
|
+
(5 'noramark-pre-face nil t)
|
155
|
+
(6 'noramark-command-face)))
|
156
|
+
; pre/code
|
157
|
+
(cons 'noramark-match-pre-command-complex
|
158
|
+
'((1 'noramark-command-face nil t) ; cmd
|
159
|
+
(2 'font-lock-keyword-face nil t) ; id
|
160
|
+
(3 'font-lock-keyword-face nil t) ; class
|
161
|
+
(4 'font-lock-string-face nil t) ; param
|
162
|
+
(5 'font-lock-string-face nil t) ; named param
|
163
|
+
(6 'noramark-command-face nil t) ; open
|
164
|
+
(7 'font-lock-keyword-face nil t) ; language
|
165
|
+
(8 'noramark-pre-face nil t) ; body of pre
|
166
|
+
(9 'noramark-command-face nil t))) ; close
|
167
|
+
; pre/code
|
168
|
+
(cons 'noramark-match-pre-command
|
169
|
+
'((1 'noramark-command-face nil t) ; cmd
|
170
|
+
(2 'font-lock-keyword-face nil t) ;id
|
171
|
+
(3 'font-lock-keyword-face nil t) ;class
|
172
|
+
(4 'font-lock-string-face nil t) ;param
|
173
|
+
(5 'font-lock-string-face nil t) ;named param
|
174
|
+
(6 'noramark-command-face nil t) ; open
|
175
|
+
(7 'noramark-pre-face nil t) ; body
|
176
|
+
(8 'noramark-command-face nil t))) ;close
|
177
|
+
; inline code
|
178
|
+
(cons 'noramark-match-inline-code '((0 noramark-inline-code-face)))
|
179
|
+
; block-end
|
180
|
+
'("^[ \t]*}[ \t]*\n" . noramark-command-face)
|
181
|
+
; comment
|
182
|
+
'("^[ \t]*//.*$" . font-lock-comment-face)
|
183
|
+
; ul
|
184
|
+
'("^[ \t]*[*]+" . noramark-list-face)
|
185
|
+
; ol
|
186
|
+
'("^[ \t]*[[:digit:]]+\\.[ \t]" . noramark-list-face)
|
187
|
+
; headings
|
188
|
+
(cons noramark-regex-header '((0 noramark-header-face)))
|
189
|
+
; headings: hN
|
190
|
+
'("^[ \t]*h[1-6]:.*$" . noramark-header-face)
|
191
|
+
; definition-list short
|
192
|
+
(cons 'noramark-match-definition-list-short
|
193
|
+
'((1 'noramark-list-face)
|
194
|
+
(2 'noramark-list-face)))
|
195
|
+
|
196
|
+
; definition-list long
|
197
|
+
(cons 'noramark-match-definition-list-long
|
198
|
+
'((1 'noramark-list-face)
|
199
|
+
(2 'noramark-command-face)))
|
200
|
+
; line-command
|
201
|
+
(cons 'noramark-match-line-command
|
202
|
+
'((1 'noramark-command-face)
|
203
|
+
(2 'font-lock-keyword-face nil t)
|
204
|
+
(3 'font-lock-keyword-face nil t)
|
205
|
+
(4 'font-lock-string-face nil t)
|
206
|
+
(5 'font-lock-string-face nil t)
|
207
|
+
(6 'noramark-command-face)))
|
208
|
+
; inline-command
|
209
|
+
(cons 'noramark-match-inline-command
|
210
|
+
'((1 'noramark-command-face)
|
211
|
+
(2 'font-lock-keyword-face nil t)
|
212
|
+
(3 'font-lock-keyword-face nil t)
|
213
|
+
(4 'font-lock-string-face nil t)
|
214
|
+
(5 'font-lock-string-face nil t)
|
215
|
+
(6 'noramark-command-face nil t)
|
216
|
+
(7 'noramark-command-face))))
|
217
|
+
"Syntax highlighting for NoraMark files.")
|
218
|
+
|
219
|
+
|
220
|
+
;;; Noramark Font Lock Matching Functions =====================================
|
221
|
+
(defun noramark-match-frontmatter (last)
|
222
|
+
(let (start body end all)
|
223
|
+
(cond ((search-forward-regexp noramark-regex-frontmatter last t)
|
224
|
+
(forward-line)
|
225
|
+
(beginning-of-line)
|
226
|
+
(setq start (list (match-beginning 1) (match-end 1)))
|
227
|
+
(setq body (list (point)))
|
228
|
+
(cond ((search-forward-regexp noramark-regex-frontmatter last t)
|
229
|
+
(forward-line)
|
230
|
+
(setq body (reverse (cons (1- (match-beginning 0)) body))
|
231
|
+
end (list (match-beginning 1) (match-end 1))
|
232
|
+
all (list (car start) (match-end 0)))
|
233
|
+
(set-match-data (append all start body end))
|
234
|
+
t)
|
235
|
+
(t nil)))
|
236
|
+
(t nil))))
|
237
|
+
|
238
|
+
(defun noramark-match-inline-code (last)
|
239
|
+
"Match inline code from the point to LAST."
|
240
|
+
(unless (bobp)
|
241
|
+
(backward-char 1))
|
242
|
+
(cond ((re-search-forward noramark-regex-code last t)
|
243
|
+
(set-match-data (list (match-beginning 2) (match-end 2)
|
244
|
+
(match-beginning 4) (match-end 4)))
|
245
|
+
(goto-char (match-end 0))
|
246
|
+
t)
|
247
|
+
(t (forward-char 2) nil)))
|
248
|
+
|
249
|
+
(defun noramark-match-line-command (last)
|
250
|
+
(let (cmd id class param nparam comma)
|
251
|
+
(cond ((search-forward-regexp (concat "^[[:space:]]*\\([A-Za-z0-9-_]+\\)" noramark-regex-command-param "[[:space:]]*\\([:{]\\)") last t)
|
252
|
+
(beginning-of-line)
|
253
|
+
|
254
|
+
(setq cmd (list (match-beginning 1) (match-end 1))
|
255
|
+
id (list (match-beginning 2) (match-end 2))
|
256
|
+
class (list (match-beginning 4) (match-end 4))
|
257
|
+
param (list (match-beginning 6) (match-end 6))
|
258
|
+
nparam (list (match-beginning 7) (match-end 7))
|
259
|
+
comma (list (match-beginning 8) (match-end 8))
|
260
|
+
all (list (match-beginning 0) (match-end 0)))
|
261
|
+
(forward-line)
|
262
|
+
(set-match-data (append all cmd id class param nparam comma))
|
263
|
+
t)
|
264
|
+
(t nil))))
|
265
|
+
|
266
|
+
(defun noramark-match-definition-list-short (last)
|
267
|
+
(let (all open delimiter)
|
268
|
+
(cond ((search-forward-regexp "^[ \t]*\\(;:\\)[[:space:]]*?[^:]*?\\(:\\)[[:space:]]" last t)
|
269
|
+
(beginning-of-line)
|
270
|
+
(setq open (list (match-beginning 1) (match-end 1))
|
271
|
+
delimiter (list (match-beginning 2) (match-end 2))
|
272
|
+
all (list (match-beginning 0) (match-end 0)))
|
273
|
+
(forward-line)
|
274
|
+
(set-match-data (append all open delimiter))
|
275
|
+
t)
|
276
|
+
(t nil))))
|
277
|
+
|
278
|
+
(defun noramark-match-definition-list-long (last)
|
279
|
+
(let (all open delimiter)
|
280
|
+
(cond ((search-forward-regexp "^[ \t]*\\(;:\\)[[:space:]]*?[^{]*?\\({\\)[[:space:]]*?\n" last t)
|
281
|
+
(beginning-of-line)
|
282
|
+
(setq open (list (match-beginning 1) (match-end 1))
|
283
|
+
delimiter (list (match-beginning 2) (match-end 2))
|
284
|
+
all (list (match-beginning 0) (match-end 0)))
|
285
|
+
(forward-line)
|
286
|
+
(set-match-data (append all open delimiter))
|
287
|
+
t)
|
288
|
+
(t nil))))
|
289
|
+
|
290
|
+
|
291
|
+
|
292
|
+
(defun noramark-match-inline-command (last)
|
293
|
+
(let (cmd id class param nparam open close)
|
294
|
+
(cond ((search-forward-regexp (concat "\\(\\[[A-Za-z0-9-_]+\\)" noramark-regex-command-param "\\({\\).*?\\(}]\\)") last t)
|
295
|
+
(beginning-of-line)
|
296
|
+
(setq cmd (list (match-beginning 1) (match-end 1))
|
297
|
+
id (list (match-beginning 2) (match-end 2))
|
298
|
+
class (list (match-beginning 4) (match-end 4))
|
299
|
+
param (list (match-beginning 6) (match-end 6))
|
300
|
+
nparam (list (match-beginning 7) (match-end 7))
|
301
|
+
open (list (match-beginning 8) (match-end 8))
|
302
|
+
close (list (match-beginning 9) (match-end 9))
|
303
|
+
all (list (match-beginning 0) (match-end 0)))
|
304
|
+
(goto-char (1+ (match-end 0)))
|
305
|
+
(set-match-data (append all cmd id class param nparam open close))
|
306
|
+
t)
|
307
|
+
(t nil))))
|
308
|
+
|
309
|
+
(defun noramark-match-pre-command (last)
|
310
|
+
"Match Noramark pre command from point to LAST."
|
311
|
+
(let (cmd id class param nparam open cm lang body close all)
|
312
|
+
(cond ((search-forward-regexp
|
313
|
+
noramark-regex-pre-head last t)
|
314
|
+
(beginning-of-line)
|
315
|
+
(setq cmd (list (match-beginning 1) (match-end 1))
|
316
|
+
id (list (match-beginning 2) (match-end 2))
|
317
|
+
class (list (match-beginning 4) (match-end 4))
|
318
|
+
param (list (match-beginning 6) (match-end 6))
|
319
|
+
nparam (list (match-beginning 7) (match-end 7))
|
320
|
+
open (list (match-beginning 8) (match-end 8)))
|
321
|
+
(setq body (list (point)))
|
322
|
+
(cond ((search-forward-regexp noramark-regex-pre-tail last t)
|
323
|
+
(forward-line)
|
324
|
+
(setq body (reverse (cons (1- (match-beginning 0)) body))
|
325
|
+
close (list (match-beginning 0) (match-end 0))
|
326
|
+
all (list (car cmd) (match-end 0)))
|
327
|
+
(set-match-data (append all cmd id class param nparam open body close))
|
328
|
+
t)
|
329
|
+
(t nil)))
|
330
|
+
(t nil))))
|
331
|
+
|
332
|
+
(defun noramark-match-fence (last)
|
333
|
+
"Match Noramark fence command from point to LAST."
|
334
|
+
(let (open lang param nparam body close all)
|
335
|
+
(cond ((search-forward-regexp noramark-regex-fence-head last t)
|
336
|
+
(beginning-of-line)
|
337
|
+
(setq open (list (match-beginning 1) (match-end 1))
|
338
|
+
lang (list (match-beginning 2) (match-end 2))
|
339
|
+
param (list (match-beginning 3) (match-end 3))
|
340
|
+
nparam (list (match-beginning 4) (match-end 4)))
|
341
|
+
(forward-line)
|
342
|
+
(setq body (list (point)))
|
343
|
+
(cond ((search-forward-regexp noramark-regex-fence-tail last t)
|
344
|
+
(setq body (reverse (cons (1- (match-beginning 0)) body))
|
345
|
+
close (list (match-beginning 0) (match-end 0))
|
346
|
+
all (list (car open) (match-end 0)))
|
347
|
+
(set-match-data (append all open lang param nparam body close))
|
348
|
+
t)
|
349
|
+
(t nil)))
|
350
|
+
(t nil))))
|
351
|
+
|
352
|
+
|
353
|
+
(defun noramark-match-pre-command-complex (last)
|
354
|
+
"Match Noramark pre command from point to LAST."
|
355
|
+
(let (cmd id class param nparam open lang body close all)
|
356
|
+
(cond ((search-forward-regexp
|
357
|
+
noramark-regex-pre-c-head last t)
|
358
|
+
(beginning-of-line)
|
359
|
+
(setq cmd (list (match-beginning 1) (match-end 1))
|
360
|
+
id (list (match-beginning 2) (match-end 2))
|
361
|
+
class (list (match-beginning 4) (match-end 4))
|
362
|
+
param (list (match-beginning 6) (match-end 6))
|
363
|
+
nparam (list (match-beginning 7) (match-end 7))
|
364
|
+
open (list (match-beginning 8) (match-end 8))
|
365
|
+
lang (list (match-beginning 9) (match-end 9)))
|
366
|
+
(setq body (list (point)))
|
367
|
+
(cond ((search-forward-regexp noramark-regex-pre-c-tail last t)
|
368
|
+
(forward-line)
|
369
|
+
(setq body (reverse (cons (1- (match-beginning 0)) body))
|
370
|
+
close (list (match-beginning 0) (match-end 0))
|
371
|
+
all (list (car cmd) (match-end 0)))
|
372
|
+
(set-match-data (append all cmd id class param nparam open lang body close))
|
373
|
+
t)
|
374
|
+
(t nil)))
|
375
|
+
(t nil))))
|
376
|
+
|
377
|
+
|
378
|
+
;;; Outline
|
379
|
+
(defun noramark-outline-level ()
|
380
|
+
"Return the depth to which a statement is nested in the outline."
|
381
|
+
(let ((mz (match-string 0)) (mo (match-string 1)))
|
382
|
+
(message "zero : %s one : %s" mz mo)
|
383
|
+
(- (match-end 1) (match-beginning 1))))
|
384
|
+
|
385
|
+
(defun noramark-reload-extensions ()
|
386
|
+
"Check settings, update font-lock keywords, and re-fontify buffer."
|
387
|
+
(interactive)
|
388
|
+
(when (eq major-mode 'noramark-mode)
|
389
|
+
(setq noramark-mode-font-lock-keywords
|
390
|
+
noramark-mode-font-lock-keywords-basic)
|
391
|
+
(setq font-lock-defaults '(noramark-mode-font-lock-keywords))
|
392
|
+
(font-lock-refresh-defaults)))
|
393
|
+
|
394
|
+
(defun noramark-font-lock-extend-region-pre ()
|
395
|
+
(eval-when-compile (defvar font-lock-beg) (defvar font-lock-end))
|
396
|
+
(save-excursion
|
397
|
+
(goto-char font-lock-beg)
|
398
|
+
(when (re-search-backward noramark-regex-pre-head nil t)
|
399
|
+
(let ((found (match-beginning 0)))
|
400
|
+
(goto-char font-lock-beg)
|
401
|
+
(when (re-search-forward noramark-regex-pre-tail nil t)
|
402
|
+
(setq font-lock-end (max (match-end 0) font-lock-end))
|
403
|
+
(setq font-lock-beg found))))))
|
404
|
+
|
405
|
+
(defun noramark-font-lock-extend-region-pre-c ()
|
406
|
+
(eval-when-compile (defvar font-lock-beg) (defvar font-lock-end))
|
407
|
+
(save-excursion
|
408
|
+
(goto-char font-lock-beg)
|
409
|
+
(when (re-search-backward noramark-regex-pre-c-head nil t)
|
410
|
+
(let ((found (match-beginning 0)))
|
411
|
+
(goto-char font-lock-beg)
|
412
|
+
(when (re-search-forward noramark-regex-pre-c-tail nil t)
|
413
|
+
(setq font-lock-end (max (match-end 0) font-lock-end))
|
414
|
+
(setq font-lock-beg found))))))
|
415
|
+
|
416
|
+
(defun noramark-font-lock-extend-region-frontmatter ()
|
417
|
+
(eval-when-compile (defvar font-lock-beg) (defvar font-lock-end))
|
418
|
+
(save-excursion
|
419
|
+
(goto-char font-lock-beg)
|
420
|
+
(cond ((re-search-backward "^---[[:space:]]*?$" nil t)
|
421
|
+
(let ((found (point)))
|
422
|
+
(goto-char font-lock-beg)
|
423
|
+
(beginning-of-line)
|
424
|
+
(cond ((re-search-forward "^---[[:space:]]*?$" nil t)
|
425
|
+
(setq font-lock-end (max (match-end 0) font-lock-end))
|
426
|
+
(setq font-lock-beg found)
|
427
|
+
t)
|
428
|
+
(t nil))))
|
429
|
+
(t nil))))
|
430
|
+
|
431
|
+
(defun noramark-font-lock-extend-region-fence ()
|
432
|
+
(eval-when-compile (defvar font-lock-beg) (defvar font-lock-end))
|
433
|
+
(save-excursion
|
434
|
+
(goto-char font-lock-beg)
|
435
|
+
(beginning-of-line)
|
436
|
+
(cond ((re-search-backward noramark-regex-fence-head nil t)
|
437
|
+
(let ((found (point)))
|
438
|
+
(goto-char font-lock-beg)
|
439
|
+
(beginning-of-line)
|
440
|
+
(cond ((re-search-forward noramark-regex-fence-tail nil t)
|
441
|
+
(setq font-lock-end (max (match-end 0) font-lock-end))
|
442
|
+
(setq font-lock-beg (min found font-lock-beg))
|
443
|
+
t)
|
444
|
+
(t nil))))
|
445
|
+
(t nil))))
|
446
|
+
|
447
|
+
;;; Keymap
|
448
|
+
|
449
|
+
(defvar noramark-mode-map
|
450
|
+
(let ((map (make-keymap)))
|
451
|
+
;; header navigation
|
452
|
+
(define-key map (kbd "C-c C-n") 'outline-next-visible-heading)
|
453
|
+
(define-key map (kbd "C-c C-p") 'outline-previous-visible-heading)
|
454
|
+
(define-key map (kbd "C-c C-f") 'outline-forward-same-level)
|
455
|
+
(define-key map (kbd "C-c C-b") 'outline-backward-same-level)
|
456
|
+
(define-key map (kbd "C-c C-u") 'outline-up-heading)
|
457
|
+
map)
|
458
|
+
"Keymap for NoraMark major mode.")
|
459
|
+
|
460
|
+
;;; Syntax Table ==============================================================
|
461
|
+
|
462
|
+
(defvar noramark-mode-syntax-table
|
463
|
+
(make-syntax-table text-mode-syntax-table)
|
464
|
+
"Syntax table for `noramark-mode'.")
|
465
|
+
|
466
|
+
;;; Mode Definition ==========================================================
|
467
|
+
|
468
|
+
;;;###autoload
|
469
|
+
(define-derived-mode noramark-mode text-mode "NoraMark"
|
470
|
+
"Major mode for editing NoraMark files."
|
471
|
+
;; Font lock.
|
472
|
+
(set (make-local-variable 'noramark-mode-font-lock-keywords) nil)
|
473
|
+
(set (make-local-variable 'font-lock-multiline) t)
|
474
|
+
(noramark-reload-extensions)
|
475
|
+
;; Outline mode
|
476
|
+
(make-local-variable 'outline-regexp)
|
477
|
+
(setq outline-regexp noramark-regex-header)
|
478
|
+
(make-local-variable 'outline-level)
|
479
|
+
(setq outline-level 'noramark-outline-level)
|
480
|
+
;; hooks
|
481
|
+
(add-hook 'font-lock-extend-region-functions
|
482
|
+
'noramark-font-lock-extend-region-pre)
|
483
|
+
(add-hook 'font-lock-extend-region-functions
|
484
|
+
'noramark-font-lock-extend-region-pre-c)
|
485
|
+
(add-hook 'font-lock-extend-region-functions
|
486
|
+
'noramark-font-lock-extend-region-frontmatter)
|
487
|
+
(add-hook 'font-lock-extend-region-functions
|
488
|
+
'noramark-font-lock-extend-region-fence))
|
489
|
+
|
490
|
+
|
491
|
+
;;;###autoload(add-to-list 'auto-mode-alist '("\\.nora\\'" . noramark-mode))
|
492
|
+
|
493
|
+
|
494
|
+
(provide 'noramark-mode)
|
495
|
+
|
496
|
+
;;; noramark-mode.el ends here
|
497
|
+
|