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,9 +1,10 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
module Infoboxer
|
3
4
|
class Parser
|
4
5
|
module Paragraphs
|
5
6
|
include Tree
|
6
|
-
|
7
|
+
|
7
8
|
def paragraphs(until_pattern = nil)
|
8
9
|
nodes = Nodes[]
|
9
10
|
until @context.eof?
|
@@ -18,46 +19,42 @@ module Infoboxer
|
|
18
19
|
|
19
20
|
private
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
end
|
22
|
+
def paragraph(until_pattern)
|
23
|
+
case @context.current
|
24
|
+
when /^(?<level>={2,})\s*(?<text>.+?)\s*\k<level>$/
|
25
|
+
heading(Regexp.last_match[:text], Regexp.last_match[:level])
|
26
|
+
when /^\s*{\|/
|
27
|
+
table
|
28
|
+
when /^[\*\#:;]./
|
29
|
+
list(until_pattern)
|
30
|
+
when /^-{4,}/
|
31
|
+
HR.new
|
32
|
+
when /^\s*$/
|
33
|
+
# will, when merged, close previous paragraph or add spaces to <pre>
|
34
|
+
EmptyParagraph.new(@context.current)
|
35
|
+
when /^ (?!\s*{{)/ # Lookahead, because spaces before template are ignored
|
36
|
+
pre(until_pattern)
|
37
|
+
else
|
38
|
+
Paragraph.new(short_inline(until_pattern))
|
39
39
|
end
|
40
|
+
end
|
40
41
|
|
41
|
-
|
42
|
-
|
43
|
-
|
42
|
+
def heading(text, level)
|
43
|
+
Heading.new(Parser.inline(text), level.length)
|
44
|
+
end
|
44
45
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
46
|
+
# http://en.wikipedia.org/wiki/Help:List
|
47
|
+
def list(until_pattern)
|
48
|
+
marker = @context.scan(/^([*\#:;]+)\s*/).strip
|
49
|
+
List.construct(marker.chars.to_a, short_inline(until_pattern))
|
50
|
+
end
|
50
51
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
@context.current
|
58
|
-
end
|
59
|
-
Pre.new(Nodes[Text.new(str)])
|
60
|
-
end
|
52
|
+
# FIXME: in fact, there's some formatting, that should work inside pre
|
53
|
+
def pre(until_pattern)
|
54
|
+
@context.skip(/^ /)
|
55
|
+
str = until_pattern ? @context.scan_until(/(#{until_pattern}|$)/) : @context.current
|
56
|
+
Pre.new(Nodes[Text.new(str)])
|
57
|
+
end
|
61
58
|
|
62
59
|
require_relative 'table'
|
63
60
|
include Parser::Table
|
@@ -1,15 +1,19 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
module Infoboxer
|
3
4
|
class Parser
|
4
5
|
# http://en.wikipedia.org/wiki/Help:Table
|
5
6
|
module Table
|
6
7
|
include Tree
|
7
|
-
|
8
|
+
|
8
9
|
def table
|
9
|
-
|
10
|
+
@context.current =~ /^\s*{\|/ or
|
10
11
|
@context.fail!('Something went wrong: trying to parse not a table')
|
11
12
|
|
13
|
+
log 'Starting to parse table'
|
14
|
+
|
12
15
|
prms = table_params
|
16
|
+
log "Table params found #{prms}"
|
13
17
|
table = Tree::Table.new(Nodes[], prms)
|
14
18
|
|
15
19
|
@context.next!
|
@@ -20,7 +24,7 @@ module Infoboxer
|
|
20
24
|
end
|
21
25
|
|
22
26
|
# FIXME: not the most elegant way, huh?
|
23
|
-
table.children.reject!{|r| r.children.empty?}
|
27
|
+
table.children.reject! { |r| r.children.empty? }
|
24
28
|
|
25
29
|
table
|
26
30
|
end
|
@@ -34,55 +38,53 @@ module Infoboxer
|
|
34
38
|
case @context.current
|
35
39
|
when /^\s*\|}(.*)$/ # table end
|
36
40
|
@context.scan(/^\s*\|}/)
|
37
|
-
return false
|
38
|
-
|
41
|
+
return false
|
39
42
|
when /^\s*!/ # heading (th) in a row
|
40
43
|
table_cells(table, TableHeading)
|
41
|
-
|
42
44
|
when /^\s*\|\+/ # caption
|
43
45
|
table_caption(table)
|
44
|
-
|
45
46
|
when /^\s*\|-(.*)$/ # row start
|
46
|
-
table_row(table,
|
47
|
+
table_row(table, Regexp.last_match(1))
|
47
48
|
|
48
49
|
when /^\s*\|/ # cell in row
|
49
50
|
table_cells(table)
|
50
|
-
|
51
51
|
when /^\s*{{/ # template can be at row level
|
52
52
|
table_template(table)
|
53
|
-
|
54
53
|
when nil
|
55
54
|
return false
|
56
|
-
|
57
55
|
else
|
58
56
|
return table_cell_cont(table)
|
59
57
|
end
|
58
|
+
|
60
59
|
true # should continue parsing
|
61
60
|
end
|
62
61
|
|
63
62
|
def table_row(table, param_str)
|
63
|
+
log 'Table row found'
|
64
64
|
table.push_children(TableRow.new(Nodes[], parse_params(param_str)))
|
65
65
|
end
|
66
66
|
|
67
67
|
def table_caption(table)
|
68
|
+
log 'Table caption found'
|
68
69
|
@context.skip(/^\s*\|\+\s*/)
|
69
70
|
|
70
71
|
children = inline(/^\s*([|!]|{\|)/)
|
71
|
-
@context.prev! # compensate next! which will be done in table()
|
72
|
+
@context.prev! if @context.eol? # compensate next! which will be done in table()
|
72
73
|
table.push_children(TableCaption.new(children.strip))
|
73
74
|
end
|
74
75
|
|
75
76
|
def table_cells(table, cell_class = TableCell)
|
76
|
-
|
77
|
+
log 'Table cells found'
|
78
|
+
table.push_children(TableRow.new) unless table.children.last.is_a?(TableRow)
|
77
79
|
row = table.children.last
|
78
80
|
|
79
81
|
@context.skip(/\s*[!|]\s*/)
|
80
82
|
guarded_loop do
|
81
|
-
if @context.check(/[^|{|\[]+\|([^\|]|$)/)
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
83
|
+
params = if @context.check(/[^|{|\[]+\|([^\|]|$)/)
|
84
|
+
parse_params(@context.scan_until(/\|/))
|
85
|
+
else
|
86
|
+
{}
|
87
|
+
end
|
86
88
|
content = short_inline(/(\|\||!!)/)
|
87
89
|
row.push_children(cell_class.new(content, params))
|
88
90
|
break if @context.eol?
|
@@ -91,7 +93,7 @@ module Infoboxer
|
|
91
93
|
|
92
94
|
def table_template(table)
|
93
95
|
contents = paragraph(/^\s*([|!]|{\|)/).to_templates?
|
94
|
-
|
96
|
+
|
95
97
|
if (row = table.children.last).is_a?(TableRow)
|
96
98
|
if (cell = row.children.last).is_a?(BaseCell)
|
97
99
|
cell.push_children(*contents)
|
@@ -117,16 +119,13 @@ module Infoboxer
|
|
117
119
|
nil
|
118
120
|
end
|
119
121
|
|
120
|
-
|
122
|
+
unless container
|
121
123
|
# return "table not continued" unless row is empty
|
122
|
-
if @context.current.empty?
|
123
|
-
|
124
|
-
|
125
|
-
@context.prev!
|
126
|
-
return false
|
127
|
-
end
|
124
|
+
return true if @context.current.empty?
|
125
|
+
@context.prev!
|
126
|
+
return false
|
128
127
|
end
|
129
|
-
|
128
|
+
|
130
129
|
container.push_children(paragraph(/^\s*([|!]|{\|)/))
|
131
130
|
table.push_children(container) unless container.parent
|
132
131
|
true
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
module Infoboxer
|
3
4
|
class Parser
|
4
5
|
module Template
|
@@ -11,7 +12,9 @@ module Infoboxer
|
|
11
12
|
# More about magic words: https://www.mediawiki.org/wiki/Help:Magic_words
|
12
13
|
def template
|
13
14
|
name = @context.scan_continued_until(/\||:|}}/) or
|
14
|
-
@context.fail!(
|
15
|
+
@context.fail!('Template name not found')
|
16
|
+
|
17
|
+
log "Parsing template #{name}"
|
15
18
|
|
16
19
|
name.strip!
|
17
20
|
vars = @context.eat_matched?('}}') ? Nodes[] : template_vars
|
@@ -19,6 +22,8 @@ module Infoboxer
|
|
19
22
|
end
|
20
23
|
|
21
24
|
def template_vars
|
25
|
+
log 'Parsing template variables'
|
26
|
+
|
22
27
|
num = 1
|
23
28
|
res = Nodes[]
|
24
29
|
|
@@ -31,11 +36,14 @@ module Infoboxer
|
|
31
36
|
name = num
|
32
37
|
num += 1
|
33
38
|
end
|
39
|
+
log "Variable #{name} found"
|
34
40
|
|
35
41
|
value = long_inline(/\||}}/)
|
36
|
-
|
37
|
-
|
38
|
-
|
42
|
+
|
43
|
+
# it was just empty line otherwise
|
44
|
+
res << Var.new(name.to_s, value) unless value.empty? && name.is_a?(Numeric)
|
45
|
+
|
46
|
+
log 'Variable value found'
|
39
47
|
|
40
48
|
break if @context.eat_matched?('}}')
|
41
49
|
@context.eof? and @context.fail!("Unexpected break of template variables: #{res}")
|
@@ -1,19 +1,20 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
module Infoboxer
|
3
4
|
class Parser
|
4
5
|
module Util
|
5
6
|
attr_reader :re
|
6
7
|
|
7
|
-
FORMATTING =
|
8
|
+
FORMATTING = %r((
|
8
9
|
'''''|'''|'' | # bold, italic, bold italic
|
9
10
|
\[\[ | # link
|
10
11
|
{{ | # template
|
11
|
-
\[[a-z]
|
12
|
+
\[[a-z]+:// | # external link
|
12
13
|
<nowiki[^>]*> | # nowiki
|
13
14
|
<ref[^>]*> | # reference
|
14
15
|
<math> | # math
|
15
16
|
< # HTML tag
|
16
|
-
)
|
17
|
+
))x
|
17
18
|
|
18
19
|
INLINE_EOL = %r[(?= # if we have ahead... (not scanned, just checked
|
19
20
|
</ref> | # <ref> closed
|
@@ -24,7 +25,8 @@ module Infoboxer
|
|
24
25
|
</ref> | # <ref> closed
|
25
26
|
}} | # or template closed
|
26
27
|
(?<!\])\](?!\]) # or ext.link closed,
|
27
|
-
# the madness with look-ahead/behind means
|
28
|
+
# the madness with look-ahead/behind means
|
29
|
+
# "match single bracket but not double"
|
28
30
|
)]x
|
29
31
|
|
30
32
|
# FIXME: ok, NOW it's officially ridiculous
|
@@ -34,24 +36,22 @@ module Infoboxer
|
|
34
36
|
\]\] # or int.link closed
|
35
37
|
)]x
|
36
38
|
|
37
|
-
|
38
39
|
def make_regexps
|
39
40
|
{
|
40
41
|
file_namespace: /(#{@context.traits.file_namespace.join('|')}):/,
|
41
42
|
formatting: FORMATTING,
|
42
|
-
inline_until_cache: Hash.new{|h, r|
|
43
|
+
inline_until_cache: Hash.new { |h, r|
|
43
44
|
h[r] = Regexp.union(*[r, FORMATTING, /$/].compact.uniq)
|
44
45
|
},
|
45
|
-
short_inline_until_cache: Hash.new{|h, r|
|
46
|
+
short_inline_until_cache: Hash.new { |h, r|
|
46
47
|
h[r] = Regexp.union(*[r, INLINE_EOL, FORMATTING, /$/].compact.uniq)
|
47
48
|
},
|
48
|
-
short_inline_until_cache_brackets: Hash.new{|h, r|
|
49
|
+
short_inline_until_cache_brackets: Hash.new { |h, r|
|
49
50
|
h[r] = Regexp.union(*[r, INLINE_EOL_BRACK, FORMATTING, /$/].compact.uniq)
|
50
51
|
},
|
51
|
-
short_inline_until_cache_brackets2: Hash.new{|h, r|
|
52
|
+
short_inline_until_cache_brackets2: Hash.new { |h, r|
|
52
53
|
h[r] = Regexp.union(*[r, INLINE_EOL_BRACK2, FORMATTING, /$/].compact.uniq)
|
53
54
|
}
|
54
|
-
|
55
55
|
}
|
56
56
|
end
|
57
57
|
|
@@ -67,11 +67,7 @@ module Infoboxer
|
|
67
67
|
if scan.peek(1) == '='
|
68
68
|
scan.skip(/=\s*/)
|
69
69
|
q = scan.scan(/['"]/)
|
70
|
-
|
71
|
-
value = scan.scan_until(/#{q}|$/).sub(q, '')
|
72
|
-
else
|
73
|
-
value = scan.scan_until(/\s|$/)
|
74
|
-
end
|
70
|
+
value = q ? scan.scan_until(/#{q}|$/).sub(q, '') : scan.scan_until(/\s|$/)
|
75
71
|
params[name.to_sym] = value
|
76
72
|
else
|
77
73
|
params[name.to_sym] = name
|
@@ -89,7 +85,6 @@ module Infoboxer
|
|
89
85
|
@context.fail!("Infinite loop on position #{pos_after.last}")
|
90
86
|
end
|
91
87
|
end
|
92
|
-
|
93
88
|
end
|
94
89
|
end
|
95
90
|
end
|
data/lib/infoboxer/parser.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
require 'ostruct'
|
3
4
|
require 'procme'
|
5
|
+
require 'logger'
|
4
6
|
|
5
7
|
module Infoboxer
|
6
8
|
class Parser
|
@@ -47,12 +49,13 @@ module Infoboxer
|
|
47
49
|
end
|
48
50
|
end
|
49
51
|
end
|
50
|
-
|
52
|
+
|
51
53
|
include Tree
|
52
54
|
|
53
55
|
def initialize(context)
|
54
56
|
@context = context
|
55
57
|
@re = OpenStruct.new(make_regexps)
|
58
|
+
@logger = Logger.new(STDOUT).tap { |l| l.level = Logger::FATAL }
|
56
59
|
end
|
57
60
|
|
58
61
|
require_relative 'parser/inline'
|
@@ -65,6 +68,10 @@ module Infoboxer
|
|
65
68
|
|
66
69
|
require_relative 'parser/util'
|
67
70
|
include Parser::Util
|
71
|
+
|
72
|
+
def log(msg)
|
73
|
+
@logger.info "#{msg} | #{@context.lineno}:#{@context.colno}: #{@context.current}"
|
74
|
+
end
|
68
75
|
end
|
69
76
|
end
|
70
77
|
|
@@ -2,7 +2,7 @@ module Infoboxer
|
|
2
2
|
module Templates
|
3
3
|
class Base < Tree::Template
|
4
4
|
include Tree
|
5
|
-
|
5
|
+
|
6
6
|
class << self
|
7
7
|
attr_accessor :template_name, :template_options
|
8
8
|
|
@@ -16,7 +16,7 @@ module Infoboxer
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def ==(other)
|
19
|
-
other.
|
19
|
+
other.is_a?(Tree::Template) && _eq(other)
|
20
20
|
end
|
21
21
|
|
22
22
|
protected
|
@@ -49,7 +49,7 @@ module Infoboxer
|
|
49
49
|
# Used for {Set} definitions.
|
50
50
|
class Replace < Base
|
51
51
|
def replace
|
52
|
-
fail(NotImplementedError,
|
52
|
+
fail(NotImplementedError, 'Descendants should define :replace')
|
53
53
|
end
|
54
54
|
|
55
55
|
def text
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
module Infoboxer
|
3
4
|
module Templates
|
4
5
|
# Base class for defining set of templates, used for some site/domain.
|
@@ -20,7 +21,7 @@ module Infoboxer
|
|
20
21
|
|
21
22
|
# @private
|
22
23
|
def find(name)
|
23
|
-
_, template = @templates.detect{|m,
|
24
|
+
_, template = @templates.detect { |m, _t| m === name.downcase }
|
24
25
|
template || Base
|
25
26
|
end
|
26
27
|
|
@@ -43,15 +44,15 @@ module Infoboxer
|
|
43
44
|
# def from
|
44
45
|
# fetch_date('1', '2', '3')
|
45
46
|
# end
|
46
|
-
#
|
47
|
+
#
|
47
48
|
# def to
|
48
49
|
# fetch_date('4', '5', '6') || Date.today
|
49
50
|
# end
|
50
|
-
#
|
51
|
+
#
|
51
52
|
# def value
|
52
53
|
# (to - from).to_i / 365 # FIXME: obviously
|
53
54
|
# end
|
54
|
-
#
|
55
|
+
#
|
55
56
|
# def text
|
56
57
|
# "#{value} years"
|
57
58
|
# end
|
@@ -100,7 +101,7 @@ module Infoboxer
|
|
100
101
|
# Expected to be used inside Set definition block.
|
101
102
|
def replace(*replacements)
|
102
103
|
case
|
103
|
-
when replacements.count == 2 && replacements.all?{|r| r.is_a?(String)}
|
104
|
+
when replacements.count == 2 && replacements.all? { |r| r.is_a?(String) }
|
104
105
|
name, what = *replacements
|
105
106
|
setup_class(name, Replace) do
|
106
107
|
define_method(:replace) do
|
@@ -108,8 +109,8 @@ module Infoboxer
|
|
108
109
|
end
|
109
110
|
end
|
110
111
|
when replacements.count == 1 && replacements.first.is_a?(Hash)
|
111
|
-
replacements.first.each do |
|
112
|
-
replace(
|
112
|
+
replacements.first.each do |nm, rep|
|
113
|
+
replace(nm, rep)
|
113
114
|
end
|
114
115
|
else
|
115
116
|
fail(ArgumentError, "Can't call :replace with #{replacements.join(', ')}")
|
@@ -163,13 +164,13 @@ module Infoboxer
|
|
163
164
|
def setup_class(name, base_class, options = {}, &definition)
|
164
165
|
match = options.fetch(:match, name.downcase)
|
165
166
|
base = options.fetch(:base, base_class)
|
166
|
-
base =
|
167
|
+
base = find(base) if base.is_a?(String)
|
167
168
|
|
168
|
-
Class.new(base, &definition).tap
|
169
|
+
Class.new(base, &definition).tap do |cls|
|
169
170
|
cls.template_name = name
|
170
171
|
cls.template_options = options
|
171
172
|
@templates.unshift [match, cls]
|
172
|
-
|
173
|
+
end
|
173
174
|
end
|
174
175
|
end
|
175
176
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
module Infoboxer
|
3
4
|
module Tree
|
4
5
|
# Base class for all nodes with children.
|
@@ -6,7 +7,7 @@ module Infoboxer
|
|
6
7
|
def initialize(children = Nodes.new, params = {})
|
7
8
|
super(params)
|
8
9
|
@children = Nodes[*children]
|
9
|
-
@children.each{|c| c.parent = self}
|
10
|
+
@children.each { |c| c.parent = self }
|
10
11
|
end
|
11
12
|
|
12
13
|
# List of children
|
@@ -24,7 +25,7 @@ module Infoboxer
|
|
24
25
|
# @private
|
25
26
|
# Internal, used by {Parser}
|
26
27
|
def push_children(*nodes)
|
27
|
-
nodes.each{|c| c.parent = self}.each do |n|
|
28
|
+
nodes.each { |c| c.parent = self }.each do |n|
|
28
29
|
@children << n
|
29
30
|
end
|
30
31
|
end
|
@@ -40,15 +41,15 @@ module Infoboxer
|
|
40
41
|
"#{indent(level)}#{children.first.text} <#{descr}>\n"
|
41
42
|
else
|
42
43
|
"#{indent(level)}<#{descr}>\n" +
|
43
|
-
children.map(&call(to_tree: level+1)).join
|
44
|
+
children.map(&call(to_tree: level + 1)).join
|
44
45
|
end
|
45
46
|
end
|
46
47
|
|
47
48
|
# Kinda "private" methods, used by Parser only -------------------
|
48
|
-
|
49
|
+
|
49
50
|
# @private
|
50
51
|
# Internal, used by {Parser}
|
51
|
-
def can_merge?(
|
52
|
+
def can_merge?(_other)
|
52
53
|
false
|
53
54
|
end
|
54
55
|
|
@@ -80,7 +81,7 @@ module Infoboxer
|
|
80
81
|
|
81
82
|
def _eq(other)
|
82
83
|
children == other.children
|
83
|
-
end
|
84
|
+
end
|
84
85
|
end
|
85
86
|
end
|
86
87
|
end
|
data/lib/infoboxer/tree/html.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
module Infoboxer
|
3
4
|
module Tree
|
4
5
|
module HTMLTagCommons
|
5
|
-
BLOCK_TAGS = %w[div p br] # FIXME: are some other used in WP?
|
6
|
+
BLOCK_TAGS = %w[div p br].freeze # FIXME: are some other used in WP?
|
6
7
|
|
7
8
|
def text
|
8
9
|
super + (BLOCK_TAGS.include?(tag) ? "\n" : '')
|
@@ -27,7 +28,7 @@ module Infoboxer
|
|
27
28
|
# even empty tag, for ex., <br>, should not be dropped!
|
28
29
|
false
|
29
30
|
end
|
30
|
-
|
31
|
+
|
31
32
|
private
|
32
33
|
|
33
34
|
def descr
|
@@ -47,12 +48,12 @@ module Infoboxer
|
|
47
48
|
super(attrs)
|
48
49
|
@tag = tag
|
49
50
|
end
|
50
|
-
|
51
|
+
|
51
52
|
attr_reader :tag
|
52
53
|
alias_method :attrs, :params
|
53
54
|
|
54
55
|
include HTMLTagCommons
|
55
|
-
|
56
|
+
|
56
57
|
private
|
57
58
|
|
58
59
|
def descr
|
data/lib/infoboxer/tree/image.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
module Infoboxer
|
3
4
|
module Tree
|
4
5
|
# Represents image (or other media file).
|
@@ -16,16 +17,16 @@ module Infoboxer
|
|
16
17
|
# @return [Nodes]
|
17
18
|
attr_reader :caption
|
18
19
|
|
19
|
-
# @!attribute [r] path
|
20
|
+
# @!attribute [r] path
|
20
21
|
# @!attribute [r] type
|
21
|
-
# @!attribute [r] location
|
22
|
+
# @!attribute [r] location
|
22
23
|
# @!attribute [r] alignment
|
23
24
|
# @!attribute [r] link
|
24
|
-
# @!attribute [r] alt
|
25
|
+
# @!attribute [r] alt
|
25
26
|
|
26
27
|
def_readers :path, :type,
|
27
|
-
|
28
|
-
|
28
|
+
:location, :alignment, :link,
|
29
|
+
:alt
|
29
30
|
|
30
31
|
def border?
|
31
32
|
!params[:border].to_s.empty?
|
@@ -42,8 +43,8 @@ module Infoboxer
|
|
42
43
|
def to_tree(level = 0)
|
43
44
|
super(level) +
|
44
45
|
if caption && !caption.empty?
|
45
|
-
indent(level+1) + "caption:\n" +
|
46
|
-
|
46
|
+
indent(level + 1) + "caption:\n" +
|
47
|
+
caption.children.map(&call(to_tree: level + 2)).join
|
47
48
|
else
|
48
49
|
''
|
49
50
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
module Infoboxer
|
3
4
|
module Tree
|
4
5
|
# Represents italic text.
|
@@ -20,17 +21,15 @@ module Infoboxer
|
|
20
21
|
super(label || Nodes.new([Text.new(link)]), link: link)
|
21
22
|
end
|
22
23
|
|
23
|
-
|
24
|
+
# @!attribute [r] link
|
24
25
|
|
25
26
|
def_readers :link
|
26
27
|
end
|
27
28
|
|
28
29
|
# External link. Has other nodes as a contents, and, err, link (url).
|
29
30
|
class ExternalLink < Link
|
30
|
-
|
31
|
-
|
32
|
-
# synonym for `#link`
|
33
|
-
|
31
|
+
# @!attribute [r] url
|
32
|
+
# synonym for `#link`
|
34
33
|
alias_method :url, :link
|
35
34
|
end
|
36
35
|
end
|
@@ -23,20 +23,18 @@ module Infoboxer
|
|
23
23
|
# @return [String]
|
24
24
|
def url
|
25
25
|
# FIXME: fragile as hell.
|
26
|
-
page.url.sub(
|
26
|
+
page.url.sub(%r{[^/]+$}, link.tr(' ', '_'))
|
27
27
|
end
|
28
28
|
|
29
29
|
protected
|
30
30
|
|
31
31
|
def page
|
32
|
-
|
33
|
-
fail("Not in a page from real source")
|
32
|
+
lookup_parents(MediaWiki::Page).first or fail('Not in a page from real source')
|
34
33
|
end
|
35
34
|
|
36
35
|
def client
|
37
|
-
page.client or fail(
|
36
|
+
page.client or fail('MediaWiki client not set')
|
38
37
|
end
|
39
|
-
|
40
38
|
end
|
41
39
|
end
|
42
40
|
end
|