infoboxer 0.3.0.pre → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 67b07bcee67c15aeb316e2eccf75e85a26cb43ae
4
- data.tar.gz: 91f3253151ff816a83b4ffb8f7937c878a5a3ed8
3
+ metadata.gz: be65bc91a5370bc24553e500754f413196caed76
4
+ data.tar.gz: d24dca5a13a64d563ddc473197a732a9f95884fd
5
5
  SHA512:
6
- metadata.gz: f7dd9aa6545853dbf827c1b0b7857b2b5654caf33dcbfcaf4c2194709379f7e73d0978776675fd6265cbf83d88a814332626945db1b45c9562e54a01fa486a55
7
- data.tar.gz: fa70f671da0d9acd7a0a131d8119a775c1ff762d7d2b640096f448678b7547477fd0fe93df74c438cd846fa550e33e530999c811bb4b0d4afe347bf058c3321b
6
+ metadata.gz: 661c06d6703db103035f61f55ebee5f0bc8a5f9ad182fcaf2a22be9f91063a9abd80bac1793fabae436b28bed274fcb7908219ba07453f46271a25d1cba0367a
7
+ data.tar.gz: 25029633e6516c30a7de21433db1903ab923af2c74082b3a3c9322b50b170cdb104652b95d261b3033a070629ee478a8b5510a7298fbef830d1445dfe56157d0
@@ -1 +1,16 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2017-06-23 13:52:16 +0300 using RuboCop version 0.49.1.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 1
10
+ Metrics/AbcSize:
11
+ Max: 29
12
+
13
+ # Offense count: 1
14
+ Metrics/PerceivedComplexity:
15
+ Max: 10
1
16
 
@@ -1,16 +1,5 @@
1
1
  # Infoboxer's change log
2
2
 
3
- ## 0.3.1.pre (2017-09-16)
4
-
5
- * Introduce interwiki links following (and proper handling of interwikis, in general);
6
- * Add `<gallery>` tag support;
7
- * Introduce `Navigation::Selector#===`;
8
- * Much more `Enumerable`'s methods supported by `Nodes`;
9
- * Lot of small simplifications, cleanups and bugfixes.
10
-
11
- TBH, it should be 0.4.0 or more, but it would be a shame to change versions so fast :) So, at least
12
- until it is `-pre`, let it be 0.3.1.
13
-
14
3
  ## 0.3.0 (2017-07-23)
15
4
 
16
5
  * Change logic of navigation through templates; now templates contents aren't hidden from global
@@ -72,8 +72,8 @@ module Infoboxer
72
72
  end
73
73
 
74
74
  # Includeable version of {Infoboxer.wiki}
75
- def wiki(api_url, **options)
76
- wikis[api_url] ||= MediaWiki.new(api_url, options)
75
+ def wiki(api_url, options = {})
76
+ wikis[api_url] ||= MediaWiki.new(api_url, options || {})
77
77
  end
78
78
 
79
79
  class << self
@@ -168,7 +168,7 @@ module Infoboxer
168
168
  end
169
169
 
170
170
  WIKIMEDIA_PROJECTS.each do |name, domain|
171
- define_method name do |lang = 'en', **options|
171
+ define_method name do |lang = 'en', options = {}|
172
172
  lang, options = 'en', lang if lang.is_a?(Hash)
173
173
 
174
174
  wiki("https://#{lang}.#{domain}/w/api.php", options)
@@ -178,7 +178,7 @@ module Infoboxer
178
178
  alias_method :wp, :wikipedia
179
179
 
180
180
  WIKIMEDIA_COMMONS.each do |name, domain|
181
- define_method name do |**options|
181
+ define_method name do |options = {}|
182
182
  wiki("https://#{domain}/w/api.php", options)
183
183
  end
184
184
  end
@@ -47,14 +47,15 @@ module Infoboxer
47
47
  # for it, as well as shortcuts for some well-known wikis, like
48
48
  # {Infoboxer.wikipedia}.
49
49
  #
50
- # @param api_base_url [String] URL of `api.php` file in your MediaWiki
50
+ # @param api_base_url URL of `api.php` file in your MediaWiki
51
51
  # installation. Typically, its `<domain>/w/api.php`, but can vary
52
52
  # in different wikis.
53
- # @param user_agent [String] (also aliased as `:ua`) Custom User-Agent header.
54
- def initialize(api_base_url, ua: nil, user_agent: ua)
53
+ # @param options Only one option is currently supported:
54
+ # * `:user_agent` (also aliased as `:ua`) -- custom User-Agent header.
55
+ def initialize(api_base_url, options = {})
55
56
  @api_base_url = Addressable::URI.parse(api_base_url)
56
- @client = MediaWiktory::Wikipedia::Api.new(api_base_url, user_agent: user_agent(user_agent))
57
- @traits = Traits.get(@api_base_url.host, siteinfo)
57
+ @client = MediaWiktory::Wikipedia::Api.new(api_base_url, user_agent: user_agent(options))
58
+ @traits = Traits.get(@api_base_url.host, namespaces: extract_namespaces)
58
59
  end
59
60
 
60
61
  # Receive "raw" data from Wikipedia (without parsing or wrapping in
@@ -122,9 +123,7 @@ module Infoboxer
122
123
  # and obtain meaningful results instead of `NoMethodError` or
123
124
  # `SomethingNotFound`.
124
125
  #
125
- def get(*titles, prop: [], interwiki: nil)
126
- return interwikis(interwiki).get(*titles, prop: prop) if interwiki
127
-
126
+ def get(*titles, prop: [])
128
127
  pages = get_h(*titles, prop: prop).values.compact
129
128
  titles.count == 1 ? pages.first : Tree::Nodes[*pages]
130
129
  end
@@ -252,26 +251,17 @@ module Infoboxer
252
251
  [namespace, titl].join(':')
253
252
  end
254
253
 
255
- def user_agent(custom)
256
- custom || self.class.user_agent || UA
257
- end
258
-
259
- def siteinfo
260
- @siteinfo ||= @client.query.meta(:siteinfo).prop(:namespaces, :namespacealiases, :interwikimap).response.to_h
254
+ def user_agent(options)
255
+ options[:user_agent] || options[:ua] || self.class.user_agent || UA
261
256
  end
262
257
 
263
- def interwikis(prefix)
264
- @interwikis ||= Hash.new { |h, pre|
265
- interwiki = siteinfo['interwikimap'].detect { |iw| iw['prefix'] == prefix } or
266
- fail ArgumentError, "Undefined interwiki: #{prefix}"
267
-
268
- # FIXME: fragile, but what can we do?..
269
- m = interwiki['url'].match(%r{^(.+)/wiki/\$1$}) or
270
- fail ArgumentError, "Interwiki #{interwiki} seems not to be a MediaWiki instance"
271
- h[pre] = self.class.new("#{m[1]}/w/api.php") # TODO: copy useragent
272
- }
273
-
274
- @interwikis[prefix]
258
+ def extract_namespaces
259
+ siteinfo = @client.query.meta(:siteinfo).prop(:namespaces, :namespacealiases).response
260
+ siteinfo['namespaces'].map do |_, namespace|
261
+ aliases =
262
+ siteinfo['namespacealiases'].select { |a| a['id'] == namespace['id'] }.map { |a| a['*'] }
263
+ namespace.merge('aliases' => aliases)
264
+ end
275
265
  end
276
266
  end
277
267
  end
@@ -34,8 +34,9 @@ module Infoboxer
34
34
  end
35
35
 
36
36
  # @private
37
- def get(domain, site_info = {})
38
- (Traits.domains[domain] || Traits).new(site_info)
37
+ def get(domain, options = {})
38
+ cls = Traits.domains[domain]
39
+ cls ? cls.new(options) : Traits.new(options)
39
40
  end
40
41
 
41
42
  # @private
@@ -67,27 +68,18 @@ module Infoboxer
67
68
  alias_method :default, :new
68
69
  end
69
70
 
70
- def initialize(site_info = {})
71
- @site_info = site_info
72
- end
73
-
74
- def namespace?(prefix)
75
- known_namespaces.include?(prefix)
76
- end
77
-
78
- def interwiki?(prefix)
79
- known_interwikis.key?(prefix)
80
- end
81
-
82
- # @private
83
- def file_namespace
84
- @file_namespace ||= ns_aliases('File')
71
+ def initialize(options = {})
72
+ @options = options
73
+ @file_namespace =
74
+ [DEFAULTS[:file_namespace], namespace_aliases(options, 'File')]
75
+ .flatten.compact.uniq
76
+ @category_namespace =
77
+ [DEFAULTS[:category_namespace], namespace_aliases(options, 'Category')]
78
+ .flatten.compact.uniq
85
79
  end
86
80
 
87
81
  # @private
88
- def category_namespace
89
- @category_namespace ||= ns_aliases('Category')
90
- end
82
+ attr_reader :file_namespace, :category_namespace
91
83
 
92
84
  # @private
93
85
  def templates
@@ -96,54 +88,16 @@ module Infoboxer
96
88
 
97
89
  private
98
90
 
99
- def known_namespaces
100
- @known_namespaces ||=
101
- if @site_info.empty?
102
- STANDARD_NAMESPACES
103
- else
104
- (@site_info['namespaces'].values + @site_info['namespacealiases']).map { |n| n['*'] }
105
- end
106
- end
107
-
108
- def known_interwikis
109
- @known_interwikis ||=
110
- if @site_info.empty?
111
- {}
112
- else
113
- @site_info['interwikimap'].map { |iw| [iw['prefix'], iw] }.to_h
114
- end
115
- end
116
-
117
- def ns_aliases(base)
118
- return [base] if @site_info.empty?
119
- main = @site_info['namespaces'].values.detect { |n| n['canonical'] == base }
120
- [base, main['*']] +
121
- @site_info['namespacealiases']
122
- .select { |a| a['id'] == main['id'] }.flat_map { |n| n['*'] }
123
- .compact.uniq
91
+ def namespace_aliases(options, canonical)
92
+ namespace = (options[:namespaces] || []).detect { |v| v['canonical'] == canonical }
93
+ return nil unless namespace
94
+ [namespace['*'], *namespace['aliases']]
124
95
  end
125
96
 
126
- # See https://www.mediawiki.org/wiki/Help:Namespaces#Standard_namespaces
127
- STANDARD_NAMESPACES = [
128
- 'Media', # Direct linking to media files.
129
- 'Special', # Special (non-editable) pages.
130
- '', # (Main)
131
- 'Talk', # Article discussion.
132
- 'User', #
133
- 'User talk', #
134
- 'Project', # Meta-discussions related to the operation and development of the wiki.
135
- 'Project talk', #
136
- 'File', # Metadata for images, videos, sound files and other media.
137
- 'File talk', #
138
- 'MediaWiki', # System messages and other important content.
139
- 'MediaWiki talk', #
140
- 'Template', # Templates: blocks of text or wikicode that are intended to be transcluded.
141
- 'Template talk', #
142
- 'Help', # Help files, instructions and "how-to" guides.
143
- 'Help talk', #
144
- 'Category', # Categories: dynamic lists of other pages.
145
- 'Category talk', #
146
- ].freeze
97
+ DEFAULTS = {
98
+ file_namespace: 'File',
99
+ category_namespace: 'Category'
100
+ }.freeze
147
101
  end
148
102
  end
149
103
  end
@@ -98,13 +98,9 @@ module Infoboxer
98
98
  # Selects matching nodes from current node's siblings, which
99
99
  # are above current node in parents children list.
100
100
 
101
- # @!method lookup_prev_sibling(*selectors, &block)
102
- # Selects first matching nodes from current node's siblings, which
103
- # are above current node in parents children list.
104
-
105
101
  # Underscored version of {#matches?}
106
102
  def _matches?(selector)
107
- selector === self
103
+ selector.matches?(self)
108
104
  end
109
105
 
110
106
  # Underscored version of {#lookup}
@@ -140,11 +136,6 @@ module Infoboxer
140
136
  prev_siblings._find(selector)
141
137
  end
142
138
 
143
- # Underscored version of {#lookup_prev_sibling}
144
- def _lookup_prev_sibling(selector)
145
- prev_siblings.reverse.detect { |n| selector === n }
146
- end
147
-
148
139
  # Underscored version of {#lookup_next_siblings}
149
140
  def _lookup_next_siblings(selector)
150
141
  next_siblings._find(selector)
@@ -155,7 +146,6 @@ module Infoboxer
155
146
  lookup lookup_children lookup_parents
156
147
  lookup_siblings
157
148
  lookup_next_siblings lookup_prev_siblings
158
- lookup_prev_sibling
159
149
  ]
160
150
  .map { |sym| [sym, :"_#{sym}"] }
161
151
  .each do |sym, underscored|
@@ -123,25 +123,21 @@ module Infoboxer
123
123
  #
124
124
  # @return {Tree::Nodes<Section>}
125
125
  def in_sections
126
- return parent.in_sections unless parent.is_a?(Tree::Document)
127
- return @in_sections if @in_sections
126
+ main_node = parent.is_a?(Tree::Document) ? self : lookup_parents[-2]
128
127
 
129
128
  heading =
130
- if is_a?(Tree::Heading)
131
- lookup_prev_sibling(Tree::Heading, level: level - 1)
129
+ if main_node.is_a?(Tree::Heading)
130
+ main_node.lookup_prev_siblings(Tree::Heading, level: main_node.level - 1).last
132
131
  else
133
- lookup_prev_sibling(Tree::Heading)
132
+ main_node.lookup_prev_siblings(Tree::Heading).last
134
133
  end
135
- unless heading
136
- @in_sections = Tree::Nodes[]
137
- return @in_sections
138
- end
134
+ return Tree::Nodes[] unless heading
139
135
 
140
136
  body = heading.next_siblings
141
137
  .take_while { |n| !n.is_a?(Tree::Heading) || n.level < heading.level }
142
138
 
143
139
  section = Section.new(heading, body)
144
- @in_sections = Tree::Nodes[section, *heading.in_sections]
140
+ Tree::Nodes[section, *heading.in_sections]
145
141
  end
146
142
  end
147
143
 
@@ -24,8 +24,8 @@ module Infoboxer
24
24
  "#<Selector(#{@arg.map(&:to_s).join(', ')})>"
25
25
  end
26
26
 
27
- def ===(other)
28
- @arg.all? { |a| arg_matches?(a, other) }
27
+ def matches?(node)
28
+ @arg.all? { |a| arg_matches?(a, node) }
29
29
  end
30
30
 
31
31
  private
@@ -44,8 +44,8 @@ module Infoboxer
44
44
  check.call(node)
45
45
  when Hash
46
46
  check.all? { |attr, value|
47
- node.respond_to?(attr) && value_matches?(value, node.send(attr)) ||
48
- node.params.key?(attr) && value_matches?(value, node.params[attr])
47
+ node.respond_to?(attr) && value === node.send(attr) ||
48
+ node.params.key?(attr) && value === node.params[attr]
49
49
  }
50
50
  when Symbol
51
51
  node.respond_to?(check) && node.send(check)
@@ -53,14 +53,6 @@ module Infoboxer
53
53
  check === node
54
54
  end
55
55
  end
56
-
57
- def value_matches?(matcher, value)
58
- if matcher.is_a?(String) && value.is_a?(String)
59
- matcher.casecmp(value).zero?
60
- else
61
- matcher === value
62
- end
63
- end
64
56
  end
65
57
  end
66
58
  end
@@ -83,7 +83,7 @@ module Infoboxer
83
83
 
84
84
  private
85
85
 
86
- def inline_formatting(match) # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/AbcSize
86
+ def inline_formatting(match)
87
87
  case match
88
88
  when "'''''"
89
89
  BoldItalic.new(short_inline(/'''''/))
@@ -109,8 +109,6 @@ module Infoboxer
109
109
  reference(Regexp.last_match(1))
110
110
  when /<math>/
111
111
  math
112
- when /<gallery([^>]*)>/
113
- gallery(Regexp.last_match(1))
114
112
  when '<'
115
113
  html || Text.new(match) # it was not HTML, just accidental <
116
114
  else
@@ -128,18 +126,8 @@ module Infoboxer
128
126
  caption = inline(/\]\]/)
129
127
  @context.pop_eol_sign
130
128
  end
131
- name, namespace = link.split(':', 2).reverse
132
- lnk, params =
133
- if @context.traits.namespace?(namespace)
134
- [link, {namespace: namespace}]
135
- elsif @context.traits.interwiki?(namespace)
136
- [name, {interwiki: namespace}]
137
- else
138
- [link, {}]
139
- end
140
129
 
141
- puts @context.rest if lnk.nil?
142
- Wikilink.new(lnk, caption, **params)
130
+ Wikilink.new(link, caption)
143
131
  end
144
132
 
145
133
  # http://en.wikipedia.org/wiki/Help:Link#External_links
@@ -171,34 +159,6 @@ module Infoboxer
171
159
  Text.new(@context.scan_continued_until(%r{</nowiki>}))
172
160
  end
173
161
  end
174
-
175
- def gallery(tag_rest)
176
- params = parse_params(tag_rest)
177
- images = []
178
- guarded_loop do
179
- @context.next! if @context.eol?
180
- path = @context.scan_until(%r{</gallery>|\||$})
181
- attrs = @context.matched == '|' ? gallery_image_attrs : {}
182
- unless path.empty?
183
- images << Tree::Image.new(path.sub(/^#{re.file_namespace}/, ''), attrs)
184
- end
185
- break if @context.matched == '</gallery>'
186
- end
187
- Gallery.new(images, params)
188
- end
189
-
190
- def gallery_image_attrs
191
- nodes = []
192
-
193
- guarded_loop do
194
- nodes << short_inline(%r{\||</gallery>})
195
- break if @context.eol? || @context.matched?(%r{</gallery>})
196
- end
197
-
198
- nodes.map(&method(:image_attr))
199
- .inject(&:merge)
200
- .reject { |_k, v| v.nil? || v.empty? }
201
- end
202
162
  end
203
163
 
204
164
  require_relative 'image'
@@ -14,7 +14,7 @@ module Infoboxer
14
14
 
15
15
  @context.next!
16
16
  end
17
- nodes
17
+ nodes.flow_templates
18
18
  end
19
19
 
20
20
  private
@@ -29,8 +29,8 @@ module Infoboxer
29
29
 
30
30
  guarded_loop do
31
31
  @context.next! while @context.eol?
32
- if @context.check(/\s*([^=}|<]+)\s*=\s*/)
33
- name = @context.scan(/\s*([^=]+)/).strip
32
+ if @context.check(/\s*([^ =}|<]+)\s*=\s*/)
33
+ name = @context.scan(/\s*([^ =]+)/).strip
34
34
  @context.skip(/\s*=\s*/)
35
35
  else
36
36
  name = num
@@ -52,7 +52,7 @@ module Infoboxer
52
52
  end
53
53
 
54
54
  def sanitize_value(nodes)
55
- nodes.pop if (nodes.last.is_a?(Pre) || nodes.last.is_a?(Text)) && nodes.last.text =~ /^\s*$/ # FIXME: dirty!
55
+ nodes.pop if nodes.last.is_a?(Pre) && nodes.last.text =~ /^\s*$/ # FIXME: dirty!
56
56
  nodes
57
57
  end
58
58
  end
@@ -12,7 +12,6 @@ module Infoboxer
12
12
  \[[a-z]+:// | # external link
13
13
  <nowiki[^>]*> | # nowiki
14
14
  <ref[^>]*> | # reference
15
- <gallery[^>]*>| # gallery
16
15
  <math> | # math
17
16
  < # HTML tag
18
17
  ))x
@@ -63,7 +63,7 @@ module Infoboxer
63
63
  require_relative 'tree/nodes'
64
64
 
65
65
  %w[text compound inline
66
- image gallery html paragraphs list template table ref math
66
+ image html paragraphs list template table ref math
67
67
  document].each do |type|
68
68
  require_relative "tree/#{type}"
69
69
  end
@@ -4,7 +4,7 @@ module Infoboxer
4
4
  module Tree
5
5
  # Base class for all nodes with children.
6
6
  class Compound < Node
7
- def initialize(children = Nodes.new, **params)
7
+ def initialize(children = Nodes.new, params = {})
8
8
  super(params)
9
9
  @children = Nodes[*children]
10
10
  @children.each { |c| c.parent = self }
@@ -7,8 +7,8 @@ module Infoboxer
7
7
  # See [Wikipedia Tutorial](https://en.wikipedia.org/wiki/Wikipedia:Extended_image_syntax)
8
8
  # for explanation of attributes.
9
9
  class Image < Node
10
- def initialize(path, caption: nil, **params)
11
- @caption = caption
10
+ def initialize(path, params = {})
11
+ @caption = params.delete(:caption)
12
12
  super({path: path}.merge(params))
13
13
  end
14
14
 
@@ -17,8 +17,8 @@ module Infoboxer
17
17
 
18
18
  # Base class for internal/external links,
19
19
  class Link < Compound
20
- def initialize(link, label = nil, **attr)
21
- super(label || Nodes.new([Text.new(link)]), link: link, **attr)
20
+ def initialize(link, label = nil)
21
+ super(label || Nodes.new([Text.new(link)]), link: link)
22
22
  end
23
23
 
24
24
  # @!attribute [r] link
@@ -15,7 +15,7 @@ module Infoboxer
15
15
  # * {Tree::Nodes#follow} for extracting multiple links at once;
16
16
  # * {MediaWiki#get} for basic information on page extraction.
17
17
  def follow
18
- client.get(link, interwiki: interwiki)
18
+ client.get(link)
19
19
  end
20
20
 
21
21
  # Human-readable page URL
@@ -28,9 +28,6 @@ module Infoboxer
28
28
 
29
29
  protected
30
30
 
31
- # redefined in {Wikilink}
32
- def interwiki; end
33
-
34
31
  def page
35
32
  lookup_parents(MediaWiki::Page).first or fail('Not in a page from real source')
36
33
  end
@@ -4,6 +4,9 @@ module Infoboxer
4
4
  #
5
5
  # See also: https://en.wikipedia.org/wiki/Help:Displaying_a_formula
6
6
  class Math < Text
7
+ def text
8
+ "<math>#{super}</math>"
9
+ end
7
10
  end
8
11
  end
9
12
  end
@@ -11,7 +11,7 @@ module Infoboxer
11
11
  # you will receive it from tree and use for navigations.
12
12
  #
13
13
  class Node
14
- def initialize(**params)
14
+ def initialize(params = {})
15
15
  @params = params
16
16
  end
17
17
 
@@ -154,7 +154,7 @@ module Infoboxer
154
154
  end
155
155
 
156
156
  def show_params(prms = nil)
157
- (prms || params).reject { |_, v| v.nil? }.map { |k, v| "#{k}: #{v.inspect}" }.join(', ')
157
+ (prms || params).map { |k, v| "#{k}: #{v.inspect}" }.join(', ')
158
158
  end
159
159
 
160
160
  def indent(level)
@@ -38,19 +38,10 @@ module Infoboxer
38
38
  # @!method compact
39
39
  # Just like Array#compact, but returns Nodes
40
40
 
41
- # @!method grep(pattern)
42
- # Just like Array#grep, but returns Nodes
43
-
44
- # @!method grep_v(pattern)
45
- # Just like Array#grep_v, but returns Nodes
46
-
47
41
  # @!method -(other)
48
42
  # Just like Array#-, but returns Nodes
49
43
 
50
- # @!method +(other)
51
- # Just like Array#+, but returns Nodes
52
-
53
- %i[select reject sort_by flatten compact grep grep_v - +].each do |sym|
44
+ %i[select reject sort_by flatten compact -].each do |sym|
54
45
  define_method(sym) do |*args, &block|
55
46
  Nodes[*super(*args, &block)]
56
47
  end
@@ -84,21 +75,6 @@ module Infoboxer
84
75
  end
85
76
  end
86
77
 
87
- # Just like Array#flat_map, but returns Nodes, **if** all map results are Node
88
- def flat_map
89
- res = super
90
- if res.all? { |n| n.is_a?(Node) || n.is_a?(Nodes) }
91
- Nodes[*res]
92
- else
93
- res
94
- end
95
- end
96
-
97
- # Just like Array#group, but returns hash with `{<grouping variable> => Nodes}`
98
- def group_by
99
- super.map { |title, group| [title, Nodes[*group]] }.to_h
100
- end
101
-
102
78
  # @!method prev_siblings
103
79
  # Previous siblings (flat list) of all nodes inside.
104
80
 
@@ -163,14 +139,12 @@ module Infoboxer
163
139
  # @return [Nodes<MediaWiki::Page>] It is still `Nodes`, so you
164
140
  # still can process them uniformely.
165
141
  def follow
166
- links = grep(Linkable)
142
+ links = select { |n| n.respond_to?(:link) }.map(&:link)
167
143
  return Nodes[] if links.empty?
168
144
  page = first.lookup_parents(MediaWiki::Page).first or
169
145
  fail('Not in a page from real source')
170
146
  page.client or fail('MediaWiki client not set')
171
- pages = links.group_by(&:interwiki)
172
- .flat_map { |iw, ls| page.client.get(*ls.map(&:link), interwiki: iw) }
173
- pages.count == 1 ? pages.first : Nodes[*pages]
147
+ page.client.get(*links)
174
148
  end
175
149
 
176
150
  # @private
@@ -199,9 +173,7 @@ module Infoboxer
199
173
  # @private
200
174
  # Internal, used by {Parser}
201
175
  def flow_templates
202
- # TODO: will it be better?..
203
- # make_nodes(map { |n| n.is_a?(Paragraph) ? n.to_templates? : n })
204
- self
176
+ make_nodes(map { |n| n.is_a?(Paragraph) ? n.to_templates? : n })
205
177
  end
206
178
 
207
179
  private
@@ -22,10 +22,6 @@ module Infoboxer
22
22
  false
23
23
  end
24
24
 
25
- def named?
26
- name !~ /^\d+$/
27
- end
28
-
29
25
  protected
30
26
 
31
27
  def descr
@@ -143,7 +139,7 @@ module Infoboxer
143
139
  #
144
140
  # @return [Nodes<Var>]
145
141
  def unnamed_variables
146
- variables.reject(&:named?)
142
+ variables.find(name: /^\d+$/)
147
143
  end
148
144
 
149
145
  # Fetches template variable(s) by name(s) or patterns.
@@ -246,7 +242,7 @@ module Infoboxer
246
242
  def extract_params(vars)
247
243
  vars
248
244
  .select { |v| v.children.count == 1 && v.children.first.is_a?(Text) }
249
- .map { |v| [v.name.to_sym, v.children.first.raw_text] }.to_h
245
+ .map { |v| [v.name, v.children.first.raw_text] }.to_h
250
246
  end
251
247
 
252
248
  def inspect_variables(depth)
@@ -15,7 +15,7 @@ module Infoboxer
15
15
  # Text fragment without decodint of HTML entities.
16
16
  attr_accessor :raw_text
17
17
 
18
- def initialize(text, **params)
18
+ def initialize(text, params = {})
19
19
  super(params)
20
20
  @raw_text = text
21
21
  end
@@ -12,23 +12,14 @@ module Infoboxer
12
12
  # Note, that Wikilink is {Linkable}, so you can {Linkable#follow #follow}
13
13
  # it to obtain linked pages.
14
14
  class Wikilink < Link
15
- def initialize(link, label = nil, namespace: nil, interwiki: nil)
16
- super(link, label, namespace: namespace, interwiki: interwiki)
17
- @namespace = namespace || ''
18
- @interwiki = interwiki
19
- parse_name!
15
+ def initialize(*)
16
+ super
17
+ parse_link!
20
18
  end
21
19
 
22
20
  # "Clean" wikilink name, for ex., `Cities` for `[Category:Cities]`
23
21
  attr_reader :name
24
22
 
25
- # Interwiki identifier. For example, `[[wikt:Argentina]]`
26
- # will have `"Argentina"` as its {#name} and `"wikt"` (wiktionary) as an
27
- # interwiki. TODO: how to use it.
28
- #
29
- # See [Wikipedia docs](https://en.wikipedia.org/wiki/Help:Interwiki_linking) for details.
30
- attr_reader :interwiki
31
-
32
23
  # Wikilink namespace, `Category` for `[Category:Cities]`, empty
33
24
  # string (not `nil`!) for just `[Cities]`
34
25
  attr_reader :namespace
@@ -55,8 +46,10 @@ module Infoboxer
55
46
 
56
47
  private
57
48
 
58
- def parse_name!
59
- @name = namespace.empty? ? link : link.sub(/^#{namespace}:/, '')
49
+ def parse_link!
50
+ @name, @namespace = link.split(':', 2).reverse
51
+ @namespace ||= ''
52
+
60
53
  @name, @anchor = @name.split('#', 2)
61
54
  @anchor ||= ''
62
55
 
@@ -4,6 +4,5 @@ module Infoboxer
4
4
  MAJOR = 0
5
5
  MINOR = 3
6
6
  PATCH = 0
7
- PRE = 'pre'.freeze # set to `nil` for normal releases
8
- VERSION = [MAJOR, MINOR, PATCH, PRE].compact.join('.')
7
+ VERSION = [MAJOR, MINOR, PATCH].join('.')
9
8
  end
@@ -36,7 +36,7 @@ module Infoboxer
36
36
  attrs[attr.to_sym] = process_value(value)
37
37
  end
38
38
  res = op == '//' ? {op: :lookup} : {}
39
- res[:type] = process_type(type) unless type.empty?
39
+ res[:type] = type.gsub(/(?:^|_)([a-z])/, &:upcase).tr('_', '').to_sym unless type.empty?
40
40
  res.merge(attrs) # TODO: raise if empty selector
41
41
  end
42
42
 
@@ -51,15 +51,6 @@ module Infoboxer
51
51
  end
52
52
  end
53
53
 
54
- def process_type(type)
55
- type.gsub(/(?:^|_)([a-z])/, &:upcase).tr('_', '').to_sym
56
- .tap { |t| valid_type?(t) or fail(ParseError, "Unrecognized node type: #{type}") }
57
- end
58
-
59
- def valid_type?(t)
60
- t == :Section || Infoboxer::Tree.const_defined?(t)
61
- end
62
-
63
54
  def unexpected(scanner, expected)
64
55
  place = scanner.eos? ? 'end of pattern' : scanner.rest.inspect
65
56
  fail ParseError, "Unexpected #{place}, expecting #{expected}"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: infoboxer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0.pre
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Shepelev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-09-16 00:00:00.000000000 Z
11
+ date: 2017-07-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: htmlentities
@@ -117,7 +117,6 @@ files:
117
117
  - lib/infoboxer/tree.rb
118
118
  - lib/infoboxer/tree/compound.rb
119
119
  - lib/infoboxer/tree/document.rb
120
- - lib/infoboxer/tree/gallery.rb
121
120
  - lib/infoboxer/tree/html.rb
122
121
  - lib/infoboxer/tree/image.rb
123
122
  - lib/infoboxer/tree/inline.rb
@@ -166,9 +165,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
166
165
  version: 2.1.0
167
166
  required_rubygems_version: !ruby/object:Gem::Requirement
168
167
  requirements:
169
- - - ">"
168
+ - - ">="
170
169
  - !ruby/object:Gem::Version
171
- version: 1.3.1
170
+ version: '0'
172
171
  requirements: []
173
172
  rubyforge_project:
174
173
  rubygems_version: 2.6.10
@@ -1,12 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Infoboxer
4
- module Tree
5
- # Represents gallery of images (contents of `<gallery>` special tag).
6
- #
7
- # See [Wikipedia Tutorial](https://en.wikipedia.org/wiki/Help:Gallery_tag)
8
- # for explanation of attributes.
9
- class Gallery < Compound
10
- end
11
- end
12
- end