infoboxer 0.2.7 → 0.2.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +1 -0
- data/CHANGELOG.md +6 -0
- data/bin/infoboxer +11 -12
- data/infoboxer.gemspec +3 -2
- data/lib/infoboxer/core_ext.rb +1 -0
- data/lib/infoboxer/definitions/en.wikipedia.org.rb +13 -13
- data/lib/infoboxer/media_wiki/page.rb +4 -3
- data/lib/infoboxer/media_wiki/traits.rb +12 -10
- data/lib/infoboxer/media_wiki.rb +97 -68
- data/lib/infoboxer/navigation/lookup.rb +30 -26
- data/lib/infoboxer/navigation/sections.rb +33 -37
- data/lib/infoboxer/navigation/selector.rb +5 -6
- data/lib/infoboxer/navigation/shortcuts.rb +12 -11
- data/lib/infoboxer/navigation.rb +2 -1
- data/lib/infoboxer/parser/context.rb +12 -13
- data/lib/infoboxer/parser/html.rb +7 -6
- data/lib/infoboxer/parser/image.rb +25 -29
- data/lib/infoboxer/parser/inline.rb +82 -79
- data/lib/infoboxer/parser/paragraphs.rb +34 -37
- data/lib/infoboxer/parser/table.rb +26 -27
- data/lib/infoboxer/parser/template.rb +12 -4
- data/lib/infoboxer/parser/util.rb +11 -16
- data/lib/infoboxer/parser.rb +8 -1
- data/lib/infoboxer/templates/base.rb +3 -3
- data/lib/infoboxer/templates/set.rb +11 -10
- data/lib/infoboxer/tree/compound.rb +7 -6
- data/lib/infoboxer/tree/document.rb +1 -0
- data/lib/infoboxer/tree/html.rb +5 -4
- data/lib/infoboxer/tree/image.rb +8 -7
- data/lib/infoboxer/tree/inline.rb +4 -5
- data/lib/infoboxer/tree/linkable.rb +3 -5
- data/lib/infoboxer/tree/list.rb +15 -16
- data/lib/infoboxer/tree/node.rb +11 -10
- data/lib/infoboxer/tree/nodes.rb +24 -23
- data/lib/infoboxer/tree/paragraphs.rb +3 -2
- data/lib/infoboxer/tree/ref.rb +6 -3
- data/lib/infoboxer/tree/table.rb +13 -13
- data/lib/infoboxer/tree/template.rb +15 -15
- data/lib/infoboxer/tree/text.rb +2 -1
- data/lib/infoboxer/tree/wikilink.rb +9 -8
- data/lib/infoboxer/tree.rb +3 -2
- data/lib/infoboxer/version.rb +2 -1
- data/lib/infoboxer.rb +24 -26
- data/regression/pages/wyoming.wiki +1085 -0
- metadata +8 -21
- data/lib/infoboxer/media_wiki/mediawiktory_patch.rb +0 -23
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
module Infoboxer
|
3
4
|
module Navigation
|
4
5
|
# `Sections` module provides logical view on document strcture.
|
@@ -24,7 +25,7 @@ module Infoboxer
|
|
24
25
|
# lookup_parents(:Section) # => []
|
25
26
|
# ```
|
26
27
|
module Sections
|
27
|
-
# This module is included in {Tree::Document Document}, allowing
|
28
|
+
# This module is included in {Tree::Document Document}, allowing
|
28
29
|
# you to navigate through document's logical sections (and also
|
29
30
|
# included in each {Sections::Section} instance, allowing to navigate
|
30
31
|
# recursively).
|
@@ -35,9 +36,9 @@ module Infoboxer
|
|
35
36
|
#
|
36
37
|
# @return {Tree::Nodes}
|
37
38
|
def intro
|
38
|
-
children
|
39
|
-
take_while{|n| !n.is_a?(Tree::Heading)}
|
40
|
-
select{|n| n.is_a?(Tree::BaseParagraph)}
|
39
|
+
children
|
40
|
+
.take_while { |n| !n.is_a?(Tree::Heading) }
|
41
|
+
.select { |n| n.is_a?(Tree::BaseParagraph) }
|
41
42
|
end
|
42
43
|
|
43
44
|
# List of sections inside current container.
|
@@ -48,12 +49,12 @@ module Infoboxer
|
|
48
49
|
# document.sections # all top-level sections
|
49
50
|
# document.sections('Culture') # only "Culture" section
|
50
51
|
# document.sections(/^List of/) # all sections with heading matching pattern
|
51
|
-
#
|
52
|
-
# document.
|
52
|
+
#
|
53
|
+
# document.
|
53
54
|
# sections('Culture'). # long way of recieve nested section
|
54
55
|
# sections('Music') # (Culture / Music)
|
55
|
-
#
|
56
|
-
# document.
|
56
|
+
#
|
57
|
+
# document.
|
57
58
|
# sections('Culture', 'Music') # the same as above
|
58
59
|
#
|
59
60
|
# document.
|
@@ -69,14 +70,14 @@ module Infoboxer
|
|
69
70
|
h.count == 1 or fail(ArgumentError, "Undefined behavior with #{h}")
|
70
71
|
names.unshift(h.keys.first, h.values.first)
|
71
72
|
end
|
72
|
-
|
73
|
+
|
73
74
|
case names.count
|
74
75
|
when 0
|
75
76
|
@sections
|
76
77
|
when 1
|
77
|
-
@sections.select{|s| names.first === s.heading.text_}
|
78
|
+
@sections.select { |s| names.first === s.heading.text_ }
|
78
79
|
else
|
79
|
-
@sections.select{|s| names.first === s.heading.text_}.sections(*names[1..-1])
|
80
|
+
@sections.select { |s| names.first === s.heading.text_ }.sections(*names[1..-1])
|
80
81
|
end
|
81
82
|
end
|
82
83
|
|
@@ -87,10 +88,10 @@ module Infoboxer
|
|
87
88
|
return res if headings.empty?
|
88
89
|
level = headings.first.level
|
89
90
|
|
90
|
-
children
|
91
|
-
chunk{|n| n.matches?(Tree::Heading, level: level)}
|
92
|
-
drop_while{|is_heading,
|
93
|
-
each do |is_heading, nodes|
|
91
|
+
children
|
92
|
+
.chunk { |n| n.matches?(Tree::Heading, level: level) }
|
93
|
+
.drop_while { |is_heading, _nodes| !is_heading }
|
94
|
+
.each do |is_heading, nodes|
|
94
95
|
if is_heading
|
95
96
|
nodes.each do |node|
|
96
97
|
res << Section.new(node)
|
@@ -115,18 +116,19 @@ module Infoboxer
|
|
115
116
|
# @return {Tree::Nodes<Section>}
|
116
117
|
def in_sections
|
117
118
|
main_node = parent.is_a?(Tree::Document) ? self : lookup_parents[-2]
|
118
|
-
|
119
|
-
heading =
|
120
|
-
main_node.
|
121
|
-
|
122
|
-
|
123
|
-
|
119
|
+
|
120
|
+
heading =
|
121
|
+
if main_node.is_a?(Tree::Heading)
|
122
|
+
main_node.lookup_prev_siblings(Tree::Heading, level: main_node.level - 1).last
|
123
|
+
else
|
124
|
+
main_node.lookup_prev_siblings(Tree::Heading).last
|
125
|
+
end
|
124
126
|
return Tree::Nodes[] unless heading
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
)
|
127
|
+
|
128
|
+
body = heading.next_siblings
|
129
|
+
.take_while { |n| !n.is_a?(Tree::Heading) || n.level < heading.level }
|
130
|
+
|
131
|
+
section = Section.new(heading, body)
|
130
132
|
Tree::Nodes[section, *heading.in_sections]
|
131
133
|
end
|
132
134
|
end
|
@@ -137,11 +139,11 @@ module Infoboxer
|
|
137
139
|
module Nodes
|
138
140
|
# @!method sections(*names)
|
139
141
|
# @!method in_sections
|
140
|
-
|
141
|
-
[
|
142
|
-
define_method(sym)
|
143
|
-
make_nodes
|
144
|
-
|
142
|
+
|
143
|
+
%i[sections in_sections].each do |sym|
|
144
|
+
define_method(sym) do |*args|
|
145
|
+
make_nodes(map { |n| n.send(sym, *args) })
|
146
|
+
end
|
145
147
|
end
|
146
148
|
end
|
147
149
|
|
@@ -174,12 +176,6 @@ module Infoboxer
|
|
174
176
|
end
|
175
177
|
|
176
178
|
include Container
|
177
|
-
|
178
|
-
private
|
179
|
-
|
180
|
-
#def show_params
|
181
|
-
#super(level: heading.level, heading: heading.text)
|
182
|
-
#end
|
183
179
|
end
|
184
180
|
end
|
185
181
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
module Infoboxer
|
3
4
|
module Navigation
|
4
5
|
module Lookup
|
@@ -7,11 +8,11 @@ module Infoboxer
|
|
7
8
|
# See {Lookup::Node Lookup::Node} for detailed explanation of available selectors.
|
8
9
|
class Selector
|
9
10
|
include ProcMe
|
10
|
-
|
11
|
+
|
11
12
|
def initialize(*arg, &block)
|
12
13
|
@arg = [arg, block].flatten.compact.map(&method(:sym_to_class))
|
13
14
|
@arg.each do |a|
|
14
|
-
a.reject!{|
|
15
|
+
a.reject! { |_k, v| v.nil? } if a.is_a?(Hash)
|
15
16
|
end
|
16
17
|
end
|
17
18
|
|
@@ -26,7 +27,7 @@ module Infoboxer
|
|
26
27
|
end
|
27
28
|
|
28
29
|
def matches?(node)
|
29
|
-
@arg.all?{|a| arg_matches?(a, node)}
|
30
|
+
@arg.all? { |a| arg_matches?(a, node) }
|
30
31
|
end
|
31
32
|
|
32
33
|
private
|
@@ -44,9 +45,7 @@ module Infoboxer
|
|
44
45
|
when Proc
|
45
46
|
check.call(node)
|
46
47
|
when Hash
|
47
|
-
check.all?{|attr, value|
|
48
|
-
node.respond_to?(attr) && value === node.send(attr)
|
49
|
-
}
|
48
|
+
check.all? { |attr, value| node.respond_to?(attr) && value === node.send(attr) }
|
50
49
|
when Symbol
|
51
50
|
node.respond_to?(check) && node.send(check)
|
52
51
|
else
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
module Infoboxer
|
3
4
|
module Navigation
|
4
5
|
# See {Shortcuts::Node Shortcuts::Node} for everything!
|
@@ -83,19 +84,19 @@ module Infoboxer
|
|
83
84
|
|
84
85
|
# Returns true, if current node is **inside** bold.
|
85
86
|
def bold?
|
86
|
-
|
87
|
+
parent?(Tree::Bold)
|
87
88
|
end
|
88
89
|
|
89
90
|
# Returns true, if current node is **inside** italic.
|
90
91
|
def italic?
|
91
|
-
|
92
|
+
parent?(Tree::Italic)
|
92
93
|
end
|
93
94
|
|
94
95
|
# Returns true, if current node is **inside** heading.
|
95
96
|
#
|
96
97
|
# @param level optional concrete level to check
|
97
98
|
def heading?(level = nil)
|
98
|
-
|
99
|
+
parent?(Tree::Heading, level: level)
|
99
100
|
end
|
100
101
|
|
101
102
|
# Returns all infoboxes inside current node.
|
@@ -129,12 +130,12 @@ module Infoboxer
|
|
129
130
|
private
|
130
131
|
|
131
132
|
def ensure_traits
|
132
|
-
ensure_page.traits or fail(
|
133
|
+
ensure_page.traits or fail('No site traits found')
|
133
134
|
end
|
134
135
|
|
135
136
|
def ensure_page
|
136
137
|
(is_a?(MediaWiki::Page) ? self : lookup_parents(MediaWiki::Page).first) or
|
137
|
-
fail(
|
138
|
+
fail('Node is not inside Page, maybe parsed from text?')
|
138
139
|
end
|
139
140
|
end
|
140
141
|
|
@@ -154,12 +155,12 @@ module Infoboxer
|
|
154
155
|
# @!method infoboxes(*selectors, &block)
|
155
156
|
# @!method categories
|
156
157
|
|
157
|
-
[
|
158
|
-
|
159
|
-
each do |m|
|
160
|
-
define_method(m)
|
161
|
-
make_nodes
|
162
|
-
|
158
|
+
%i[wikilinks headings paragraphs external_links images
|
159
|
+
templates tables lists infoboxes infobox categories]
|
160
|
+
.each do |m|
|
161
|
+
define_method(m) do |*args|
|
162
|
+
make_nodes(map { |n| n.send(m, *args) })
|
163
|
+
end
|
163
164
|
end
|
164
165
|
end
|
165
166
|
end
|
data/lib/infoboxer/navigation.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
module Infoboxer
|
3
4
|
# Navigation is one of the things Infoboxer is proud about. It tries
|
4
5
|
# to be logical, unobtrusive and compact.
|
@@ -64,7 +65,7 @@ module Infoboxer
|
|
64
65
|
%w[lookup shortcuts sections].each do |nav|
|
65
66
|
require_relative "navigation/#{nav}"
|
66
67
|
end
|
67
|
-
|
68
|
+
|
68
69
|
class Tree::Node
|
69
70
|
include Navigation::Lookup::Node
|
70
71
|
include Navigation::Shortcuts::Node
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
require 'strscan'
|
3
4
|
|
4
5
|
module Infoboxer
|
@@ -8,9 +9,9 @@ module Infoboxer
|
|
8
9
|
attr_reader :traits
|
9
10
|
|
10
11
|
def initialize(text, traits = nil)
|
11
|
-
@lines = text
|
12
|
-
|
13
|
-
|
12
|
+
@lines = text
|
13
|
+
.gsub(/<!--.+?-->/m, '') # FIXME: will also kill comments inside <nowiki> tag
|
14
|
+
.split(/[\r\n]/)
|
14
15
|
@lineno = -1
|
15
16
|
@traits = traits || MediaWiki::Traits.default
|
16
17
|
@scanner = StringScanner.new('')
|
@@ -82,7 +83,7 @@ module Infoboxer
|
|
82
83
|
|
83
84
|
def scan_until(re, leave_pattern = false)
|
84
85
|
guard_eof!
|
85
|
-
|
86
|
+
|
86
87
|
res = _scan_until(re)
|
87
88
|
res[matched] = '' if res && !leave_pattern
|
88
89
|
res
|
@@ -102,14 +103,14 @@ module Infoboxer
|
|
102
103
|
# not using StringScanner#check, as it will change #matched value
|
103
104
|
eol? ||
|
104
105
|
(
|
105
|
-
(current =~ %r[^(</ref>|}})] || @inline_eol_sign && current =~ @inline_eol_sign) &&
|
106
|
-
(!exclude ||
|
106
|
+
(current =~ %r[^(</ref>|}})] || @inline_eol_sign && current =~ @inline_eol_sign) &&
|
107
|
+
(!exclude || Regexp.last_match(1) !~ exclude)
|
107
108
|
) # FIXME: ugly, but no idea of prettier solution
|
108
109
|
end
|
109
110
|
|
110
111
|
def scan_continued_until(re, leave_pattern = false)
|
111
112
|
res = ''
|
112
|
-
|
113
|
+
|
113
114
|
loop do
|
114
115
|
chunk = _scan_until(re)
|
115
116
|
case matched
|
@@ -122,7 +123,7 @@ module Infoboxer
|
|
122
123
|
eof? && fail!("Unfinished scan: #{re} not found")
|
123
124
|
end
|
124
125
|
end
|
125
|
-
|
126
|
+
|
126
127
|
res[/#{re}\Z/] = '' unless leave_pattern
|
127
128
|
res
|
128
129
|
end
|
@@ -156,23 +157,21 @@ module Infoboxer
|
|
156
157
|
end
|
157
158
|
|
158
159
|
def guard_eof!
|
159
|
-
|
160
|
-
@scanner or fail!("End of input reached")
|
160
|
+
@scanner or fail!('End of input reached')
|
161
161
|
end
|
162
162
|
|
163
163
|
def shift(amount)
|
164
164
|
@lineno += amount
|
165
165
|
current = @lines[lineno]
|
166
|
-
@next_lines = @lines[(lineno+1)..-1]
|
166
|
+
@next_lines = @lines[(lineno + 1)..-1]
|
167
167
|
if current
|
168
168
|
@scanner.string = current
|
169
169
|
@rest = current
|
170
|
-
@matched = nil
|
171
170
|
else
|
172
171
|
@scanner = nil
|
173
172
|
@rest = nil
|
174
|
-
@matched = nil
|
175
173
|
end
|
174
|
+
@matched = nil
|
176
175
|
end
|
177
176
|
end
|
178
177
|
end
|
@@ -1,18 +1,19 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
module Infoboxer
|
3
4
|
class Parser
|
4
5
|
module HTML
|
5
6
|
include Tree
|
6
|
-
|
7
|
+
|
7
8
|
def html
|
8
9
|
case
|
9
|
-
when @context.check(
|
10
|
+
when @context.check(%r{/[a-z]+>})
|
10
11
|
html_closing_tag
|
11
12
|
when @context.check(/br\s*>/)
|
12
13
|
html_br
|
13
14
|
when @context.check(%r{[a-z]+[^/>]*/>})
|
14
15
|
html_auto_closing_tag
|
15
|
-
when @context.check(
|
16
|
+
when @context.check(%r{[a-z]+[^>/]*>})
|
16
17
|
html_opening_tag
|
17
18
|
else
|
18
19
|
# not an HTML tag at all!
|
@@ -21,7 +22,7 @@ module Infoboxer
|
|
21
22
|
end
|
22
23
|
|
23
24
|
def html_closing_tag
|
24
|
-
@context.skip(
|
25
|
+
@context.skip(%r{/})
|
25
26
|
tag = @context.scan(/[a-z]+/)
|
26
27
|
@context.skip(/>/)
|
27
28
|
HTMLClosingTag.new(tag)
|
@@ -43,8 +44,8 @@ module Infoboxer
|
|
43
44
|
tag = @context.scan(/[a-z]+/)
|
44
45
|
attrs = @context.scan(/[^>]+/)
|
45
46
|
@context.skip(/>/)
|
46
|
-
contents = short_inline(
|
47
|
-
if @context.matched =~
|
47
|
+
contents = short_inline(%r{</#{tag}>})
|
48
|
+
if @context.matched =~ %r{</#{tag}>}
|
48
49
|
HTMLTag.new(tag, parse_params(attrs), contents)
|
49
50
|
else
|
50
51
|
[
|
@@ -1,19 +1,16 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
module Infoboxer
|
3
4
|
class Parser
|
4
5
|
module Image
|
5
6
|
include Tree
|
6
|
-
|
7
|
+
|
7
8
|
def image
|
8
9
|
@context.skip(re.file_namespace) or
|
9
10
|
@context.fail!("Something went wrong: it's not image?")
|
10
11
|
|
11
12
|
path = @context.scan_until(/\||\]\]/)
|
12
|
-
attrs =
|
13
|
-
image_attrs
|
14
|
-
else
|
15
|
-
{}
|
16
|
-
end
|
13
|
+
attrs = @context.matched == '|' ? image_attrs : {}
|
17
14
|
Tree::Image.new(path, attrs)
|
18
15
|
end
|
19
16
|
|
@@ -25,32 +22,31 @@ module Infoboxer
|
|
25
22
|
break if @context.matched == ']]'
|
26
23
|
end
|
27
24
|
|
28
|
-
nodes.map(&method(:image_attr))
|
29
|
-
|
30
|
-
|
25
|
+
nodes.map(&method(:image_attr))
|
26
|
+
.inject(&:merge)
|
27
|
+
.reject { |_k, v| v.nil? || v.empty? }
|
31
28
|
end
|
32
29
|
|
33
30
|
def image_attr(nodes)
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
else # it's caption, and can have inline markup!
|
31
|
+
# it's caption, and can have inline markup!
|
32
|
+
return {caption: ImageCaption.new(nodes)} unless nodes.count == 1 && nodes.first.is_a?(Text)
|
33
|
+
|
34
|
+
case (str = nodes.first.text)
|
35
|
+
when /^(thumb)(?:nail)?$/, /^(frame)(?:d)?$/
|
36
|
+
{type: Regexp.last_match(1)}
|
37
|
+
when 'frameless'
|
38
|
+
{type: str}
|
39
|
+
when 'border'
|
40
|
+
{border: str}
|
41
|
+
when /^(baseline|middle|sub|super|text-top|text-bottom|top|bottom)$/
|
42
|
+
{alignment: str}
|
43
|
+
when /^(\d*)(?:x(\d+))?px$/
|
44
|
+
{width: Regexp.last_match(1), height: Regexp.last_match(2)}
|
45
|
+
when /^link=(.*)$/i
|
46
|
+
{link: Regexp.last_match(1)}
|
47
|
+
when /^alt=(.*)$/i
|
48
|
+
{alt: Regexp.last_match(1)}
|
49
|
+
else # text-only caption
|
54
50
|
{caption: ImageCaption.new(nodes)}
|
55
51
|
end
|
56
52
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
module Infoboxer
|
3
4
|
class Parser
|
4
5
|
module Inline
|
@@ -33,13 +34,14 @@ module Infoboxer
|
|
33
34
|
nodes = Nodes[]
|
34
35
|
guarded_loop do
|
35
36
|
# FIXME: quick and UGLY IS HELL JUST TRYING TO MAKE THE SHIT WORK
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
37
|
+
chunk =
|
38
|
+
if @context.inline_eol_sign == /^\]/
|
39
|
+
@context.scan_until(re.short_inline_until_cache_brackets[until_pattern])
|
40
|
+
elsif @context.inline_eol_sign == /^\]\]/
|
41
|
+
@context.scan_until(re.short_inline_until_cache_brackets2[until_pattern])
|
42
|
+
else
|
43
|
+
@context.scan_until(re.short_inline_until_cache[until_pattern])
|
44
|
+
end
|
43
45
|
nodes << chunk
|
44
46
|
|
45
47
|
break if @context.matched_inline?(until_pattern)
|
@@ -80,89 +82,90 @@ module Infoboxer
|
|
80
82
|
end
|
81
83
|
|
82
84
|
private
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
wikilink
|
96
|
-
end
|
97
|
-
when /\[(.+)/
|
98
|
-
external_link($1)
|
99
|
-
when '{{'
|
100
|
-
template
|
101
|
-
when /<nowiki([^>]*)>/
|
102
|
-
nowiki($1)
|
103
|
-
when /<ref([^>]*)\/>/
|
104
|
-
reference($1, true)
|
105
|
-
when /<ref([^>]*)>/
|
106
|
-
reference($1)
|
107
|
-
when /<math>/
|
108
|
-
math
|
109
|
-
when '<'
|
110
|
-
html || Text.new(match) # it was not HTML, just accidental <
|
85
|
+
|
86
|
+
def inline_formatting(match)
|
87
|
+
case match
|
88
|
+
when "'''''"
|
89
|
+
BoldItalic.new(short_inline(/'''''/))
|
90
|
+
when "'''"
|
91
|
+
Bold.new(short_inline(/'''/))
|
92
|
+
when "''"
|
93
|
+
Italic.new(short_inline(/''/))
|
94
|
+
when '[['
|
95
|
+
if @context.check(re.file_namespace)
|
96
|
+
image
|
111
97
|
else
|
112
|
-
|
98
|
+
wikilink
|
113
99
|
end
|
100
|
+
when /\[(.+)/
|
101
|
+
external_link(Regexp.last_match(1))
|
102
|
+
when '{{'
|
103
|
+
template
|
104
|
+
when /<nowiki([^>]*)>/
|
105
|
+
nowiki(Regexp.last_match(1))
|
106
|
+
when %r{<ref([^>]*)/>}
|
107
|
+
reference(Regexp.last_match(1), true)
|
108
|
+
when /<ref([^>]*)>/
|
109
|
+
reference(Regexp.last_match(1))
|
110
|
+
when /<math>/
|
111
|
+
math
|
112
|
+
when '<'
|
113
|
+
html || Text.new(match) # it was not HTML, just accidental <
|
114
|
+
else
|
115
|
+
match # FIXME: TEMP
|
114
116
|
end
|
117
|
+
end
|
115
118
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
end
|
126
|
-
|
127
|
-
Wikilink.new(link, caption)
|
119
|
+
# http://en.wikipedia.org/wiki/Help:Link#Wikilinks
|
120
|
+
# [[abc]]
|
121
|
+
# [[a|b]]
|
122
|
+
def wikilink
|
123
|
+
link = @context.scan_continued_until(/\||\]\]/)
|
124
|
+
if @context.matched == '|'
|
125
|
+
@context.push_eol_sign(/^\]\]/)
|
126
|
+
caption = inline(/\]\]/)
|
127
|
+
@context.pop_eol_sign
|
128
128
|
end
|
129
129
|
|
130
|
-
|
131
|
-
|
132
|
-
# [http://www.example.org link name]
|
133
|
-
def external_link(protocol)
|
134
|
-
link = @context.scan_continued_until(/\s+|\]/)
|
135
|
-
if @context.matched =~ /\s+/
|
136
|
-
@context.push_eol_sign(/^\]/)
|
137
|
-
caption = short_inline(/\]/)
|
138
|
-
@context.pop_eol_sign
|
139
|
-
end
|
140
|
-
ExternalLink.new(protocol + link, caption)
|
141
|
-
end
|
130
|
+
Wikilink.new(link, caption)
|
131
|
+
end
|
142
132
|
|
143
|
-
|
144
|
-
|
145
|
-
|
133
|
+
# http://en.wikipedia.org/wiki/Help:Link#External_links
|
134
|
+
# [http://www.example.org]
|
135
|
+
# [http://www.example.org link name]
|
136
|
+
def external_link(protocol)
|
137
|
+
link = @context.scan_continued_until(/\s+|\]/)
|
138
|
+
if @context.matched =~ /\s+/
|
139
|
+
@context.push_eol_sign(/^\]/)
|
140
|
+
caption = short_inline(/\]/)
|
141
|
+
@context.pop_eol_sign
|
146
142
|
end
|
143
|
+
ExternalLink.new(protocol + link, caption)
|
144
|
+
end
|
147
145
|
|
148
|
-
|
149
|
-
|
150
|
-
|
146
|
+
def reference(param_str, closed = false)
|
147
|
+
children = closed ? Nodes[] : long_inline(%r{</ref>})
|
148
|
+
Ref.new(children, parse_params(param_str))
|
149
|
+
end
|
151
150
|
|
152
|
-
|
153
|
-
|
154
|
-
Text.new('')
|
155
|
-
else
|
156
|
-
Text.new(@context.scan_continued_until(/<\/nowiki>/))
|
157
|
-
end
|
158
|
-
end
|
151
|
+
def math
|
152
|
+
Math.new(@context.scan_continued_until(%r{</math>}))
|
159
153
|
end
|
160
154
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
155
|
+
def nowiki(tag_rest)
|
156
|
+
if tag_rest.end_with?('/')
|
157
|
+
Text.new('')
|
158
|
+
else
|
159
|
+
Text.new(@context.scan_continued_until(%r{</nowiki>}))
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
require_relative 'image'
|
165
|
+
require_relative 'html'
|
166
|
+
require_relative 'template'
|
167
|
+
include Infoboxer::Parser::Image
|
168
|
+
include Infoboxer::Parser::HTML
|
169
|
+
include Infoboxer::Parser::Template
|
167
170
|
end
|
168
171
|
end
|