infoboxer 0.1.0
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 +7 -0
- data/.dokaz +1 -0
- data/.yardopts +1 -0
- data/LICENSE.txt +22 -0
- data/Parsing.md +33 -0
- data/README.md +115 -0
- data/examples/output/.gitkeep +0 -0
- data/examples/pages/argentina.wiki +808 -0
- data/examples/to_text.rb +8 -0
- data/examples/tree.rb +8 -0
- data/infoboxer.gemspec +43 -0
- data/lib/infoboxer.rb +196 -0
- data/lib/infoboxer/core_ext.rb +10 -0
- data/lib/infoboxer/definitions/en.wikipedia.org.rb +355 -0
- data/lib/infoboxer/media_wiki.rb +162 -0
- data/lib/infoboxer/media_wiki/page.rb +38 -0
- data/lib/infoboxer/media_wiki/traits.rb +60 -0
- data/lib/infoboxer/navigation.rb +84 -0
- data/lib/infoboxer/navigation/lookup.rb +216 -0
- data/lib/infoboxer/navigation/sections.rb +179 -0
- data/lib/infoboxer/navigation/selector.rb +59 -0
- data/lib/infoboxer/navigation/shortcuts.rb +165 -0
- data/lib/infoboxer/parser.rb +71 -0
- data/lib/infoboxer/parser/context.rb +165 -0
- data/lib/infoboxer/parser/html.rb +58 -0
- data/lib/infoboxer/parser/image.rb +59 -0
- data/lib/infoboxer/parser/inline.rb +142 -0
- data/lib/infoboxer/parser/paragraphs.rb +66 -0
- data/lib/infoboxer/parser/table.rb +132 -0
- data/lib/infoboxer/parser/template.rb +47 -0
- data/lib/infoboxer/parser/util.rb +73 -0
- data/lib/infoboxer/templates.rb +10 -0
- data/lib/infoboxer/templates/base.rb +82 -0
- data/lib/infoboxer/templates/set.rb +72 -0
- data/lib/infoboxer/tree.rb +70 -0
- data/lib/infoboxer/tree/compound.rb +81 -0
- data/lib/infoboxer/tree/document.rb +11 -0
- data/lib/infoboxer/tree/html.rb +76 -0
- data/lib/infoboxer/tree/image.rb +53 -0
- data/lib/infoboxer/tree/inline.rb +39 -0
- data/lib/infoboxer/tree/list.rb +160 -0
- data/lib/infoboxer/tree/node.rb +181 -0
- data/lib/infoboxer/tree/nodes.rb +185 -0
- data/lib/infoboxer/tree/paragraphs.rb +122 -0
- data/lib/infoboxer/tree/ref.rb +34 -0
- data/lib/infoboxer/tree/table.rb +89 -0
- data/lib/infoboxer/tree/template.rb +82 -0
- data/lib/infoboxer/tree/text.rb +60 -0
- data/lib/infoboxer/tree/wikilink.rb +83 -0
- data/lib/infoboxer/version.rb +4 -0
- data/profile/out/.gitkeep +0 -0
- data/profile/pages/argentina.txt +808 -0
- data/profile/pages/canada.wiki +544 -0
- data/profile/pages/ukraine.wiki +1006 -0
- data/profile/pages/usa.wiki +843 -0
- data/regression/pages/canada.wiki +544 -0
- data/regression/pages/chiang_mai.wiki +2615 -0
- data/regression/pages/south_america.wiki +640 -0
- data/regression/pages/ukraine.wiki +1006 -0
- data/regression/pages/usa.wiki +843 -0
- metadata +272 -0
data/examples/to_text.rb
ADDED
data/examples/tree.rb
ADDED
data/infoboxer.gemspec
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require './lib/infoboxer/version'
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'infoboxer'
|
5
|
+
s.version = Infoboxer::VERSION
|
6
|
+
s.authors = ['Victor Shepelev']
|
7
|
+
s.email = 'zverok.offline@gmail.com'
|
8
|
+
s.homepage = 'https://github.com/zverok/infoboxer'
|
9
|
+
|
10
|
+
s.summary = 'MediaWiki client and parser, targeting information extraction.'
|
11
|
+
s.description = <<-EOF
|
12
|
+
Infoboxer is library targeting use of Wikipedia (or any other
|
13
|
+
MediaWiki-based wiki) as a rich powerful data source.
|
14
|
+
EOF
|
15
|
+
s.licenses = ['MIT']
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split($RS).reject do |file|
|
18
|
+
file =~ /^(?:
|
19
|
+
spec\/.*
|
20
|
+
|Gemfile
|
21
|
+
|Rakefile
|
22
|
+
|\.rspec
|
23
|
+
|\.gitignore
|
24
|
+
|\.rubocop.yml
|
25
|
+
|\.travis.yml
|
26
|
+
)$/x
|
27
|
+
end
|
28
|
+
s.require_paths = ["lib"]
|
29
|
+
|
30
|
+
s.add_dependency 'htmlentities'
|
31
|
+
s.add_dependency 'procme'
|
32
|
+
s.add_dependency 'rest-client'
|
33
|
+
s.add_dependency 'addressable'
|
34
|
+
s.add_dependency 'terminal-table'
|
35
|
+
s.add_dependency 'backports'
|
36
|
+
|
37
|
+
s.add_development_dependency 'rake'
|
38
|
+
s.add_development_dependency 'rspec', '~> 3'
|
39
|
+
s.add_development_dependency 'rspec-its', '~> 1'
|
40
|
+
s.add_development_dependency 'ruby-prof'
|
41
|
+
s.add_development_dependency 'vcr'
|
42
|
+
s.add_development_dependency 'webmock'
|
43
|
+
end
|
data/lib/infoboxer.rb
ADDED
@@ -0,0 +1,196 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'procme'
|
3
|
+
require 'backports/2.1.0/array/to_h'
|
4
|
+
#require 'backports/2.2.0/object/itself' Y U NO???
|
5
|
+
|
6
|
+
# Main client module for entire infoboxer functionality. If you're lucky,
|
7
|
+
# there's no other classes/modules you need to instantiate or call
|
8
|
+
# directly. You just do:
|
9
|
+
#
|
10
|
+
# ```ruby
|
11
|
+
# Infoboxer.wp.get('List of radio telescopes')
|
12
|
+
# # or
|
13
|
+
# Infoboxer.wikiquote.get('Vonnegut')
|
14
|
+
# ```
|
15
|
+
# ...and have fully navigable Wiki information.
|
16
|
+
#
|
17
|
+
# Please read [wiki](http://github.com/molybdenum-99/infoboxer/wiki)
|
18
|
+
# for extensive [showcases](https://github.com/molybdenum-99/infoboxer/wiki/Showcase)
|
19
|
+
# and usage recommendations.
|
20
|
+
#
|
21
|
+
# Here's main components list, which also can serve as a TOC for
|
22
|
+
# Infoboxer's functionality (we suggest to read their docs in this order):
|
23
|
+
#
|
24
|
+
# * {Tree} -- nodes, of which Wikipedia AST is consisting; you'll be
|
25
|
+
# interested in basic {Tree::Node} functionality, as well as node
|
26
|
+
# classes list (which is useful for navigation);
|
27
|
+
# * {Navigation} -- how to navigate the tree you have, basic way
|
28
|
+
# (children, parents, siblings) and hi-level shortcuts way (like
|
29
|
+
# all unnumbered list items in second level-3 section);
|
30
|
+
# * {Templates} -- the most advanced data extraction from wikipedia definitely
|
31
|
+
# needs your undestanding of this (rather complicated) topic.
|
32
|
+
#
|
33
|
+
# You also may be interested in (though may be never need to use them directly):
|
34
|
+
#
|
35
|
+
# * {MediaWiki} client class;
|
36
|
+
# * {Parser} -- which, you know, parses.
|
37
|
+
#
|
38
|
+
module Infoboxer
|
39
|
+
private # hiding constants from YARD
|
40
|
+
|
41
|
+
WIKIA_API_URL = 'http://%s.wikia.com/api.php'
|
42
|
+
|
43
|
+
WIKIMEDIA_PROJECTS = {
|
44
|
+
wikipedia: 'wikipedia.org',
|
45
|
+
wikivoyage: 'wikivoyage.org',
|
46
|
+
wikiquote: 'wikiquote.org',
|
47
|
+
wiktionary: 'wiktionary.org',
|
48
|
+
wikibooks: 'wikibooks.org',
|
49
|
+
wikinews: 'wikinews.org',
|
50
|
+
wikiversity: 'wikiversity.org',
|
51
|
+
wikisource: 'wikisource.org'
|
52
|
+
}
|
53
|
+
|
54
|
+
WIKIMEDIA_COMMONS = {
|
55
|
+
commons: 'commons.wikimedia.org',
|
56
|
+
species: 'species.wikimedia.org',
|
57
|
+
}
|
58
|
+
|
59
|
+
class << self
|
60
|
+
|
61
|
+
# Default method for creating MediaWiki API client.
|
62
|
+
#
|
63
|
+
# @param api_url should be URL of api.php for your MediaWiki
|
64
|
+
# @param options list of options.
|
65
|
+
# The only recognized option for now, though, is
|
66
|
+
# * `:user_agent` (also aliased as `:ua`) -- custom User-Agent header.
|
67
|
+
# @return [MediaWiki] an instance of API client, which you can
|
68
|
+
# further use like this:
|
69
|
+
#
|
70
|
+
# ```ruby
|
71
|
+
# Infoboxer.wiki('some_url').get('Some page title')
|
72
|
+
# ```
|
73
|
+
def wiki(api_url, options = {})
|
74
|
+
MediaWiki.new(api_url, options || {})
|
75
|
+
end
|
76
|
+
|
77
|
+
# @!method wikipedia(lang = 'en', options = {})
|
78
|
+
# Shortcut for creating Wikipedia client.
|
79
|
+
#
|
80
|
+
# @param lang two-character code for language version
|
81
|
+
# @param options (see #wiki for list of options)
|
82
|
+
# @return [MediaWiki]
|
83
|
+
|
84
|
+
# @!method commons(options = {})
|
85
|
+
# Shortcut for creating [WikiMedia Commons](https://commons.wikimedia.org/) client.
|
86
|
+
#
|
87
|
+
# @param options (see #wiki for list of options)
|
88
|
+
# @return [MediaWiki]
|
89
|
+
|
90
|
+
# @!method wikibooks(lang = 'en', options = {})
|
91
|
+
# Shortcut for creating [Wikibooks](https://en.wikibooks.org/) client.
|
92
|
+
# See {wikipedia} for params explanation.
|
93
|
+
# @return [MediaWiki]
|
94
|
+
|
95
|
+
# @!method wikiquote(lang = 'en', options = {})
|
96
|
+
# Shortcut for creating [Wikiquote](https://en.wikiquote.org/) client.
|
97
|
+
# See {wikipedia} for params explanation.
|
98
|
+
# @return [MediaWiki]
|
99
|
+
|
100
|
+
# @!method wikiversity(lang = 'en', options = {})
|
101
|
+
# Shortcut for creating [Wikiversity](https://en.wikiversity.org/) client.
|
102
|
+
# See {wikipedia} for params explanation.
|
103
|
+
# @return [MediaWiki]
|
104
|
+
|
105
|
+
# @!method wikisource(lang = 'en', options = {})
|
106
|
+
# Shortcut for creating [Wikisource](https://en.wikisource.org/) client.
|
107
|
+
# See {wikipedia} for params explanation.
|
108
|
+
# @return [MediaWiki]
|
109
|
+
|
110
|
+
# @!method wikivoyage(lang = 'en', options = {})
|
111
|
+
# Shortcut for creating [Wikivoyage](http://wikivoyage.org) client.
|
112
|
+
# See {wikipedia} for params explanation.
|
113
|
+
# @return [MediaWiki]
|
114
|
+
|
115
|
+
# @!method wikinews(lang = 'en', options = {})
|
116
|
+
# Shortcut for creating [Wikinews](https://en.wikinews.org/) client.
|
117
|
+
# See {wikipedia} for params explanation.
|
118
|
+
# @return [MediaWiki]
|
119
|
+
|
120
|
+
# @!method species(options = {})
|
121
|
+
# Shortcut for creating [Wikispecies](https://species.wikimedia.org/) client.
|
122
|
+
#
|
123
|
+
# @param options (see #wiki for list of options)
|
124
|
+
# @return [MediaWiki]
|
125
|
+
|
126
|
+
# @!method wiktionary(lang = 'en', options = {})
|
127
|
+
# Shortcut for creating [Wiktionary](https://en.wiktionary.org/) client.
|
128
|
+
# See {wikipedia} for params explanation.
|
129
|
+
# @return [MediaWiki]
|
130
|
+
|
131
|
+
WIKIMEDIA_PROJECTS.each do |name, domain|
|
132
|
+
define_method name do |lang = 'en', options = {}|
|
133
|
+
if lang.is_a?(Hash)
|
134
|
+
lang, options = 'en', lang
|
135
|
+
end
|
136
|
+
|
137
|
+
wiki("http://#{lang}.#{domain}/w/api.php", options)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
alias_method :wp, :wikipedia
|
142
|
+
|
143
|
+
WIKIMEDIA_COMMONS.each do |name, domain|
|
144
|
+
define_method name do |options = {}|
|
145
|
+
wiki("http://#{domain}/w/api.php", options)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
# Performs request to wikia.com wikis.
|
150
|
+
#
|
151
|
+
# @overload wikia(*domains)
|
152
|
+
# @param *domains list of domains to merge, like this:
|
153
|
+
#
|
154
|
+
# ```ruby
|
155
|
+
# Infoboxer.wikia('tardis') # looks at tardis.wikia.com
|
156
|
+
# Infoboxer.wikia('tardis', 'ru') # looks in Russian version, ru.tardis.wikia.com
|
157
|
+
# ```
|
158
|
+
# If you are surprised by "reversing" list of subdomains, think of
|
159
|
+
# it as of chain of refinements (looking in "tardis" wiki, its "ru"
|
160
|
+
# version, specifically).
|
161
|
+
#
|
162
|
+
# @overload wikia(*domains, options)
|
163
|
+
# @param *domains same as above
|
164
|
+
# @param options just last of params, if it is hash
|
165
|
+
# (see {wiki} for list of options)
|
166
|
+
#
|
167
|
+
# @return [MediaWiki]
|
168
|
+
def wikia(*domains)
|
169
|
+
options = domains.last.is_a?(Hash) ? domains.pop : {}
|
170
|
+
wiki(WIKIA_API_URL % domains.reverse.join('.'), options)
|
171
|
+
end
|
172
|
+
|
173
|
+
# Sets user agent string globally. Default user agent is
|
174
|
+
# {MediaWiki::UA}.
|
175
|
+
#
|
176
|
+
# User agent can also be rewriten as an option to {wiki} method (and
|
177
|
+
# its shortcuts like {wikipedia}), or by using {MediaWiki#initialize}
|
178
|
+
# explicitly.
|
179
|
+
#
|
180
|
+
def user_agent=(ua)
|
181
|
+
MediaWiki.user_agent = ua
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
require_relative 'infoboxer/version'
|
187
|
+
require_relative 'infoboxer/core_ext'
|
188
|
+
|
189
|
+
require_relative 'infoboxer/tree'
|
190
|
+
require_relative 'infoboxer/parser'
|
191
|
+
require_relative 'infoboxer/navigation'
|
192
|
+
require_relative 'infoboxer/templates'
|
193
|
+
|
194
|
+
require_relative 'infoboxer/media_wiki'
|
195
|
+
|
196
|
+
require_relative 'infoboxer/definitions/en.wikipedia.org'
|
@@ -0,0 +1,355 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Infoboxer
|
3
|
+
MediaWiki::Traits.for('en.wikipedia.org') do
|
4
|
+
templates do
|
5
|
+
# https://en.wikipedia.org/wiki/Category:Wikipedia_character-substitution_templates
|
6
|
+
# ---------------------------------------------------------------------------------
|
7
|
+
# Extracted semi-automatically
|
8
|
+
# TODO: fully automatical extraction
|
9
|
+
literal(
|
10
|
+
'&',
|
11
|
+
';',
|
12
|
+
'=',
|
13
|
+
'?',
|
14
|
+
'—',
|
15
|
+
'1/2',
|
16
|
+
'1/3',
|
17
|
+
'1/4',
|
18
|
+
'2/3',
|
19
|
+
'3/4',
|
20
|
+
)
|
21
|
+
replace(
|
22
|
+
'!!' => '||',
|
23
|
+
'!(' => '[',
|
24
|
+
'!((' => '[[',
|
25
|
+
'!-' => '|-',
|
26
|
+
'!:' => ':',
|
27
|
+
'&' => '&',
|
28
|
+
"'" => " '",
|
29
|
+
"''" => '″',
|
30
|
+
"'s" => "'s",
|
31
|
+
'(' => '{',
|
32
|
+
'((' => '{{',
|
33
|
+
'(((' => '{{{',
|
34
|
+
')' => '}',
|
35
|
+
')!' => ']',
|
36
|
+
'))' => '}}',
|
37
|
+
'))!' => ']]',
|
38
|
+
')))' => '}}}',
|
39
|
+
'Asterisk' => '*',
|
40
|
+
'Colon' => ':',
|
41
|
+
'Em dash' => '—',
|
42
|
+
'Gc' => "†",
|
43
|
+
'Ibeam' => 'I',
|
44
|
+
'Long dash' => ' ——— ',
|
45
|
+
'Nbhyph' => '‑',
|
46
|
+
'Number sign' => '#',
|
47
|
+
'Shy' => '', # soft hyphen
|
48
|
+
'Single space' => "' ",
|
49
|
+
'Space single' => " '",
|
50
|
+
'Spaced ndash' => ' – ',
|
51
|
+
'Square bracket close' => ']',
|
52
|
+
'Square bracket open' => '[',
|
53
|
+
'Zwsp' => '',
|
54
|
+
'\\' => ' / ',
|
55
|
+
'`' => "'",
|
56
|
+
'·' => ' · ',
|
57
|
+
'‘' => '‘',
|
58
|
+
'•' => ' • ',
|
59
|
+
)
|
60
|
+
|
61
|
+
# https://en.wikipedia.org/wiki/Category:Line-handling_templates
|
62
|
+
# ------------------------------------------------------------------
|
63
|
+
replace(
|
64
|
+
'-' => "\n",
|
65
|
+
'Break' => "\n", # FIXME: in fact, break has optional parameter "how many breaks"
|
66
|
+
'Crlf' => "\n", # FIXME: in fact, alias for break, should have DSL syntax for it!
|
67
|
+
'Crlf2' => "\n",
|
68
|
+
|
69
|
+
)
|
70
|
+
show(
|
71
|
+
'Allow wrap',
|
72
|
+
'Nowrap',
|
73
|
+
'j', 'nobr', 'nobreak', # aliases for Nowrap
|
74
|
+
'nowraplinks',
|
75
|
+
)
|
76
|
+
# inflow_template('Normalwraplink') # TODO: tricky
|
77
|
+
|
78
|
+
# https://en.wikipedia.org/wiki/Category:List_formatting_and_function_templates
|
79
|
+
# -----------------------------------------------------------------------------
|
80
|
+
# NB: it's enough for most cases to have all list-representing templates
|
81
|
+
# just navigable inside and rendered as space-separated list of entries
|
82
|
+
show(
|
83
|
+
'Br separated entries',
|
84
|
+
'Bulleted list',
|
85
|
+
'Collapsible list',
|
86
|
+
'Comma separated entries',
|
87
|
+
'Hlist',
|
88
|
+
'Flatlist',
|
89
|
+
'Flowlist',
|
90
|
+
'Pagelist',
|
91
|
+
'Ordered list',
|
92
|
+
'Plainlist',
|
93
|
+
'Space separated entries',
|
94
|
+
'Toolbar',
|
95
|
+
)
|
96
|
+
|
97
|
+
# https://en.wikipedia.org/wiki/Category:Wikipedia_XHTML_tag-replacing_templates
|
98
|
+
# ------------------------------------------------------------------------------
|
99
|
+
|
100
|
+
show(
|
101
|
+
# Font size
|
102
|
+
'Small',
|
103
|
+
'Smaller',
|
104
|
+
'Midsize',
|
105
|
+
'Larger',
|
106
|
+
'Big',
|
107
|
+
'Large',
|
108
|
+
'Huge',
|
109
|
+
|
110
|
+
# Align
|
111
|
+
'left',
|
112
|
+
'Center',
|
113
|
+
'Right',
|
114
|
+
|
115
|
+
# Simple style
|
116
|
+
'Em',
|
117
|
+
'Kbd',
|
118
|
+
'Var',
|
119
|
+
'Varserif',
|
120
|
+
'Samp',
|
121
|
+
'Strikethrough',
|
122
|
+
'Strong',
|
123
|
+
'Sub',
|
124
|
+
'Sup',
|
125
|
+
'Underline',
|
126
|
+
|
127
|
+
# FIXME: should do something wiser
|
128
|
+
'Pre',
|
129
|
+
'Pre2',
|
130
|
+
'Code'
|
131
|
+
)
|
132
|
+
|
133
|
+
template 'Abbr' do
|
134
|
+
def children
|
135
|
+
fetch('1')
|
136
|
+
end
|
137
|
+
end
|
138
|
+
# TODO: has aliases: {{Define}}, {{Explain}}, {{Tooltip}}
|
139
|
+
|
140
|
+
template 'Align' do
|
141
|
+
def children
|
142
|
+
fetch('2')
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
template 'Dfn' do
|
147
|
+
def children
|
148
|
+
fetch('1')
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
template 'Resize' do
|
153
|
+
def children
|
154
|
+
unnamed_variables.count < 2 ? fetch('1') : fetch('2')
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
template 'Font' do
|
159
|
+
def children
|
160
|
+
res = fetch('text')
|
161
|
+
res.empty? ? fetch('1') : res
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
# https://en.wikipedia.org/wiki/Category:Text_color_templates
|
166
|
+
show(
|
167
|
+
'white', 'silver (color)', 'gray', 'black', 'pink', 'red', 'darkred',
|
168
|
+
'maroon', 'brown', 'orange (color)', 'gold (color)', 'yellow', 'olive',
|
169
|
+
'lime', 'green', 'aqua (color)', 'cyan', 'teal', 'blue', 'navy (color)',
|
170
|
+
'purple', 'fuchsia', 'magenta'
|
171
|
+
)
|
172
|
+
|
173
|
+
# Some most popular templates, without categorical splitting
|
174
|
+
# https://en.wikipedia.org/wiki/Wikipedia:Database_reports/Templates_transcluded_on_the_most_pages
|
175
|
+
# ------------------------------------------------------------------------------------------------
|
176
|
+
# Currently scanned by eyes up to 250-th line, which is used in 130549 articles, according to the
|
177
|
+
# page - which, though, is dramatically outdated.
|
178
|
+
|
179
|
+
template 'Stub', match: /-stub$/ do
|
180
|
+
def stub?
|
181
|
+
true
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
template 'Infobox', match: /^Infobox/i do
|
186
|
+
def infobox?
|
187
|
+
true
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
template 'Coord' do
|
192
|
+
def model
|
193
|
+
@model ||= begin
|
194
|
+
npos = lookup_children(text: /^N|S$/).first.index rescue nil
|
195
|
+
case npos
|
196
|
+
when 1
|
197
|
+
:decimal
|
198
|
+
when 2
|
199
|
+
:min
|
200
|
+
when 3
|
201
|
+
:sec
|
202
|
+
else
|
203
|
+
:decimal_sign
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
def lat
|
209
|
+
case model
|
210
|
+
when :decimal
|
211
|
+
'%s°%s′%s' % fetch('1', '2').map(&:text)
|
212
|
+
when :decimal_sign
|
213
|
+
fetch('1').text
|
214
|
+
when :min
|
215
|
+
'%s°%s′%s' % fetch('1', '2', '3').map(&:text)
|
216
|
+
when :sec
|
217
|
+
'%s°%s′%s″%s' % fetch('1', '2', '3', '4').map(&:text)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
def lng
|
222
|
+
case model
|
223
|
+
when :decimal, :decimal_sign
|
224
|
+
fetch('1').text
|
225
|
+
when :min
|
226
|
+
'%s°%s′%s' % fetch('1', '2', '3').map(&:text)
|
227
|
+
when :sec
|
228
|
+
'%s°%s′%s″%s' % fetch('1', '2', '3', '4').map(&:text)
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
template 'Convert' do
|
234
|
+
def value1
|
235
|
+
fetch('1').text
|
236
|
+
end
|
237
|
+
|
238
|
+
ALLOW_BETWEEN = ['-;', '–',
|
239
|
+
'and', '&', 'and(-)', ', and',
|
240
|
+
'or', ', or',
|
241
|
+
'to', 'to(-)', 'to about',
|
242
|
+
'+/-', '±', '+',
|
243
|
+
'by', 'x', '×', 'x',
|
244
|
+
]
|
245
|
+
|
246
|
+
def between
|
247
|
+
ALLOW_BETWEEN.include?(fetch('2').text) ? fetch('2').text : nil
|
248
|
+
end
|
249
|
+
|
250
|
+
def value2
|
251
|
+
between ? fetch('3').text : nil
|
252
|
+
end
|
253
|
+
|
254
|
+
def measure_from
|
255
|
+
between ? fetch('4').text : fetch('2').text
|
256
|
+
end
|
257
|
+
|
258
|
+
def measure_to
|
259
|
+
between ? fetch('5').text : fetch('3').text
|
260
|
+
end
|
261
|
+
|
262
|
+
def text
|
263
|
+
[value1, between, value2, measure_from].compact.join(' ')
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
template 'Age' do
|
268
|
+
def from
|
269
|
+
fetch_date('1', '2', '3')
|
270
|
+
end
|
271
|
+
|
272
|
+
def to
|
273
|
+
fetch_date('4', '5', '6') || Date.today
|
274
|
+
end
|
275
|
+
|
276
|
+
def value
|
277
|
+
(to - from).to_i / 365 # FIXME: obviously
|
278
|
+
end
|
279
|
+
|
280
|
+
def text
|
281
|
+
"#{value} years"
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
template 'Birth date and age' do
|
286
|
+
def date
|
287
|
+
fetch_date('1', '2', '3')
|
288
|
+
end
|
289
|
+
|
290
|
+
def text
|
291
|
+
date.to_s
|
292
|
+
end
|
293
|
+
end
|
294
|
+
# TODO: aliased as bda
|
295
|
+
|
296
|
+
template 'Birth date' do
|
297
|
+
def date
|
298
|
+
fetch_date('1', '2', '3')
|
299
|
+
end
|
300
|
+
|
301
|
+
def text
|
302
|
+
date.to_s
|
303
|
+
end
|
304
|
+
end
|
305
|
+
# TODO: aliased as dob
|
306
|
+
|
307
|
+
template 'Time ago' do
|
308
|
+
def text
|
309
|
+
str = fetch('1').text
|
310
|
+
begin
|
311
|
+
date = Date.parse(str)
|
312
|
+
"#{(Date.today - date).to_i} days ago" # not trying complext time_distance_in_words formatting here
|
313
|
+
rescue ArgumentError
|
314
|
+
str
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
template 'Flagcountry' do # very popular instead of country name
|
320
|
+
def children
|
321
|
+
fetch('1')
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
template 'Flag' do # very popular instead of country name
|
326
|
+
def children
|
327
|
+
fetch('1')
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
show 'Plural'
|
332
|
+
|
333
|
+
template 'URL' do
|
334
|
+
def children
|
335
|
+
unnamed_variables.count > 1 ? fetch('2') : fetch('1')
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
# TODO: extremely popular:
|
340
|
+
# Str left - https://en.wikipedia.org/wiki/Category:String_manipulation_templates
|
341
|
+
# Rnd - https://en.wikipedia.org/wiki/Category:Mathematical_function_templates
|
342
|
+
|
343
|
+
# TODO: useful categories
|
344
|
+
# https://en.wikipedia.org/wiki/Category:Date_mathematics_templates
|
345
|
+
# https://en.wikipedia.org/wiki/Category:Mathematical_function_templates
|
346
|
+
# https://en.wikipedia.org/wiki/Category:Wikipedia_formatting_and_function_templates
|
347
|
+
# https://en.wikipedia.org/wiki/Category:Semantic_markup_templates
|
348
|
+
# https://en.wikipedia.org/wiki/Category:Quotation_templates
|
349
|
+
# https://en.wikipedia.org/wiki/Category:Typing-aid_templates
|
350
|
+
# https://en.wikipedia.org/wiki/Category:Inline_spacing_templates
|
351
|
+
# https://en.wikipedia.org/wiki/Category:Sorting_templates
|
352
|
+
# https://en.wikipedia.org/wiki/Wikipedia:Database_reports/Templates_transcluded_on_the_most_pages
|
353
|
+
end
|
354
|
+
end
|
355
|
+
end
|