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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5ee7b20c586d15b36f4f461c63b98335e9396088
4
- data.tar.gz: 3acba3835a8e034cd17068e3ac437f3a3eede844
3
+ metadata.gz: b3c7634c3b142ce5a88d05603a3c1e3511a629e5
4
+ data.tar.gz: f8f28a75f465ba76b21fd54afd7c65c75c16b733
5
5
  SHA512:
6
- metadata.gz: 2dff66fe2c8bd19a830fa4f05b89a3c948f7649a00573cf3e885093a4611100d5a4b7c05af96a138c50a6d6f92a0831ca458b5008b8010244f98791858014d76
7
- data.tar.gz: dad3396c2af1d582ea7b3479e6d6f88b9394cde4cae304269b349ca18da9175c1d891f10e2a0aff689b4467656f96a85cd1b87cd8bc8392db62c01e8fa06c0ea
6
+ metadata.gz: 8748711f3848e9bb9cfbbf9d2629d30ed43d434c1e9259dfe9b16e0fd47c0fd10606df33070ef97b5e22e5dce114635e5fbe879be344af37cd6da8a7a176d233
7
+ data.tar.gz: d27e161322269ea36b1bf6475cde05a1dce20551be6f59311a8777229e70051b40ef576b11ba15c75450a5e0018f2a57cde5690c0aae286cba02dd9da77e4e02
@@ -2,4 +2,4 @@ language: ruby
2
2
  rvm:
3
3
  - 2.0.0
4
4
  - 2.1.0
5
- script: bundle exec rake test
5
+ script: bundle exec rake spec
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. Its default mode is for Japanese text.
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 english, but the paragraph style is japanese)
48
+ An example of markup text (text is in English, but the paragraph style is Japanese)
48
49
 
49
- # line begins with # is a comment.
50
- # you don't need to indent noramark text.
50
+ // line begins with // is a comment.
51
+ // you don't need to indent noramark text.
51
52
 
52
- # page/document metadata in YAML frontmatter
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 [s.strong{this}] is available.
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
- <?xml version="1.0" encoding="UTF-8"?>
75
- <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
76
- <head>
77
- <title> test title</title>
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
- </head>
81
- <body>
82
- <article>
83
- <h1>header 1</h1>
84
- <div class='pgroup'>
85
- <p>article comes here.</p>
86
- <p>linebreak will produce paragraph.</p>
87
- </div>
88
- <div class='pgroup'>
89
- <p>blank line will produce</p>
90
- </div>
91
- <div class='column'>
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
- </body>
99
- </html>
95
+ </body>
96
+ </html>
97
+ ```
100
98
 
101
99
  Another example of markup text in non-japanese (paragraph style is default)
102
100
 
103
- # line begins with # is a comment.
104
- # you don't need to indent noramark text.
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 [s.strong{this}] is available.
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
- <?xml version="1.0" encoding="UTF-8"?>
128
- <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
129
- <head>
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
- </head>
134
- <body>
132
+ </head>
133
+ <body>
135
134
  <article>
136
- <h1>header 1</h1>
137
- <p>article comes here.<br />linebreak will produce paragraph.</p>
138
- <p>blank line will produce paragraph</p>
139
- <div class='column'>
140
- <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>
141
- </div>
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
- </body>
144
- </html>
142
+ </body>
143
+ </html>
144
+ ```
145
145
 
146
146
 
147
147
  Another example of markup text
148
148
 
149
- # Markdown-ish heading will creates section
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
- =: this is the first heading
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
- ==: this is the second heading
162
+ ## this is the second heading
163
163
 
164
164
  This section is nested.
165
165
 
166
- =: this is the third heading
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
- <?xml version="1.0" encoding="UTF-8"?>
173
- <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="en">
174
- <head>
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
- </head>
179
- <body>
179
+ </head>
180
+ <body>
180
181
  <section><h1>this is the first heading</h1>
181
- <div class='pgroup'><p>This line is in a section.</p>
182
- <p>This line is in a section.</p>
183
- </div>
184
- <section><h2>this is the second heading</h2>
185
- <div class='pgroup'><p>This section is nested.</p>
186
- </div>
187
- </section>
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
- <div class='pgroup'><p>will terminate lower level section</p>
191
- </div>
191
+ <div class='pgroup'><p>will terminate lower level section</p>
192
+ </div>
192
193
  </section>
193
- </body>
194
- </html>
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
- Simple Customization Sample
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
- for_node("speak", :modify) do # "speak" is selector for node. :modify is action.
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
- for_node({:type => :HeadedSection}, :replace) do
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
 
@@ -9,7 +9,7 @@ opt.on('--kconv') {
9
9
  }
10
10
 
11
11
  args = opt.parse(ARGV)
12
- input = args.length > 0 ? File.open(args[0]).read : STDIN.read
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
+