infoboxer 0.2.7 → 0.2.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +1 -0
  3. data/CHANGELOG.md +6 -0
  4. data/bin/infoboxer +11 -12
  5. data/infoboxer.gemspec +3 -2
  6. data/lib/infoboxer/core_ext.rb +1 -0
  7. data/lib/infoboxer/definitions/en.wikipedia.org.rb +13 -13
  8. data/lib/infoboxer/media_wiki/page.rb +4 -3
  9. data/lib/infoboxer/media_wiki/traits.rb +12 -10
  10. data/lib/infoboxer/media_wiki.rb +97 -68
  11. data/lib/infoboxer/navigation/lookup.rb +30 -26
  12. data/lib/infoboxer/navigation/sections.rb +33 -37
  13. data/lib/infoboxer/navigation/selector.rb +5 -6
  14. data/lib/infoboxer/navigation/shortcuts.rb +12 -11
  15. data/lib/infoboxer/navigation.rb +2 -1
  16. data/lib/infoboxer/parser/context.rb +12 -13
  17. data/lib/infoboxer/parser/html.rb +7 -6
  18. data/lib/infoboxer/parser/image.rb +25 -29
  19. data/lib/infoboxer/parser/inline.rb +82 -79
  20. data/lib/infoboxer/parser/paragraphs.rb +34 -37
  21. data/lib/infoboxer/parser/table.rb +26 -27
  22. data/lib/infoboxer/parser/template.rb +12 -4
  23. data/lib/infoboxer/parser/util.rb +11 -16
  24. data/lib/infoboxer/parser.rb +8 -1
  25. data/lib/infoboxer/templates/base.rb +3 -3
  26. data/lib/infoboxer/templates/set.rb +11 -10
  27. data/lib/infoboxer/tree/compound.rb +7 -6
  28. data/lib/infoboxer/tree/document.rb +1 -0
  29. data/lib/infoboxer/tree/html.rb +5 -4
  30. data/lib/infoboxer/tree/image.rb +8 -7
  31. data/lib/infoboxer/tree/inline.rb +4 -5
  32. data/lib/infoboxer/tree/linkable.rb +3 -5
  33. data/lib/infoboxer/tree/list.rb +15 -16
  34. data/lib/infoboxer/tree/node.rb +11 -10
  35. data/lib/infoboxer/tree/nodes.rb +24 -23
  36. data/lib/infoboxer/tree/paragraphs.rb +3 -2
  37. data/lib/infoboxer/tree/ref.rb +6 -3
  38. data/lib/infoboxer/tree/table.rb +13 -13
  39. data/lib/infoboxer/tree/template.rb +15 -15
  40. data/lib/infoboxer/tree/text.rb +2 -1
  41. data/lib/infoboxer/tree/wikilink.rb +9 -8
  42. data/lib/infoboxer/tree.rb +3 -2
  43. data/lib/infoboxer/version.rb +2 -1
  44. data/lib/infoboxer.rb +24 -26
  45. data/regression/pages/wyoming.wiki +1085 -0
  46. metadata +8 -21
  47. 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
- def paragraph(until_pattern)
22
- case @context.current
23
- when /^(?<level>={2,})\s*(?<text>.+?)\s*\k<level>$/
24
- heading(Regexp.last_match[:text], Regexp.last_match[:level])
25
- when /^\s*{\|/
26
- table
27
- when /^[\*\#:;]./
28
- list(until_pattern)
29
- when /^-{4,}/
30
- HR.new
31
- when /^\s*$/
32
- # will, when merged, close previous paragraph or add spaces to <pre>
33
- EmptyParagraph.new(@context.current)
34
- when /^ (?!\s*{{)/ # Lookahead, because spaces before template are ignored
35
- pre(until_pattern)
36
- else
37
- Paragraph.new(short_inline(until_pattern))
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
- def heading(text, level)
42
- Heading.new(Parser.inline(text), level.length)
43
- end
42
+ def heading(text, level)
43
+ Heading.new(Parser.inline(text), level.length)
44
+ end
44
45
 
45
- # http://en.wikipedia.org/wiki/Help:List
46
- def list(until_pattern)
47
- marker = @context.scan(/^([*\#:;]+)\s*/).strip
48
- List.construct(marker.chars.to_a, short_inline(until_pattern))
49
- end
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
- # FIXME: in fact, there's some formatting, that should work inside pre
52
- def pre(until_pattern)
53
- @context.skip(/^ /)
54
- str = if until_pattern
55
- @context.scan_until(/(#{until_pattern}|$)/)
56
- else
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
- @context.current =~ /^\s*{\|/ or
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 # should not continue
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, $1)
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
- table.push_children(TableRow.new()) unless table.children.last.is_a?(TableRow)
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
- params = parse_params(@context.scan_until(/\|/))
83
- else
84
- params = {}
85
- end
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
- if !container
122
+ unless container
121
123
  # return "table not continued" unless row is empty
122
- if @context.current.empty?
123
- return true
124
- else
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!("Template name not found")
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
- unless value.empty? && name.is_a?(Numeric) # it was just empty line otherwise
37
- res << Var.new(name.to_s, value)
38
- end
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]+:\/\/ | # external link
12
+ \[[a-z]+:// | # external link
12
13
  <nowiki[^>]*> | # nowiki
13
14
  <ref[^>]*> | # reference
14
15
  <math> | # math
15
16
  < # HTML tag
16
- )/x
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 "match single bracket but not double"
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
- if q
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
@@ -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.kind_of?(Tree::Template) && _eq(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, "Descendants should define :replace")
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, t| m === name.downcase}
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 |name, what|
112
- replace(name, what)
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 = self.find(base) if base.is_a?(String)
167
+ base = find(base) if base.is_a?(String)
167
168
 
168
- Class.new(base, &definition).tap{|cls|
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?(other)
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
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+
2
3
  module Infoboxer
3
4
  module Tree
4
5
  # Represents entire document.
@@ -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
@@ -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
- :location, :alignment, :link,
28
- :alt
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
- caption.children.map(&call(to_tree: level+2)).join
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
- #@!attribute [r] link
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
- #@!attribute [r] url
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(/[^\/]+$/, link.gsub(' ', '_'))
26
+ page.url.sub(%r{[^/]+$}, link.tr(' ', '_'))
27
27
  end
28
28
 
29
29
  protected
30
30
 
31
31
  def page
32
- page = lookup_parents(MediaWiki::Page).first or
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("MediaWiki client not set")
36
+ page.client or fail('MediaWiki client not set')
38
37
  end
39
-
40
38
  end
41
39
  end
42
40
  end