infoboxer 0.2.7 → 0.2.8
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.
- 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
|