arti_mark 0.0.1.beta0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,123 @@
1
+ module ArtiMark
2
+ class Syntax
3
+ include CommandLexer
4
+
5
+ attr_accessor :inline_handler, :linecommand_handler
6
+
7
+ def initialize
8
+ @inline_handler = Class.new do extend CommandLexer end
9
+ @linecommand_handler = Class.new do extend CommandLexer end
10
+ @block_parsers = []
11
+ @block_parsers <<
12
+ [
13
+ Proc.new { |lines| lex_line_command(lines[0])[:cmd] == 'newpage' },
14
+ Proc.new {
15
+ |lines, context, syntax|
16
+ lexed = lex_line_command(lines.shift)
17
+ if lexed[:params].size > 0
18
+ title = escape_html lexed[:params].first
19
+ else
20
+ title = nil
21
+ end
22
+ context.start_html(title)
23
+ }
24
+ ]
25
+
26
+ [DivParser.instance, ArticleParser.instance, ParagraphParser.instance, HeadParser.instance, BlockImageParser.instance, OrderedListParser.instance, UnorderedListParser.instance, DefinitionListParser.instance].each {
27
+ |parser|
28
+ @block_parsers << [
29
+ parser.method(:accept?),
30
+ parser.method(:parse)
31
+ ]
32
+ }
33
+
34
+ def @inline_handler.l(lexed, context)
35
+ ref = lexed[:params][0].strip
36
+ "<a#{class_string(lexed[:cls])} href='#{ref}'>#{lexed[:text].strip}</a>"
37
+ end
38
+
39
+ def @inline_handler.link(lexed, context)
40
+ l(lexed, context)
41
+ end
42
+
43
+ def @inline_handler.s(lexed, context)
44
+ cls, text = lexed[:cls], lexed[:text]
45
+ "<span#{class_string(cls)}>#{text.strip}</a>"
46
+ end
47
+
48
+ def @inline_handler.img(lexed, context)
49
+ cls, param, text = lexed[:cls], lexed[:params], lexed[:text]
50
+ "<img#{class_string(cls)} src='#{text.strip}' alt='#{param.join(' ')}' />"
51
+ end
52
+
53
+ def @inline_handler.ruby(lexed, context)
54
+ cls, param, text = lexed[:cls], lexed[:params], lexed[:text]
55
+ "<ruby#{class_string(cls)}>#{text.strip}<rp>(</rp><rt>#{param.join}</rt><rp>)</rp></ruby>"
56
+ end
57
+
58
+ # universal inline command handler
59
+ def @inline_handler.method_missing(cmd, *args)
60
+ cls, text = args[0][:cls], args[0][:text]
61
+ "<#{cmd}#{class_string(cls)}>#{text.strip}</#{cmd}>"
62
+ end
63
+
64
+ def @linecommand_handler.p(lexed, context)
65
+ cls, text = lexed[:cls], lexed[:text]
66
+ "<p#{class_string(cls)}>#{text.strip}</p>\n"
67
+ end
68
+
69
+ def @linecommand_handler.stylesheets(lexed, context)
70
+ context.stylesheets = lexed[:text].split(',').map {|s|
71
+ s.strip!
72
+ if s =~ /^(.+?\.css):\((.+?)\)$/
73
+ [$1, $2]
74
+ else
75
+ s
76
+ end
77
+ }
78
+ ''
79
+ end
80
+
81
+ def @linecommand_handler.title(lexed, context)
82
+ context.title = lexed[:text].strip
83
+ ''
84
+ end
85
+
86
+ #univarsal line command handler
87
+ def @linecommand_handler.method_missing(cmd, *args)
88
+ "<#{cmd}#{class_string(args[0][:cls])}>#{args[0][:text].strip}</#{cmd}>\n"
89
+ end
90
+
91
+
92
+ end
93
+
94
+ def determine_parser(lines, opt = {})
95
+ @block_parsers.each {
96
+ |accept, parser|
97
+ return parser if accept.call(lines)
98
+ }
99
+
100
+ if UniversalBlockParser.instance.accept?(lines)
101
+ UniversalBlockParser.instance.method(:parse)
102
+ elsif opt[:get_default]
103
+ default_parser
104
+ else
105
+ nil
106
+ end
107
+ end
108
+
109
+ def default_parser
110
+ ParagraphParser.instance.method(:parse)
111
+ end
112
+
113
+ def parse(lines, context)
114
+ throw "something wrong: #{lines}" if lines[0] == '}' # TODO: should do something here with paragraph_parser
115
+ if parser = determine_parser(lines)
116
+ parser.call(lines, context, self)
117
+ else
118
+ default_parser.call(lines, context, self)
119
+ end
120
+ end
121
+
122
+ end
123
+ end
@@ -0,0 +1,10 @@
1
+ require 'singleton'
2
+
3
+ module ArtiMark
4
+ class UniversalBlockParser
5
+ include CommonBlockParser, Singleton
6
+ def initialize
7
+ @command = /\w+/
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,14 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'singleton'
3
+
4
+ module ArtiMark
5
+ class UnorderedListParser
6
+ include ListParser, Singleton
7
+
8
+ def initialize
9
+ @cmd = /\*/
10
+ @blockname = 'ul'
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ module ArtiMark
2
+ VERSION = "0.0.1.beta0"
3
+ end
data/lib/arti_mark.rb ADDED
@@ -0,0 +1,45 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require "arti_mark/version"
3
+ require "arti_mark/command_lexer"
4
+ require "arti_mark/base_parser"
5
+ require 'arti_mark/common_block_parser'
6
+ require "arti_mark/paragraph_parser"
7
+ require "arti_mark/div_parser"
8
+ require "arti_mark/article_parser"
9
+ require "arti_mark/section_parser"
10
+ require "arti_mark/head_parser"
11
+ require "arti_mark/block_image_parser"
12
+ require "arti_mark/list_parser"
13
+ require "arti_mark/ordered_list_parser"
14
+ require "arti_mark/unordered_list_parser"
15
+ require "arti_mark/definition_list_parser"
16
+ require "arti_mark/universal_block_parser"
17
+ require 'arti_mark/syntax'
18
+ require 'arti_mark/context'
19
+
20
+ module ArtiMark
21
+ class Document
22
+ def initialize(param = {})
23
+ @context = Context.new(param)
24
+ @syntax = Syntax.new
25
+ end
26
+
27
+ def convert(text)
28
+ # split text to lines
29
+ lines = text.strip.gsub(/ /, ' ').gsub(/\r?\n(\r?\n)+/, "\n\n").split(/\r?\n/).map { |line| line.strip } # text preprocess should be plaggable
30
+ process_lines(lines, @context)
31
+ @context.result
32
+ end
33
+
34
+ def toc
35
+ @context.toc
36
+ end
37
+
38
+ def process_lines(lines, context)
39
+ while (lines.size > 0)
40
+ @syntax.parse(lines, context)
41
+ end
42
+ end
43
+
44
+ end
45
+ end
data/memo.txt ADDED
@@ -0,0 +1,22 @@
1
+ 「blockを取り出してパースする」
2
+ のではなく、
3
+ 「blockの先頭を認識したら、そのblockを処理するオブジェクトに処理をまかせる」
4
+
5
+ blockの処理
6
+
7
+ lineを取り出す
8
+ blockのend条件をチェック
9
+ endじゃなければ処理
10
+ endなら終了
11
+
12
+ end条件チェック:
13
+ paragraph: 他のブロック開始
14
+ ol/ul : リスト条件の終了
15
+ その他のブロック: 終端記号
16
+
17
+ 処理:
18
+ a. 他のブロック開始: ブロックパーサ起動
19
+ b. 通常のライン: ラインとして処理
20
+ c. 特殊処理 (ol/ul)
21
+
22
+ b/cについては、preがなければインラインコマンドを処理する。