nora_mark 0.2beta7 → 0.2beta8
Sign up to get free protection for your applications and to get access to all the features.
- 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) [![Coverage Status](https://coveralls.io/repos/skoji/noramark/badge.png?branch=master)](https://coveralls.io/r/skoji/noramark?branch=master)
|
3
|
+
[![Dependency Status](https://gemnasium.com/skoji/noramark.png)](https://gemnasium.com/skoji/noramark)
|
3
4
|
[![Gem Version](https://badge.fury.io/rb/nora_mark.png)](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
|
+
|