nora_mark 0.2beta3

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.
@@ -0,0 +1,52 @@
1
+ # -*- coding: utf-8 -*-
2
+ module NoraMark
3
+ module Html
4
+ class ParagraphWriter
5
+ def initialize(generator)
6
+ @generator = generator
7
+ @context = generator.context
8
+ @writer_set = { use_paragraph_group: {
9
+ :paragraph =>
10
+ TagWriter.create('p', @generator, chop_last_space: true,
11
+ item_preprocessor: proc do |item|
12
+ add_class(item, 'noindent') if item[:children][0] =~/^(「|『|()/ # TODO: should be plaggable}
13
+ item
14
+ end
15
+ ),
16
+ :paragraph_group =>
17
+ TagWriter.create("div", @generator,
18
+ item_preprocessor: proc do |item|
19
+ add_class item, 'pgroup'
20
+ item[:no_tag] = true unless @context.enable_pgroup
21
+ item
22
+ end
23
+ )
24
+ },
25
+ default: {
26
+ :paragraph =>
27
+ TagWriter.create(nil, @generator, chop_last_space: true,
28
+ item_preprocessor: proc do |item|
29
+ item[:no_tag] = true
30
+ item
31
+ end),
32
+ :paragraph_group =>
33
+ TagWriter.create("p", @generator,
34
+ item_preprocessor: proc do |item|
35
+ item[:children] = item[:children].inject([]) do |memo, item|
36
+ memo << { :type => :br, :args => [] } if !memo.last.nil? && memo.last[:type] == :paragraph && item[:type] == :paragraph
37
+ memo << item
38
+ end
39
+ item
40
+ end
41
+ )
42
+ }
43
+ }
44
+ end
45
+ def write(item)
46
+ writer_set = @writer_set[@context.paragraph_style]
47
+ writer_set = @writer_set['default'] if writer_set.nil?
48
+ writer_set[item[:type]].write(item)
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,110 @@
1
+ module NoraMark
2
+ module Html
3
+ class TagWriter
4
+ include Util
5
+ attr_accessor :trailer, :item_preprocessors, :write_body_preprocessors
6
+
7
+ def self.create(tag_name, generator, item_preprocessor: nil, write_body_preprocessor: nil, trailer: "\n", chop_last_space: false)
8
+ instance = TagWriter.new(tag_name, generator, chop_last_space: chop_last_space)
9
+ instance.item_preprocessors << item_preprocessor unless item_preprocessor.nil?
10
+ instance.write_body_preprocessors << write_body_preprocessor unless write_body_preprocessor.nil?
11
+ instance.trailer = trailer
12
+ yield instance if block_given?
13
+ instance
14
+ end
15
+
16
+ def initialize(tag_name, generator, **param)
17
+ @tag_name = tag_name
18
+ @generator = generator
19
+ @context = generator.context
20
+ @trailer = trailer
21
+ @item_preprocessors = []
22
+ @write_body_preprocessors = []
23
+ @param = param
24
+ end
25
+
26
+ def attr_string(attrs)
27
+ attrs.map do
28
+ |name, vals|
29
+ if vals.size == 0
30
+ ''
31
+ else
32
+ " #{name}='#{vals.join(' ')}'"
33
+ end
34
+ end.join('')
35
+ end
36
+
37
+ def class_string(cls_array)
38
+ attr_string({'class' => cls_array})
39
+ end
40
+
41
+ def ids_string(ids_array)
42
+ attr_string({'id' => ids_array})
43
+ end
44
+
45
+ def add_class(item, cls)
46
+ (item[:classes] ||= []) << cls
47
+ end
48
+
49
+ def add_class_if_empty(item, cls)
50
+ add_class(item, cls) if item[:classes].nil? || item[:classes].size == 0
51
+ end
52
+
53
+ def tag_start(item)
54
+ return if item[:no_tag]
55
+ ids = item[:ids] || []
56
+ classes = item[:classes] || []
57
+ attr = item[:attrs] || {}
58
+ tag_name = @tag_name || item[:name]
59
+ @context << "<#{tag_name}#{ids_string(ids)}#{class_string(classes)}#{attr_string(attr)}"
60
+ if item[:no_body]
61
+ @context << " />"
62
+ else
63
+ @context << ">"
64
+ end
65
+ end
66
+
67
+ def output(string)
68
+ @context << string
69
+ end
70
+
71
+ def tag_end(item)
72
+ return if item[:no_tag]
73
+ tag_name = @tag_name || item[:name]
74
+ @context << "</#{tag_name}>#{@trailer}"
75
+ end
76
+
77
+ def write(item)
78
+ @item_preprocessors.each { |x| item = instance_exec item.dup, &x }
79
+ @context.enable_pgroup, saved_ep = !(item[:args].include?('wo-pgroup') || !@context.enable_pgroup), @context.enable_pgroup
80
+ tag_start item
81
+ write_body item if !item[:no_body]
82
+ tag_end item if !item[:no_body]
83
+ @context.enable_pgroup = saved_ep
84
+ end
85
+
86
+ def write_body(item)
87
+ @write_body_preprocessors.each {
88
+ |x|
89
+ return if instance_exec(item, &x) == :done
90
+ }
91
+ write_children item
92
+ end
93
+
94
+ def write_children(item)
95
+ write_array(item[:children])
96
+ end
97
+
98
+ def write_array(array)
99
+ return if array.nil? || array.size == 0
100
+ array.each { |x| @generator.to_html x }
101
+ @generator.context.chop_last_space if (@param[:chop_last_space])
102
+ end
103
+
104
+ def children_not_empty(item)
105
+ !item[:children].nil? && item[:children].size > 0 && item[:children].select { |x| (x.is_a? String) ? x.size >0 : !x.nil? }.size > 0
106
+ end
107
+
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,12 @@
1
+ module NoraMark
2
+ module Html
3
+ module Util
4
+ def escape_html(string)
5
+ string.to_s.gsub("&", "&amp;").
6
+ gsub("<", "&lt;").
7
+ gsub(">", "&gt;").
8
+ gsub('"', "&quot;")
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,24 @@
1
+ module NoraMark
2
+ module Html
3
+ class WriterSelector
4
+ def initialize(generator, tag_writers = {}, trailer_default: "\n" )
5
+ @generator = generator
6
+ @common_tag_writer = TagWriter.create(nil, @generator, trailer: trailer_default)
7
+ @tag_writers = tag_writers
8
+ if !trailer_default.nil?
9
+ @tag_writers.each { |k, t|
10
+ if t.is_a? TagWriter
11
+ t.trailer = trailer_default
12
+ end
13
+ }
14
+ end
15
+
16
+ end
17
+
18
+ def write(item)
19
+ writer = @tag_writers[item[:name]] || @common_tag_writer
20
+ writer.write(item)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,123 @@
1
+ %% name = NoraMark::Parser
2
+
3
+ # literals
4
+ eof = !.
5
+ space = ' ' | '\t'
6
+ eof_comment = lh space* "#" (!eof .)*
7
+ comment = lh space* "#" (!nl .)* nl empty_line*
8
+ - = ( space | comment )*
9
+ empty_line = lh - nl
10
+ nl = /\r?\n/
11
+ lh = /^/
12
+ le = nl | eof
13
+ word = < /[\w0-9]/ ( '-' | /[\w0-9]/ )* > { text }
14
+ num = < [0-9]+ > { text.to_i }
15
+
16
+
17
+ #common syntax
18
+ classname = '.' word:classname { classname }
19
+ classnames = (classname)*:classnames { classnames }
20
+ idname = '#' word:idname { idname }
21
+ idnames = (idname)*:idnames { idnames }
22
+
23
+ commandname = word:name idnames?:idnames classnames?:classes { {:name => name, :ids => idnames, :classes => classes} }
24
+ parameter = < ( /[^,)]/* | '"' /[^"]/* '"' | "'" /[^']/* "'" ) > { text }
25
+ parameters = < parameter (',' parameter)* > { text }
26
+ command = commandname:cn ('(' - parameters:arg - ')')? { arg ||= ''; cn.merge({ :args => arg.split(',') }) }
27
+
28
+ # paragraph
29
+ implicit_paragraph = < (!paragraph_delimiter - documentline:p -) > { create_item(:paragraph, nil, p, raw: text) }
30
+ paragraph = explicit_paragraph | implicit_paragraph
31
+
32
+ # paragraph_group
33
+ paragraph_group = < paragraph+:p empty_line* > { create_item(:paragraph_group, nil, p, raw: text) }
34
+
35
+ # explicit block
36
+ blockhead = lh - command:command - '{' - nl empty_line* { command }
37
+ blockend = lh - '}' - le empty_line*
38
+ blockbody = (!blockend block)+:body { body }
39
+ explicit_block = < blockhead:head - blockbody:body - blockend > { create_item(:block, head, body, raw: text) }
40
+
41
+ # preformatted block
42
+ preformatted_command = command:command &{ ['pre', 'precode'].include? command[:name] }
43
+ preformatted_command_head = lh - preformatted_command:command - '<<' &/[\w0-9]/ { command }
44
+ preformat_end(start) = lh word:delimiter &{ delimiter == start }
45
+ preformatted_block = < lh - preformatted_command_head:command !nl word:delimiter nl (!preformat_end(delimiter) (lh charstring nl))+:content preformat_end(delimiter) > { create_item(:preformatted, command, content, raw: text) }
46
+
47
+ # inline command
48
+ inline = img_inline | common_inline
49
+ common_inline = < '[' command:c '{' documentcontent_except('}'):content '}' ']' > { create_item(:inline, c, content, raw: text) }
50
+ img_command = command:c &{ c[:name] == 'img' && c[:args].size == 2}
51
+ img_inline = < '[' img_command:c ']' > { create_item(:inline, c, nil, raw: text) }
52
+
53
+ # special line commands
54
+ commandname_for_special_line_command = newpage_command | explicit_paragraph_command
55
+
56
+ # newpage
57
+ newpage_command = command:command &{ command[:name] == 'newpage' }
58
+ newpage = < lh - newpage_command:c ':' documentcontent?:content - nl > { create_item(:newpage, c, content, raw:text) }
59
+
60
+ # explicit paragraph
61
+ explicit_paragraph_command = command:c &{ c[:name] == 'p' }
62
+ explicit_paragraph = < lh - explicit_paragraph_command:c ':' documentcontent?:content le empty_line*> { create_item(:paragraph, c, content, raw:text) }
63
+
64
+
65
+ # unordered list
66
+ unordered_list = < unordered_item+:items > { create_item(:ul, nil, items, raw: text) }
67
+ unordered_item = < lh '*:' documentcontent:content le > { create_item(:li, nil, content, raw: text) }
68
+
69
+ # ordered list
70
+ ordered_list = < ordered_item+:items > { create_item(:ol, nil, items, raw: text) }
71
+ ordered_item = < lh num ':' documentcontent:content le > { create_item(:li, nil, content, raw: text) }
72
+
73
+ # definition list
74
+ definition_list = < definition_item+:items > { create_item(:dl, nil, items, raw: text) }
75
+ definition_item = < lh ';:' - documentcontent_except(':'):term ':' - documentcontent:definition le > { create_item(:dtdd, {:args => [term, definition]}, nil, raw: text) }
76
+
77
+ items_list = unordered_list | ordered_list | definition_list
78
+
79
+
80
+ # generic line command
81
+ line_command = < lh - !commandname_for_special_line_command command:c ':' documentcontent?:content - le empty_line* > { create_item(:line_command, c, content, raw: text) }
82
+
83
+ # blocks
84
+ line_block = items_list | line_command
85
+ block = (preformatted_block | headed_section | line_block | explicit_block | paragraph_group ):block empty_line* {block}
86
+ block_delimiter = blockhead | blockend
87
+ paragraph_delimiter = block_delimiter | preformatted_command_head | line_block | newpage | headed_start
88
+
89
+ # markdown-style headings
90
+ h_start_mark(n) = < '='+ ':' > &{ text.length - 1 == n }
91
+ h_markup_terminator(n) = lh - < '='+ ':' > &{ text.length - 1 <= n }
92
+
93
+ h_start(n) = lh - h_start_mark(n) charstring:s le { { level: n, heading: s } }
94
+ h_section(n) = < h_start(n):h (!h_markup_terminator(n) !eof block)+:content > { create_item(:h_section, h, content, raw: text) }
95
+
96
+ headed_start = h_start(1) | h_start(2) | h_start(3) | h_start(4) | h_start(5) | h_start(6)
97
+ headed_section = h_section(1) | h_section(2)| h_section(3)| h_section(4)| h_section(5) | h_section(6)
98
+
99
+ #header
100
+ stylesheets = < lh - 'stylesheets:' !le charstring:s nl > { create_item(:stylesheets, {:stylesheets => s.split(',').map(&:strip)}, nil, raw:text) }
101
+ title = < lh - 'title:' !le charstring:t nl > { create_item(:title, {:title => t }, nil, raw:text) }
102
+ lang = < lh - 'lang:' !le charstring:l nl > { create_item(:lang, {:lang => l }, nil, raw:text) }
103
+ paragraph_style = < lh - 'paragraph-style:' !le charstring:l nl > { create_item(:paragraph_style, {:paragraph_style => l }, nil, raw:text) }
104
+ header = (stylesheets | title | lang | paragraph_style ) empty_line*
105
+
106
+ # texts
107
+ char = < /[[:print:]]/ > { text }
108
+ charstring = < char* > { text }
109
+ char_except(e) = char:c &{ c != e }
110
+ charstring_except(e) = < char_except(e)* > { text }
111
+ documentcontent_except(e) = (inline | !inline char_except(e))+:content ~parse_text(content)
112
+ documentcontent = (inline | !inline char)+:content ~parse_text(content)
113
+ documentline = lh documentcontent:content le { content }
114
+
115
+ #page
116
+ headers = header*:headers { create_item(:headers, nil, headers) }
117
+ page = headers:headers - (!newpage block)*:blocks { create_item(:page, nil, [headers] + blocks.select{ |x| !x.nil?}) }
118
+ newpaged_page = newpage:newpage page:page { page[:children] = page[:children].unshift newpage; page }
119
+ #root
120
+ root = page:page newpaged_page*:pages - eof_comment? eof { [ page ] + pages }
121
+
122
+
123
+