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 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
+