Merge lp:~gatesphere/leo-editor/markdown_support into lp:leo-editor

Proposed by Jake Peck
Status: Merged
Approved by: Jake Peck
Approved revision: 5613
Merged at revision: 5758
Proposed branch: lp:~gatesphere/leo-editor/markdown_support
Merge into: lp:leo-editor
Diff against target: 739 lines (+644/-3)
3 files modified
leo/core/leoApp.py (+3/-0)
leo/modes/md.py (+543/-0)
leo/plugins/viewrendered.py (+98/-3)
To merge this branch: bzr merge lp:~gatesphere/leo-editor/markdown_support
Reviewer Review Type Date Requested Status
Jake Peck Approve
Review via email: mp+147256@code.launchpad.net

Description of the change

Adds support for markdown (.md) files to colorizer, as well as rendering support for .md files in viewrendered (requires the python module "markdown" from http://pypi.python.org/pypi/Markdown).

To post a comment you must log in.
5603. By Jake Peck

Correction on comment definitions for md mode.

5604. By Jake Peck

Updated viewrendered docstring

5605. By Jake Peck

Merged revs 5601-5602 from mainline

5606. By Jake Peck

Fancier colorizer, based on https://github.com/peterlynch/jEdit-modes/blob/master/markdown.xml - run through jEdit2py

5607. By Jake Peck

Added configurable support for markdown extensions.

5608. By Jake Peck

Merge upstream revision 5603

5609. By Jake Peck

merge upstream rev 5605

5610. By Jake Peck

merge upstream rev 5606

5611. By Jake Peck

Merge upstream rev 5634

5612. By Jake Peck

Merged upstrem rev. 5644

5613. By Jake Peck

Merged upstream rev 5757

Revision history for this message
Jake Peck (gatesphere) wrote :

All unit tests pass, code looks good.

review: Approve
Revision history for this message
Edward K. Ream (edreamleo) wrote :

On Thu, May 2, 2013 at 1:00 PM, <email address hidden> wrote:

> The proposal to merge lp:~gatesphere/leo-editor/markdown_support into
> lp:leo-editor has been updated.
>
> Status: Approved => Merged
>

Looks good. All unit tests pass here.

EKR

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'leo/core/leoApp.py'
--- leo/core/leoApp.py 2013-03-02 17:50:17 +0000
+++ leo/core/leoApp.py 2013-05-02 13:27:25 +0000
@@ -265,6 +265,7 @@
265 "makefile" : "#",265 "makefile" : "#",
266 "maple" : "//",266 "maple" : "//",
267 "matlab" : "%", # EKR: 2011/10/21267 "matlab" : "%", # EKR: 2011/10/21
268 "md" : "<!-- -->", # PeckJ: 2013/02/08
268 "ml" : "(* *)",269 "ml" : "(* *)",
269 "modula3" : "(* *)",270 "modula3" : "(* *)",
270 "moin" : "##",271 "moin" : "##",
@@ -428,6 +429,7 @@
428 "makefile" : "mak",429 "makefile" : "mak",
429 "maple" : "mpl",430 "maple" : "mpl",
430 "matlab" : "m",431 "matlab" : "m",
432 "md" : "md", # PeckJ: 2013/02/07
431 "ml" : "ml",433 "ml" : "ml",
432 "modula3" : "mod",434 "modula3" : "mod",
433 "moin" : "wiki",435 "moin" : "wiki",
@@ -573,6 +575,7 @@
573 "ly": "lilypond",575 "ly": "lilypond",
574 "m": "matlab", # EKR: 2011/10/21576 "m": "matlab", # EKR: 2011/10/21
575 "mak": "makefile",577 "mak": "makefile",
578 "md": "md", # PeckJ 2013/02/07
576 "ml": "ml",579 "ml": "ml",
577 "mm": "objective_c", # Only one extension is valid: .m580 "mm": "objective_c", # Only one extension is valid: .m
578 "mod": "modula3",581 "mod": "modula3",
579582
=== added file 'leo/modes/md.py'
--- leo/modes/md.py 1970-01-01 00:00:00 +0000
+++ leo/modes/md.py 2013-05-02 13:27:25 +0000
@@ -0,0 +1,543 @@
1# Leo colorizer control file for md mode.
2# This file is in the public domain.
3
4# Properties for md mode.
5properties = {
6 "commentEnd": "-->",
7 "commentStart": "<!--",
8 "indentSize": "4",
9 "maxLineLen": "120",
10 "tabSize": "4",
11}
12
13# Attributes dict for md_main ruleset.
14md_main_attributes_dict = {
15 "default": "null",
16 "digit_re": "",
17 "escape": "",
18 "highlight_digits": "true",
19 "ignore_case": "true",
20 "no_word_sep": "",
21}
22
23# Attributes dict for md_inline_markup ruleset.
24md_inline_markup_attributes_dict = {
25 "default": "MARKUP",
26 "digit_re": "",
27 "escape": "",
28 "highlight_digits": "true",
29 "ignore_case": "true",
30 "no_word_sep": "",
31}
32
33# Attributes dict for md_block_html_tags ruleset.
34md_block_html_tags_attributes_dict = {
35 "default": "MARKUP",
36 "digit_re": "",
37 "escape": "",
38 "highlight_digits": "true",
39 "ignore_case": "true",
40 "no_word_sep": "",
41}
42
43# Attributes dict for md_markdown ruleset.
44md_markdown_attributes_dict = {
45 "default": "MARKUP",
46 "digit_re": "",
47 "escape": "",
48 "highlight_digits": "true",
49 "ignore_case": "false",
50 "no_word_sep": "",
51}
52
53# Attributes dict for md_link_label_definition ruleset.
54md_link_label_definition_attributes_dict = {
55 "default": "KEYWORD3",
56 "digit_re": "",
57 "escape": "",
58 "highlight_digits": "true",
59 "ignore_case": "false",
60 "no_word_sep": "",
61}
62
63# Attributes dict for md_link_inline_url_title ruleset.
64md_link_inline_url_title_attributes_dict = {
65 "default": "KEYWORD3",
66 "digit_re": "",
67 "escape": "",
68 "highlight_digits": "true",
69 "ignore_case": "false",
70 "no_word_sep": "",
71}
72
73# Attributes dict for md_link_inline_url_title_close ruleset.
74md_link_inline_url_title_close_attributes_dict = {
75 "default": "KEYWORD3",
76 "digit_re": "",
77 "escape": "",
78 "highlight_digits": "true",
79 "ignore_case": "false",
80 "no_word_sep": "",
81}
82
83# Attributes dict for md_link_inline_label_close ruleset.
84md_link_inline_label_close_attributes_dict = {
85 "default": "LABEL",
86 "digit_re": "",
87 "escape": "",
88 "highlight_digits": "true",
89 "ignore_case": "false",
90 "no_word_sep": "",
91}
92
93# Attributes dict for md_markdown_blockquote ruleset.
94md_markdown_blockquote_attributes_dict = {
95 "default": "LABEL",
96 "digit_re": "",
97 "escape": "",
98 "highlight_digits": "true",
99 "ignore_case": "false",
100 "no_word_sep": "",
101}
102
103# Dictionary of attributes dictionaries for md mode.
104attributesDictDict = {
105 "md_block_html_tags": md_block_html_tags_attributes_dict,
106 "md_inline_markup": md_inline_markup_attributes_dict,
107 "md_link_inline_label_close": md_link_inline_label_close_attributes_dict,
108 "md_link_inline_url_title": md_link_inline_url_title_attributes_dict,
109 "md_link_inline_url_title_close": md_link_inline_url_title_close_attributes_dict,
110 "md_link_label_definition": md_link_label_definition_attributes_dict,
111 "md_main": md_main_attributes_dict,
112 "md_markdown": md_markdown_attributes_dict,
113 "md_markdown_blockquote": md_markdown_blockquote_attributes_dict,
114}
115
116# Keywords dict for md_main ruleset.
117md_main_keywords_dict = {}
118
119# Keywords dict for md_inline_markup ruleset.
120md_inline_markup_keywords_dict = {}
121
122# Keywords dict for md_block_html_tags ruleset.
123md_block_html_tags_keywords_dict = {}
124
125# Keywords dict for md_markdown ruleset.
126md_markdown_keywords_dict = {}
127
128# Keywords dict for md_link_label_definition ruleset.
129md_link_label_definition_keywords_dict = {}
130
131# Keywords dict for md_link_inline_url_title ruleset.
132md_link_inline_url_title_keywords_dict = {}
133
134# Keywords dict for md_link_inline_url_title_close ruleset.
135md_link_inline_url_title_close_keywords_dict = {}
136
137# Keywords dict for md_link_inline_label_close ruleset.
138md_link_inline_label_close_keywords_dict = {}
139
140# Keywords dict for md_markdown_blockquote ruleset.
141md_markdown_blockquote_keywords_dict = {}
142
143# Dictionary of keywords dictionaries for md mode.
144keywordsDictDict = {
145 "md_block_html_tags": md_block_html_tags_keywords_dict,
146 "md_inline_markup": md_inline_markup_keywords_dict,
147 "md_link_inline_label_close": md_link_inline_label_close_keywords_dict,
148 "md_link_inline_url_title": md_link_inline_url_title_keywords_dict,
149 "md_link_inline_url_title_close": md_link_inline_url_title_close_keywords_dict,
150 "md_link_label_definition": md_link_label_definition_keywords_dict,
151 "md_main": md_main_keywords_dict,
152 "md_markdown": md_markdown_keywords_dict,
153 "md_markdown_blockquote": md_markdown_blockquote_keywords_dict,
154}
155
156# Rules for md_main ruleset.
157
158def md_rule0(colorer, s, i):
159 return colorer.match_span(s, i, kind="comment1", begin="<!--", end="-->",
160 at_line_start=False, at_whitespace_end=False, at_word_start=False,
161 delegate="",exclude_match=False,
162 no_escape=False, no_line_break=False, no_word_break=False)
163
164def md_rule1(colorer, s, i):
165 return colorer.match_span(s, i, kind="markup", begin="<script", end="</script>",
166 at_line_start=True, at_whitespace_end=False, at_word_start=False,
167 delegate="html::javascript",exclude_match=False,
168 no_escape=False, no_line_break=False, no_word_break=False)
169
170def md_rule2(colorer, s, i):
171 return colorer.match_seq_regexp(s, i, kind="markup", regexp="<hr\\b([^<>])*?/?>",
172 at_line_start=True, at_whitespace_end=False, at_word_start=False, delegate="")
173
174def md_rule3(colorer, s, i):
175 return colorer.match_span_regexp(s, i, kind="markup", begin="<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|noscript|form|fieldset|iframe|math|ins|del)\\b", end="</$1>",
176 at_line_start=True, at_whitespace_end=False, at_word_start=False,
177 delegate="md::block_html_tags",exclude_match=False,
178 no_escape=False, no_line_break=False, no_word_break=False)
179
180def md_rule4(colorer, s, i):
181 return colorer.match_seq(s, i, kind="null", seq=" < ",
182 at_line_start=False, at_whitespace_end=False, at_word_start=False, delegate="")
183
184def md_rule5(colorer, s, i):
185 return colorer.match_span(s, i, kind="markup", begin="<", end=">",
186 at_line_start=False, at_whitespace_end=False, at_word_start=False,
187 delegate="md::inline_markup",exclude_match=False,
188 no_escape=False, no_line_break=False, no_word_break=False)
189
190
191# Rules dict for md_main ruleset.
192rulesDict1 = {
193 " ": [md_rule4,],
194 "<": [md_rule0,md_rule1,md_rule2,md_rule3,md_rule5,],
195}
196
197# Rules for md_inline_markup ruleset.
198
199
200# Rules dict for md_inline_markup ruleset.
201rulesDict2 = {}
202
203# Rules for md_block_html_tags ruleset.
204
205def md_rule6(colorer, s, i):
206 return colorer.match_eol_span_regexp(s, i, kind="invalid", regexp="[\\S]+",
207 at_line_start=True, at_whitespace_end=False, at_word_start=False,
208 delegate="", exclude_match=False)
209
210def md_rule7(colorer, s, i):
211 return colorer.match_eol_span_regexp(s, i, kind="invalid", regexp="{1,3}[\\S]+",
212 at_line_start=True, at_whitespace_end=False, at_word_start=False,
213 delegate="", exclude_match=False)
214
215def md_rule8(colorer, s, i):
216 return colorer.match_eol_span_regexp(s, i, kind="", regexp="( {4}|\\t)",
217 at_line_start=True, at_whitespace_end=False, at_word_start=False,
218 delegate="html::main", exclude_match=False)
219
220def md_rule9(colorer, s, i):
221 return colorer.match_span(s, i, kind="literal1", begin="\"", end="\"",
222 at_line_start=False, at_whitespace_end=False, at_word_start=False,
223 delegate="",exclude_match=False,
224 no_escape=False, no_line_break=False, no_word_break=False)
225
226def md_rule10(colorer, s, i):
227 return colorer.match_span(s, i, kind="literal1", begin="'", end="'",
228 at_line_start=False, at_whitespace_end=False, at_word_start=False,
229 delegate="",exclude_match=False,
230 no_escape=False, no_line_break=False, no_word_break=False)
231
232def md_rule11(colorer, s, i):
233 return colorer.match_seq(s, i, kind="operator", seq="=",
234 at_line_start=False, at_whitespace_end=False, at_word_start=False, delegate="")
235
236# Rules dict for md_block_html_tags ruleset.
237rulesDict3 = {
238 "\"": [md_rule9,],
239 "'": [md_rule10,],
240 "(": [md_rule8,],
241 "=": [md_rule11,],
242 "[": [md_rule6,],
243 "{": [md_rule7,],
244}
245
246# Rules for md_markdown ruleset.
247
248def md_rule12(colorer, s, i):
249 return colorer.match_eol_span_regexp(s, i, kind="", regexp="[ \\t]*(>[ \\t]{1})+",
250 at_line_start=True, at_whitespace_end=False, at_word_start=False,
251 delegate="md::markdown_blockquote", exclude_match=False)
252
253def md_rule13(colorer, s, i):
254 return colorer.match_seq(s, i, kind="null", seq="*",
255 at_line_start=False, at_whitespace_end=False, at_word_start=False, delegate="")
256
257def md_rule14(colorer, s, i):
258 return colorer.match_seq(s, i, kind="null", seq="_",
259 at_line_start=False, at_whitespace_end=False, at_word_start=False, delegate="")
260
261def md_rule15(colorer, s, i):
262 return colorer.match_seq(s, i, kind="null", seq="\\][",
263 at_line_start=False, at_whitespace_end=False, at_word_start=False, delegate="")
264
265def md_rule16(colorer, s, i):
266 return colorer.match_seq_regexp(s, i, kind="null", regexp="\\\\[\\Q*_\\`[](){}#+.!-\\E]",
267 at_line_start=False, at_whitespace_end=False, at_word_start=False, delegate="")
268
269def md_rule17(colorer, s, i):
270 return colorer.match_span(s, i, kind="literal2", begin="``` ruby", end="```",
271 at_line_start=True, at_whitespace_end=False, at_word_start=False,
272 delegate="ruby::main",exclude_match=False,
273 no_escape=False, no_line_break=False, no_word_break=False)
274
275def md_rule18(colorer, s, i):
276 return colorer.match_span(s, i, kind="literal2", begin="```", end="```",
277 at_line_start=True, at_whitespace_end=False, at_word_start=False,
278 delegate="",exclude_match=False,
279 no_escape=False, no_line_break=False, no_word_break=False)
280
281def md_rule19(colorer, s, i):
282 return colorer.match_span_regexp(s, i, kind="literal2", begin="(`{1,2})", end="$1",
283 at_line_start=False, at_whitespace_end=False, at_word_start=False,
284 delegate="",exclude_match=False,
285 no_escape=False, no_line_break=False, no_word_break=False)
286
287def md_rule20(colorer, s, i):
288 return colorer.match_eol_span_regexp(s, i, kind="literal2", regexp="( {4,}|\\t+)\\S",
289 at_line_start=True, at_whitespace_end=False, at_word_start=False,
290 delegate="", exclude_match=False)
291
292def md_rule21(colorer, s, i):
293 return colorer.match_eol_span_regexp(s, i, kind="keyword1", regexp="[=-]+",
294 at_line_start=True, at_whitespace_end=False, at_word_start=False,
295 delegate="", exclude_match=False)
296
297def md_rule22(colorer, s, i):
298 return colorer.match_eol_span_regexp(s, i, kind="keyword1", regexp="#{1,6}[ \\t]*(.+?)",
299 at_line_start=True, at_whitespace_end=False, at_word_start=False,
300 delegate="", exclude_match=False)
301
302def md_rule23(colorer, s, i):
303 return colorer.match_eol_span_regexp(s, i, kind="keyword1", regexp="[ ]{0,2}([ ]?[-_*][ ]?){3,}[ \\t]*",
304 at_line_start=True, at_whitespace_end=False, at_word_start=False,
305 delegate="", exclude_match=False)
306
307def md_rule24(colorer, s, i):
308 return colorer.match_seq_regexp(s, i, kind="keyword2", regexp="[ \\t]{0,}[*+-][ \\t]+",
309 at_line_start=True, at_whitespace_end=False, at_word_start=False, delegate="")
310
311def md_rule25(colorer, s, i):
312 return colorer.match_seq_regexp(s, i, kind="keyword2", regexp="[ \\t]{0,}\\d+\\.[ \\t]+",
313 at_line_start=True, at_whitespace_end=False, at_word_start=False, delegate="")
314
315def md_rule26(colorer, s, i):
316 return colorer.match_eol_span_regexp(s, i, kind="label", regexp="\\[(.*?)\\]\\:",
317 at_line_start=False, at_whitespace_end=True, at_word_start=False,
318 delegate="md::link_label_definition", exclude_match=False)
319
320def md_rule27(colorer, s, i):
321 return colorer.match_span_regexp(s, i, kind="keyword4", begin="!?\\[[\\p{Alnum}\\p{Blank}]*", end="\\]",
322 at_line_start=False, at_whitespace_end=False, at_word_start=False,
323 delegate="md::link_inline_url_title",exclude_match=False,
324 no_escape=False, no_line_break=True, no_word_break=False)
325
326def md_rule28(colorer, s, i):
327 return colorer.match_span_regexp(s, i, kind="literal3", begin="(\\*\\*|__)", end="$1",
328 at_line_start=False, at_whitespace_end=False, at_word_start=False,
329 delegate="",exclude_match=False,
330 no_escape=False, no_line_break=True, no_word_break=False)
331
332def md_rule29(colorer, s, i):
333 return colorer.match_span_regexp(s, i, kind="literal4", begin="(\\*|_)", end="$1",
334 at_line_start=False, at_whitespace_end=False, at_word_start=False,
335 delegate="",exclude_match=False,
336 no_escape=False, no_line_break=True, no_word_break=False)
337
338# Rules dict for md_markdown ruleset.
339rulesDict4 = {
340 "!": [md_rule27,],
341 "#": [md_rule22,],
342 "(": [md_rule19,md_rule20,md_rule28,md_rule29,],
343 "*": [md_rule13,],
344 "[": [md_rule12,md_rule21,md_rule23,md_rule24,md_rule25,],
345 "\\": [md_rule15,md_rule16,md_rule26,],
346 "_": [md_rule14,],
347 "`": [md_rule17,md_rule18,],
348}
349
350# Rules for md_link_label_definition ruleset.
351
352def md_rule30(colorer, s, i):
353 return colorer.match_seq_regexp(s, i, kind="null", regexp="\\\\[\\Q*_\\`[](){}#+.!-\\E]",
354 at_line_start=False, at_whitespace_end=False, at_word_start=False, delegate="")
355
356def md_rule31(colorer, s, i):
357 return colorer.match_seq(s, i, kind="operator", seq="\"",
358 at_line_start=False, at_whitespace_end=False, at_word_start=False, delegate="")
359
360def md_rule32(colorer, s, i):
361 return colorer.match_seq(s, i, kind="operator", seq="(",
362 at_line_start=False, at_whitespace_end=False, at_word_start=False, delegate="")
363
364def md_rule33(colorer, s, i):
365 return colorer.match_seq(s, i, kind="operator", seq=")",
366 at_line_start=False, at_whitespace_end=False, at_word_start=False, delegate="")
367
368
369# Rules dict for md_link_label_definition ruleset.
370rulesDict5 = {
371 "\"": [md_rule31,],
372 "(": [md_rule32,],
373 ")": [md_rule33,],
374 "\\": [md_rule30,],
375}
376
377# Rules for md_link_inline_url_title ruleset.
378
379def md_rule34(colorer, s, i):
380 return colorer.match_seq(s, i, kind="operator", seq="]",
381 at_line_start=False, at_whitespace_end=False, at_word_start=False, delegate="")
382
383def md_rule35(colorer, s, i):
384 return colorer.match_span_regexp(s, i, kind="keyword4", begin="\\[", end="\\]",
385 at_line_start=False, at_whitespace_end=False, at_word_start=False,
386 delegate="md::link_inline_label_close",exclude_match=False,
387 no_escape=False, no_line_break=True, no_word_break=False)
388
389def md_rule36(colorer, s, i):
390 return colorer.match_span_regexp(s, i, kind="keyword4", begin="\\(", end="\\)",
391 at_line_start=False, at_whitespace_end=False, at_word_start=False,
392 delegate="md::link_inline_url_title_close",exclude_match=False,
393 no_escape=False, no_line_break=True, no_word_break=False)
394
395# Rules dict for md_link_inline_url_title ruleset.
396rulesDict6 = {
397 "(": [md_rule36,],
398 "[": [md_rule35,],
399 "]": [md_rule34,],
400}
401
402# Rules for md_link_inline_url_title_close ruleset.
403
404def md_rule37(colorer, s, i):
405 return colorer.match_eol_span(s, i, kind="null", seq=")",
406 at_line_start=False, at_whitespace_end=False, at_word_start=False,
407 delegate="md::main", exclude_match=False)
408
409# Rules dict for md_link_inline_url_title_close ruleset.
410rulesDict7 = {
411 ")": [md_rule37,],
412}
413
414# Rules for md_link_inline_label_close ruleset.
415
416def md_rule38(colorer, s, i):
417 return colorer.match_eol_span(s, i, kind="null", seq="]",
418 at_line_start=False, at_whitespace_end=False, at_word_start=False,
419 delegate="md::main", exclude_match=False)
420
421# Rules dict for md_link_inline_label_close ruleset.
422rulesDict8 = {
423 "]": [md_rule38,],
424}
425
426# Rules for md_markdown_blockquote ruleset.
427
428def md_rule39(colorer, s, i):
429 return colorer.match_seq(s, i, kind="null", seq=" < ",
430 at_line_start=False, at_whitespace_end=False, at_word_start=False, delegate="")
431
432def md_rule40(colorer, s, i):
433 return colorer.match_span(s, i, kind="markup", begin="<", end=">",
434 at_line_start=False, at_whitespace_end=False, at_word_start=False,
435 delegate="md::inline_markup",exclude_match=False,
436 no_escape=False, no_line_break=False, no_word_break=False)
437
438def md_rule41(colorer, s, i):
439 return colorer.match_seq(s, i, kind="null", seq="*",
440 at_line_start=False, at_whitespace_end=False, at_word_start=False, delegate="")
441
442def md_rule42(colorer, s, i):
443 return colorer.match_seq(s, i, kind="null", seq="_",
444 at_line_start=False, at_whitespace_end=False, at_word_start=False, delegate="")
445
446def md_rule43(colorer, s, i):
447 return colorer.match_seq(s, i, kind="null", seq="\\][",
448 at_line_start=False, at_whitespace_end=False, at_word_start=False, delegate="")
449
450def md_rule44(colorer, s, i):
451 return colorer.match_seq_regexp(s, i, kind="null", regexp="\\\\[\\Q*_\\`[](){}#+.!-\\E]",
452 at_line_start=False, at_whitespace_end=False, at_word_start=False, delegate="")
453
454def md_rule45(colorer, s, i):
455 return colorer.match_span_regexp(s, i, kind="literal2", begin="(`{1,2})", end="$1",
456 at_line_start=False, at_whitespace_end=False, at_word_start=False,
457 delegate="",exclude_match=False,
458 no_escape=False, no_line_break=False, no_word_break=False)
459
460def md_rule46(colorer, s, i):
461 return colorer.match_eol_span_regexp(s, i, kind="literal2", regexp="( {4,}|\\t+)\\S",
462 at_line_start=False, at_whitespace_end=False, at_word_start=False,
463 delegate="", exclude_match=False)
464
465def md_rule47(colorer, s, i):
466 return colorer.match_eol_span_regexp(s, i, kind="keyword1", regexp="[=-]+",
467 at_line_start=False, at_whitespace_end=False, at_word_start=False,
468 delegate="", exclude_match=False)
469
470def md_rule48(colorer, s, i):
471 return colorer.match_eol_span_regexp(s, i, kind="keyword1", regexp="#{1,6}[ \\t]*(.+?)",
472 at_line_start=False, at_whitespace_end=False, at_word_start=False,
473 delegate="", exclude_match=False)
474
475def md_rule49(colorer, s, i):
476 return colorer.match_eol_span_regexp(s, i, kind="keyword1", regexp="[ ]{0,2}([ ]?[-_*][ ]?){3,}[ \\t]*",
477 at_line_start=False, at_whitespace_end=False, at_word_start=False,
478 delegate="", exclude_match=False)
479
480def md_rule50(colorer, s, i):
481 return colorer.match_seq_regexp(s, i, kind="keyword2", regexp="[ \\t]{0,}[*+-][ \\t]+",
482 at_line_start=False, at_whitespace_end=False, at_word_start=False, delegate="")
483
484def md_rule51(colorer, s, i):
485 return colorer.match_seq_regexp(s, i, kind="keyword2", regexp="[ \\t]{0,}\\d+\\.[ \\t]+",
486 at_line_start=False, at_whitespace_end=False, at_word_start=False, delegate="")
487
488def md_rule52(colorer, s, i):
489 return colorer.match_eol_span_regexp(s, i, kind="label", regexp="\\[(.*?)\\]\\:",
490 at_line_start=False, at_whitespace_end=False, at_word_start=False,
491 delegate="md::link_label_definition", exclude_match=False)
492
493def md_rule53(colorer, s, i):
494 return colorer.match_span_regexp(s, i, kind="keyword4", begin="!?\\[[\\p{Alnum}\\p{Blank}]*", end="\\]",
495 at_line_start=False, at_whitespace_end=False, at_word_start=False,
496 delegate="md::link_inline_url_title",exclude_match=False,
497 no_escape=False, no_line_break=True, no_word_break=False)
498
499def md_rule54(colorer, s, i):
500 return colorer.match_span_regexp(s, i, kind="literal3", begin="(\\*\\*|__)", end="$1",
501 at_line_start=False, at_whitespace_end=False, at_word_start=False,
502 delegate="",exclude_match=False,
503 no_escape=False, no_line_break=False, no_word_break=False)
504
505def md_rule55(colorer, s, i):
506 return colorer.match_span_regexp(s, i, kind="literal4", begin="(\\*|_)", end="$1",
507 at_line_start=False, at_whitespace_end=False, at_word_start=False,
508 delegate="",exclude_match=False,
509 no_escape=False, no_line_break=False, no_word_break=False)
510
511# Rules dict for md_markdown_blockquote ruleset.
512rulesDict9 = {
513 " ": [md_rule39,],
514 "!": [md_rule53,],
515 "#": [md_rule48,],
516 "(": [md_rule45,md_rule46,md_rule54,md_rule55,],
517 "*": [md_rule41,],
518 "<": [md_rule40,],
519 "[": [md_rule47,md_rule49,md_rule50,md_rule51,],
520 "\\": [md_rule43,md_rule44,md_rule52,],
521 "_": [md_rule42,],
522}
523
524# x.rulesDictDict for md mode.
525rulesDictDict = {
526 "md_block_html_tags": rulesDict3,
527 "md_inline_markup": rulesDict2,
528 "md_link_inline_label_close": rulesDict8,
529 "md_link_inline_url_title": rulesDict6,
530 "md_link_inline_url_title_close": rulesDict7,
531 "md_link_label_definition": rulesDict5,
532 "md_main": rulesDict1,
533 "md_markdown": rulesDict4,
534 "md_markdown_blockquote": rulesDict9,
535}
536
537# Import dict for md mode.
538importDict = {
539 "md_inline_markup": ["html::tags",],
540 "md_link_label_definition": ["md_link_label_definition::markdown",],
541 "md_main": ["md_main::markdown",],
542}
543
0544
=== modified file 'leo/plugins/viewrendered.py' (properties changed: -x to +x)
--- leo/plugins/viewrendered.py 2013-04-26 12:06:51 +0000
+++ leo/plugins/viewrendered.py 2013-05-02 13:27:25 +0000
@@ -9,9 +9,12 @@
9Dependencies9Dependencies
10============10============
1111
12This plugin uses docutils,http://docutils.sourceforge.net/, to render reStructuredText,12This plugin uses docutils, http://docutils.sourceforge.net/, to render reStructuredText,
13so installing docutils is highly recommended when using this plugin.13so installing docutils is highly recommended when using this plugin.
1414
15This plugin uses markdown, http://http://pypi.python.org/pypi/Markdown, to render Markdown,
16so installing markdown is highly recommended when using this plugin.
17
15Commands18Commands
16========19========
1720
@@ -88,6 +91,14 @@
88 91
89**Important**: reStructuredText errors and warnings will appear in red in the rendering pane.92**Important**: reStructuredText errors and warnings will appear in red in the rendering pane.
9093
94Rendering markdown
95==================
96Please see the markdown syntax document at http://daringfireball.net/projects/markdown/syntax
97for more information on markdown.
98
99Unless ``@string view-rendered-default-kind`` is set to ``md``, markdown rendering must be
100specified by putting it in a ``@md`` node.
101
91Special Renderings102Special Renderings
92===================103===================
93104
@@ -137,8 +148,13 @@
137 When True, hide the rendering pane for text-only renderings.148 When True, hide the rendering pane for text-only renderings.
138149
139- ``@string view-rendered-default-kind = rst``150- ``@string view-rendered-default-kind = rst``
140 The default kind of rendering. One of (big,rst,html)151 The default kind of rendering. One of (big,rst,md,html)
141 152
153- ``@string view-rendered-md-extensions = extra``
154 A comma-delineated list of markdown extensions to use.
155 Suitable extensions can be seen here:
156 http://pythonhosted.org/Markdown/extensions/index.html
157
142Acknowledgments158Acknowledgments
143================159================
144160
@@ -148,6 +164,8 @@
148Edward K. Ream generalized this plugin and added communication164Edward K. Ream generalized this plugin and added communication
149and coordination between the free_layout, NestedSplitter and viewrendered plugins.165and coordination between the free_layout, NestedSplitter and viewrendered plugins.
150166
167Jacob Peck added markdown support to this plugin.
168
151'''169'''
152#@-<< docstring >>170#@-<< docstring >>
153171
@@ -176,6 +194,13 @@
176 g.es_exception()194 g.es_exception()
177else:195else:
178 got_docutils = False196 got_docutils = False
197
198## markdown support, non-vital
199try:
200 from markdown import markdown
201 got_markdown = True
202except ImportError:
203 got_markdown = False
179 204
180try:205try:
181 import PyQt4.phonon as phonon206 import PyQt4.phonon as phonon
@@ -486,6 +511,7 @@
486 'html': pc.update_html,511 'html': pc.update_html,
487 'graphics-script': pc.update_graphics_script,512 'graphics-script': pc.update_graphics_script,
488 'image': pc.update_image,513 'image': pc.update_image,
514 'md': pc.update_md,
489 'movie': pc.update_movie,515 'movie': pc.update_movie,
490 'networkx': pc.update_networkx,516 'networkx': pc.update_networkx,
491 'rst': pc.update_rst,517 'rst': pc.update_rst,
@@ -752,6 +778,74 @@
752 w.setHtml(template)778 w.setHtml(template)
753 w.setReadOnly(True)779 w.setReadOnly(True)
754 780
781 #@+node:peckj.20130207132858.3671: *4* update_md
782 def update_md (self,s,keywords):
783
784 trace = False and not g.unitTesting
785 pc = self ; c = pc.c ; p = c.p
786 s = s.strip().strip('"""').strip("'''").strip()
787 isHtml = s.startswith('<') and not s.startswith('<<')
788
789 if trace: g.trace('isHtml',isHtml)
790
791 # Do this regardless of whether we show the widget or not.
792 w = pc.ensure_text_widget()
793 assert pc.w
794
795 if s:
796 pc.show()
797 else:
798 if pc.auto_hide:
799 pass # needs review
800 # pc.hide()
801 return
802
803 if got_markdown and not isHtml:
804 # Not html: convert to html.
805 path = g.scanAllAtPathDirectives(c,p) or c.getNodePath(p)
806 if not os.path.isdir(path):
807 path = os.path.dirname(path)
808 if os.path.isdir(path):
809 os.chdir(path)
810
811 try:
812 msg = '' # The error message from docutils.
813 if pc.title:
814 s = pc.underline(pc.title) + s
815 pc.title = None
816 mdext = c.config.getString('view-rendered-md-extensions') or 'extra'
817 mdext = [x.strip() for x in mdext.split(',')]
818 s = markdown(s, mdext)
819 s = g.toUnicode(s) # 2011/03/15
820 show = True
821 except SystemMessage as sm:
822 # g.trace(sm,sm.args)
823 msg = sm.args[0]
824 if 'SEVERE' in msg or 'FATAL' in msg:
825 s = 'MD error:\n%s\n\n%s' % (msg,s)
826
827 sb = w.verticalScrollBar()
828
829 if sb:
830 d = pc.scrollbar_pos_dict
831 if pc.node_changed:
832 # Set the scrollbar.
833 pos = d.get(p.v,sb.sliderPosition())
834 sb.setSliderPosition(pos)
835 else:
836 # Save the scrollbars
837 d[p.v] = pos = sb.sliderPosition()
838
839 if pc.kind in ('big','rst','html', 'md'):
840 w.setHtml(s)
841 if pc.kind == 'big':
842 w.zoomIn(4) # Doesn't work.
843 else:
844 w.setPlainText(s)
845
846 if sb and pos:
847 # Restore the scrollbars
848 sb.setSliderPosition(pos)
755 #@+node:ekr.20110320120020.14481: *4* update_movie849 #@+node:ekr.20110320120020.14481: *4* update_movie
756 def update_movie (self,s,keywords):850 def update_movie (self,s,keywords):
757 851
@@ -852,7 +946,8 @@
852 else:946 else:
853 # Save the scrollbars947 # Save the scrollbars
854 d[p.v] = pos = sb.sliderPosition()948 d[p.v] = pos = sb.sliderPosition()
855 if pc.kind in ('big','rst','html'):949
950 if pc.kind in ('big','rst','html', 'md'):
856 w.setHtml(s)951 w.setHtml(s)
857 if pc.kind == 'big':952 if pc.kind == 'big':
858 w.zoomIn(4) # Doesn't work.953 w.zoomIn(4) # Doesn't work.

Subscribers

People subscribed via source and target branches

to all changes: