wolf 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.
- data/.gemspec +21 -0
- data/CHANGELOG.rdoc +2 -0
- data/LICENSE.txt +22 -0
- data/README.rdoc +182 -0
- data/Rakefile +35 -0
- data/bin/wolf +4 -0
- data/deps.rip +2 -0
- data/lib/wolf.rb +62 -0
- data/lib/wolf/mouth.rb +85 -0
- data/lib/wolf/stomach.rb +57 -0
- data/lib/wolf/version.rb +3 -0
- metadata +111 -0
data/.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require 'rubygems' unless Object.const_defined?(:Gem)
|
3
|
+
require File.dirname(__FILE__) + "/lib/wolf/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "wolf"
|
7
|
+
s.version = Wolf::VERSION
|
8
|
+
s.authors = ["Gabriel Horner"]
|
9
|
+
s.email = "gabriel.horner@gmail.com"
|
10
|
+
s.homepage = "http://github.com/cldwalker/wolf"
|
11
|
+
s.summary = "Devour wolfram's computational knowledge in your shell"
|
12
|
+
s.description = "Devour computational knowledge on the commandline with wolframalpha."
|
13
|
+
s.required_rubygems_version = ">= 1.3.6"
|
14
|
+
s.rubyforge_project = 'tagaholic'
|
15
|
+
s.executables = ['wolf']
|
16
|
+
s.add_dependency 'hirb', '>= 0.3.6'
|
17
|
+
s.add_dependency 'wolfram', '>= 0.1.1'
|
18
|
+
s.files = Dir.glob(%w[{lib,test}/**/*.rb bin/* [A-Z]*.{txt,rdoc} ext/**/*.{rb,c} **/deps.rip]) + %w{Rakefile .gemspec}
|
19
|
+
s.extra_rdoc_files = ["README.rdoc", "LICENSE.txt"]
|
20
|
+
s.license = 'MIT'
|
21
|
+
end
|
data/CHANGELOG.rdoc
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT LICENSE
|
2
|
+
|
3
|
+
Copyright (c) 2011 Gabriel Horner
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,182 @@
|
|
1
|
+
== Description
|
2
|
+
Devour computational knowledge on the commandline with {wolframalpha}[http://wolframalpha.com].
|
3
|
+
|
4
|
+
== Install
|
5
|
+
|
6
|
+
To install this gem:
|
7
|
+
|
8
|
+
gem install wolf
|
9
|
+
|
10
|
+
== Setup
|
11
|
+
|
12
|
+
Get a free Wolfram Appid (api key) by {creating an account
|
13
|
+
here}[http://developer.wolframalpha.com/portal/apisignup.html] and
|
14
|
+
then clicking on the 'Get an APPID' button.
|
15
|
+
|
16
|
+
Once you have your own appid, set it in your shell, preferably in your ~/.zshrc or ~/.bashrc:
|
17
|
+
|
18
|
+
export WOLFRAM_APPID='YOURKEY'
|
19
|
+
|
20
|
+
Or you can set your appid in your ~/.wolfrc:
|
21
|
+
|
22
|
+
Wolfram.appid = "YOURKEY"
|
23
|
+
|
24
|
+
== Usage
|
25
|
+
|
26
|
+
wolf displays results to wolfram queries as tables:
|
27
|
+
|
28
|
+
# Calculate distance and travel time between places
|
29
|
+
$ wolf boston to new york
|
30
|
+
Distance
|
31
|
+
+-------------+
|
32
|
+
| 184.3 miles |
|
33
|
+
+-------------+
|
34
|
+
|
35
|
+
Direct travel times
|
36
|
+
+---------------------+-------------------------+
|
37
|
+
| aircraft (550 mph) | 20 minutes |
|
38
|
+
| sound | 14 minutes 30 seconds |
|
39
|
+
| light in fiber | 1.39 ms (milliseconds) |
|
40
|
+
| light in vacuum | 0.99 ms (milliseconds) |
|
41
|
+
+---------------------+-------------------------+
|
42
|
+
...
|
43
|
+
|
44
|
+
# Solve an equation
|
45
|
+
ru wolf 'x^3 - sinx = e^-x'
|
46
|
+
+--------------------+---------------------------+
|
47
|
+
| Input | x^3-sin(x) = e^(-x) |
|
48
|
+
| Numerical solution | x ~~ 1.068531813164789... |
|
49
|
+
+--------------------+---------------------------+
|
50
|
+
|
51
|
+
# Compare stocks
|
52
|
+
$ wolf goog, apple, microsoft
|
53
|
+
Latest trades
|
54
|
+
+------+---------------+--------+----------------+--------------------+
|
55
|
+
| GOOG | $600.30 (GOOG | NASDAQ | 4:02:42 pm EST | 5 hrs 41 mins ago) |
|
56
|
+
| AAPL | $339.30 (AAPL | NASDAQ | 4:21:45 pm EST | 5 hrs 22 mins ago) |
|
57
|
+
| MSFT | $27.73 (MSFT | NASDAQ | 4:00:00 pm EST | 5 hrs 43 mins ago) |
|
58
|
+
+------+---------------+--------+----------------+--------------------+
|
59
|
+
|
60
|
+
Fundamentals and financials
|
61
|
+
+--------------------------+----------------+----------------+----------------+
|
62
|
+
| | Google | Apple | Microsoft |
|
63
|
+
+--------------------------+----------------+----------------+----------------+
|
64
|
+
| market cap | $192 billion | $312.6 billion | $233 billion |
|
65
|
+
| revenue | $27.55 billion | $76.28 billion | $66.69 billion |
|
66
|
+
| employees | 23331 | 49400 | 89000 |
|
67
|
+
...
|
68
|
+
|
69
|
+
# Display local weather info
|
70
|
+
$ wolf weather
|
71
|
+
Latest recorded weather for boston, massachusetts
|
72
|
+
+-------------------+----------------------------+
|
73
|
+
| temperature | 34 °F (wind chill: 25 °F) |
|
74
|
+
| conditions | cloudy |
|
75
|
+
| relative humidity | 47% (dew point: 16 °F) |
|
76
|
+
| wind speed | 12 mph |
|
77
|
+
+-------------------+----------------------------+
|
78
|
+
...
|
79
|
+
|
80
|
+
In some cases wolf displays information more concisely than the website itself. Compare {the
|
81
|
+
website}[http://www.wolframalpha.com/input/?i=pi] to:
|
82
|
+
|
83
|
+
$ wolf pi
|
84
|
+
+-----------------------------+---------------------------------------------------------------------------------------+
|
85
|
+
| Input | pi |
|
86
|
+
| Decimal approximation | 3.1415926535897932384626433832795028841971693993751058209749... |
|
87
|
+
| Property | pi is a transcendental number |
|
88
|
+
| Continued fraction | [3; 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2, 2, 2, 1, 84, 2, 1, 1, ...] |
|
89
|
+
| Alternative representations | pi = 180 ° |
|
90
|
+
| Series representations | pi = 4 sum_(k=0)^infinity(-1)^k/(2 k+1) |
|
91
|
+
| Integral representations | pi = 2 integral_0^infinity1/(t^2+1) dt |
|
92
|
+
+-----------------------------+---------------------------------------------------------------------------------------+
|
93
|
+
|
94
|
+
If you clicked on the previous link, you'll notice links to more information about the current result.
|
95
|
+
wolf makes this available via the menu option (-m):
|
96
|
+
|
97
|
+
$ wolf pi -m
|
98
|
+
|
99
|
+
+-----------------------------+---------------------------------------------------------------------------------------+
|
100
|
+
| Input | pi |
|
101
|
+
| Decimal approximation | 3.1415926535897932384626433832795028841971693993751058209749... |
|
102
|
+
| Property | pi is a transcendental number |
|
103
|
+
| Continued fraction | [3; 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2, 2, 2, 1, 84, 2, 1, 1, ...] |
|
104
|
+
| Alternative representations | pi = 180 ° |
|
105
|
+
| Series representations | pi = 4 sum_(k=0)^infinity(-1)^k/(2 k+1) |
|
106
|
+
| Integral representations | pi = 2 integral_0^infinity1/(t^2+1) dt |
|
107
|
+
+-----------------------------+---------------------------------------------------------------------------------------+
|
108
|
+
|
109
|
+
** LINKS **
|
110
|
+
+--------+-----------------------------+---------------+
|
111
|
+
| number | Section | Choice |
|
112
|
+
+--------+-----------------------------+---------------+
|
113
|
+
| 1 | Decimal approximation | More digits |
|
114
|
+
| 2 | Continued fraction | Fraction form |
|
115
|
+
| 3 | Continued fraction | More terms |
|
116
|
+
| 4 | Alternative representations | More |
|
117
|
+
| 5 | Series representations | More |
|
118
|
+
| 6 | Integral representations | More |
|
119
|
+
+--------+-----------------------------+---------------+
|
120
|
+
Choose one link to requery:
|
121
|
+
|
122
|
+
# User types '1'
|
123
|
+
Choose one link to requery: 1
|
124
|
+
|
125
|
+
# To get back
|
126
|
+
+-----------------------------+-------------------------------------------------------------------------------------------------------------------------+
|
127
|
+
| Input | pi |
|
128
|
+
| Decimal approximation | 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282... |
|
129
|
+
| Property | pi is a transcendental number |
|
130
|
+
| Continued fraction | [3; 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2, 2, 2, 1, 84, 2, 1, 1, ...] |
|
131
|
+
| Alternative representations | pi = 180 ° |
|
132
|
+
| Series representations | pi = 4 sum_(k=0)^infinity(-1)^k/(2 k+1) |
|
133
|
+
| Integral representations | pi = 2 integral_0^infinity1/(t^2+1) dt |
|
134
|
+
+-----------------------------+-------------------------------------------------------------------------------------------------------------------------+
|
135
|
+
|
136
|
+
wolf has more options you can explore with:
|
137
|
+
|
138
|
+
$ wolf -h
|
139
|
+
|
140
|
+
Some examples of options:
|
141
|
+
|
142
|
+
# Only display tables whose titles match the case insensitive regex
|
143
|
+
$ wolf .me -t=name
|
144
|
+
Name
|
145
|
+
+------------------+------------------------+
|
146
|
+
| full name | Republic of Montenegro |
|
147
|
+
| full native name | Republika Crna Gora |
|
148
|
+
| internet code | .me |
|
149
|
+
+------------------+------------------------+
|
150
|
+
|
151
|
+
# Print a query's xml response
|
152
|
+
$ wolf -x 4th monday in march
|
153
|
+
<queryresult success="true" error="false" numpods="9" datatypes="CalendarEvent,City" timedout=""
|
154
|
+
timing="1.985" parsetiming="0.559" parsetimedout="false" recalculate="" version="2.0">
|
155
|
+
...
|
156
|
+
|
157
|
+
# Load local xml file(s) to read in console
|
158
|
+
$ wolf -l fourth_monday.xml
|
159
|
+
Result
|
160
|
+
+------------------------+
|
161
|
+
| Monday, March 28, 2011 |
|
162
|
+
+------------------------+
|
163
|
+
...
|
164
|
+
|
165
|
+
# Append additional params to a query with --PARAM=VALUE
|
166
|
+
# Read API docs for available query params
|
167
|
+
$ wolf --format=html 50 euros
|
168
|
+
<queryresult success="true" error="false" numpods="4" datatypes="Quantity" timedout=""
|
169
|
+
timing="2.566" parsetiming="0.115" parsetimedout="false" recalculate="" version="2.0">
|
170
|
+
<pod title="Input interpretation" scanner="Identity" id="Input" position="100" error="false"
|
171
|
+
numsubpods="0">
|
172
|
+
<markup>
|
173
|
+
...
|
174
|
+
|
175
|
+
== Links
|
176
|
+
* {Many query examples}[http://www.wolframalpha.com/examples/]
|
177
|
+
* {API docs (pdf)}[https://products.wolframalpha.com/docs/WolframAlpha-API-Reference.pdf]
|
178
|
+
|
179
|
+
== Todo
|
180
|
+
* Tests!
|
181
|
+
* Better aliasing of commands
|
182
|
+
* option to tab delimit results for easy nix slicing + dicing
|
data/Rakefile
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
def gemspec
|
5
|
+
@gemspec ||= eval(File.read('.gemspec'), binding, '.gemspec')
|
6
|
+
end
|
7
|
+
|
8
|
+
desc "Build the gem"
|
9
|
+
task :gem=>:gemspec do
|
10
|
+
sh "gem build .gemspec"
|
11
|
+
FileUtils.mkdir_p 'pkg'
|
12
|
+
FileUtils.mv "#{gemspec.name}-#{gemspec.version}.gem", 'pkg'
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "Install the gem locally"
|
16
|
+
task :install => :gem do
|
17
|
+
sh %{gem install pkg/#{gemspec.name}-#{gemspec.version}}
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "Generate the gemspec"
|
21
|
+
task :generate do
|
22
|
+
puts gemspec.to_ruby
|
23
|
+
end
|
24
|
+
|
25
|
+
desc "Validate the gemspec"
|
26
|
+
task :gemspec do
|
27
|
+
gemspec.validate
|
28
|
+
end
|
29
|
+
|
30
|
+
desc 'Run tests'
|
31
|
+
task :test do |t|
|
32
|
+
sh 'bacon -q -Ilib -I. test/*_test.rb'
|
33
|
+
end
|
34
|
+
|
35
|
+
task :default => :test
|
data/bin/wolf
ADDED
data/deps.rip
ADDED
data/lib/wolf.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'wolfram'
|
2
|
+
require 'hirb'
|
3
|
+
require 'wolf/stomach'
|
4
|
+
require 'wolf/mouth'
|
5
|
+
require 'wolf/version'
|
6
|
+
|
7
|
+
module Wolf
|
8
|
+
extend self
|
9
|
+
|
10
|
+
ALIASES = {}
|
11
|
+
OPTIONS = {:o => :open, :m => :menu, :x => :xml, :v => :verbose, :h => :help,
|
12
|
+
:a => :all, :l => :load, :t => :title, :V => :version}
|
13
|
+
HELP_OPTIONS = [
|
14
|
+
['-m, --menu', 'Choose from links in a menu and requery with one'],
|
15
|
+
['-a, --all', 'Print all tables and rows (uninteresting ones are hidden by default)'],
|
16
|
+
['-t, --title=TITLE', 'Only display tables whose title match TITLE'],
|
17
|
+
['-x, --xml', 'Print raw xml response instead of printing tables'],
|
18
|
+
['-l, --load', "Load one or more xml files to print"],
|
19
|
+
['-o, --open', 'Open query in the browser (mac only)'],
|
20
|
+
['-v, --verbose', 'Print additional information'],
|
21
|
+
['-V, --version', 'Print version'],
|
22
|
+
['-h, --help', 'Print help']
|
23
|
+
]
|
24
|
+
|
25
|
+
def devour(argv=ARGV)
|
26
|
+
options, fetch_options = parse_options(argv)
|
27
|
+
return puts(VERSION) if options[:version]
|
28
|
+
return puts(help) if argv.empty? || options[:help]
|
29
|
+
Mouth.eat(argv, options, fetch_options)
|
30
|
+
end
|
31
|
+
|
32
|
+
def help
|
33
|
+
name_max = HELP_OPTIONS.map {|e| e[0].length }.max
|
34
|
+
desc_max = HELP_OPTIONS.map {|e| e[1].length }.max
|
35
|
+
["Usage: wolf [OPTIONS] [ARGS]", "\nOptions:",
|
36
|
+
HELP_OPTIONS.map {|k,v| " %-*s %-*s" % [name_max, k, desc_max, v] },
|
37
|
+
"", "Append parameters to a query with options in the format --PARAM=VALUE i.e.",
|
38
|
+
" --reinterpret=true --format=html"]
|
39
|
+
end
|
40
|
+
|
41
|
+
def parse_options(argv)
|
42
|
+
options, fetch_options = {}, {}
|
43
|
+
arg = argv.find {|e| e[/^-/] }
|
44
|
+
index = argv.index(arg)
|
45
|
+
while arg =~ /^-/
|
46
|
+
if arg[/^--?(\w+)=(\S+)/]
|
47
|
+
opt = $1.to_sym
|
48
|
+
option?(opt) ? options[OPTIONS[opt] || opt] = $2 :
|
49
|
+
fetch_options[$1.to_sym] = $2
|
50
|
+
elsif (opt = arg[/^--?(\w+)/, 1]) && option?(opt.to_sym)
|
51
|
+
options[OPTIONS[opt.to_sym] || opt.to_sym] = true
|
52
|
+
end
|
53
|
+
argv.delete_at(index)
|
54
|
+
arg = argv[index]
|
55
|
+
end
|
56
|
+
[options, fetch_options]
|
57
|
+
end
|
58
|
+
|
59
|
+
def option?(opt)
|
60
|
+
OPTIONS.key?(opt) || OPTIONS.value?(opt)
|
61
|
+
end
|
62
|
+
end
|
data/lib/wolf/mouth.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
module Wolf
|
2
|
+
module Mouth
|
3
|
+
extend self
|
4
|
+
|
5
|
+
def eat(argv, options, fetch_options)
|
6
|
+
load_rc '~/.wolfrc'
|
7
|
+
options[:load] ? eat_at_home(argv, options) :
|
8
|
+
eat_out(build_query(argv), options, fetch_options)
|
9
|
+
end
|
10
|
+
|
11
|
+
def eat_at_home(files, options)
|
12
|
+
Hirb.enable
|
13
|
+
files.each {|file|
|
14
|
+
Mouth.swallow Wolfram::Result.new(File.read(@file = file)), options
|
15
|
+
}
|
16
|
+
rescue Errno::ENOENT
|
17
|
+
abort "Wolf Error: File '#{@file}' does not exist"
|
18
|
+
end
|
19
|
+
|
20
|
+
def load_rc(file)
|
21
|
+
load file if File.exists?(File.expand_path(file))
|
22
|
+
rescue StandardError, SyntaxError, LoadError => e
|
23
|
+
warn "Wolf Error while loading #{file}:\n"+
|
24
|
+
"#{e.class}: #{e.message}\n #{e.backtrace.join("\n ")}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def build_query(args)
|
28
|
+
cmd = args.shift
|
29
|
+
cmd_alias = ALIASES[cmd] || ALIASES[cmd.to_sym]
|
30
|
+
if cmd_alias.to_s.include?('%s')
|
31
|
+
cmd_alias % args
|
32
|
+
else
|
33
|
+
cmd = cmd_alias || cmd
|
34
|
+
([cmd] + args).join(' ')
|
35
|
+
end
|
36
|
+
rescue ArgumentError
|
37
|
+
abort "Wolf Error: Wrong number of arguments"
|
38
|
+
end
|
39
|
+
|
40
|
+
def eat_out(query, options, fetch_options)
|
41
|
+
# Can't display other formats except as raw xml
|
42
|
+
options[:xml] = true if fetch_options[:format] && !options.key?(:xml)
|
43
|
+
if options[:open]
|
44
|
+
open Wolfram.query(query,
|
45
|
+
:query_uri => "http://www.wolframalpha.com/input/").uri(:i => query)
|
46
|
+
elsif options[:xml]
|
47
|
+
puts Wolfram.fetch(query, fetch_options).xml
|
48
|
+
else
|
49
|
+
Hirb.enable
|
50
|
+
result = Wolfram.fetch(query, fetch_options)
|
51
|
+
swallow result, options
|
52
|
+
menu(result) if options[:menu]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def menu(result)
|
57
|
+
choices = []
|
58
|
+
result.pods.select {|e| e.states.size > 0 }.each {|e|
|
59
|
+
choices += e.states.map {|s| [e.title, s.name] } }
|
60
|
+
puts "\n** LINKS **"
|
61
|
+
choice = Hirb::Menu.render(choices, :change_fields => ['Section', 'Choice'],
|
62
|
+
:prompt =>"Choose one link to requery: ", :description => false,
|
63
|
+
:directions => false)[0]
|
64
|
+
if choice && (pod = result[choice[0]]) && state = pod.states.find {|e| e.name == choice[1] }
|
65
|
+
swallow state.refetch, options
|
66
|
+
else
|
67
|
+
abort "Wolf Error: Unable to find this link to requery it"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def swallow(result, options={})
|
72
|
+
if result.success
|
73
|
+
puts Stomach.digest(result, options)
|
74
|
+
else
|
75
|
+
warn "No results found"
|
76
|
+
end
|
77
|
+
puts "\nURI: #{result.uri}", "Fetched in #{result.timing}s",
|
78
|
+
"Found #{result.pods.size} pods" if options[:verbose]
|
79
|
+
end
|
80
|
+
|
81
|
+
def open(uri)
|
82
|
+
system('open', uri)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/lib/wolf/stomach.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
module Wolf
|
2
|
+
module Stomach
|
3
|
+
extend self
|
4
|
+
|
5
|
+
def digest(result, options)
|
6
|
+
body = ''
|
7
|
+
pods = options[:all] ? result.pods :
|
8
|
+
result.pods.reject {|e| e.title == 'Input interpretation' || e.plaintext == '' }
|
9
|
+
pods = pods.select {|e| e.title[/#{options[:title]}/i] } if options[:title]
|
10
|
+
# multiple 1-row tables i.e. math results
|
11
|
+
if pods.all? {|e| !e.plaintext.include?('|') }
|
12
|
+
body << render_table(pods.map {|e| [e.title, e.plaintext] })
|
13
|
+
# one one-row table i.e. word results
|
14
|
+
elsif pods.size == 1 && pod_rows(pods[0]).size == 1
|
15
|
+
body << pods[0].title.capitalize << "\n"
|
16
|
+
body << render_table(pod_rows(pods[0])[0])
|
17
|
+
else
|
18
|
+
pods.each do |pod|
|
19
|
+
body << pod.title.capitalize << "\n"
|
20
|
+
|
21
|
+
# Handle multiple tables divided by graphs i.e. when comparing stocks
|
22
|
+
if pod.plaintext.include?("\n\n") && pod.states.empty?
|
23
|
+
strip(pod.plaintext).split(/\n{2,}/).each {|text|
|
24
|
+
body << render_pod_rows(text_rows(text), text, options)
|
25
|
+
}
|
26
|
+
else
|
27
|
+
body << render_pod_rows(pod_rows(pod), strip(pod.plaintext), options)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
body
|
32
|
+
end
|
33
|
+
|
34
|
+
def render_pod_rows(rows, text, options)
|
35
|
+
# delete comments
|
36
|
+
rows.delete_if {|e| e.size == 1 } if rows.size > 1 && !options[:all]
|
37
|
+
headers = text[/^\s*\|/] ? rows.shift : false
|
38
|
+
render_table(rows, headers) << "\n\n"
|
39
|
+
end
|
40
|
+
|
41
|
+
def render_table(rows, headers=false)
|
42
|
+
Hirb::Helpers::AutoTable.render(rows, :description => false, :headers => headers)
|
43
|
+
end
|
44
|
+
|
45
|
+
def pod_rows(pod)
|
46
|
+
text_rows strip(pod.plaintext)
|
47
|
+
end
|
48
|
+
|
49
|
+
def strip(text)
|
50
|
+
text.sub(/\A(\s+\|){2,}/m, '').sub(/(\s+\|){2,}\s*\Z/, '').strip
|
51
|
+
end
|
52
|
+
|
53
|
+
def text_rows(text)
|
54
|
+
text.split(/\n+/).map {|e| e.split(/\s*\|\s+/) }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/wolf/version.rb
ADDED
metadata
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: wolf
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Gabriel Horner
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-02-01 00:00:00 -05:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: hirb
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 31
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
- 3
|
33
|
+
- 6
|
34
|
+
version: 0.3.6
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: wolfram
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 25
|
46
|
+
segments:
|
47
|
+
- 0
|
48
|
+
- 1
|
49
|
+
- 1
|
50
|
+
version: 0.1.1
|
51
|
+
type: :runtime
|
52
|
+
version_requirements: *id002
|
53
|
+
description: Devour computational knowledge on the commandline with wolframalpha.
|
54
|
+
email: gabriel.horner@gmail.com
|
55
|
+
executables:
|
56
|
+
- wolf
|
57
|
+
extensions: []
|
58
|
+
|
59
|
+
extra_rdoc_files:
|
60
|
+
- README.rdoc
|
61
|
+
- LICENSE.txt
|
62
|
+
files:
|
63
|
+
- lib/wolf/mouth.rb
|
64
|
+
- lib/wolf/stomach.rb
|
65
|
+
- lib/wolf/version.rb
|
66
|
+
- lib/wolf.rb
|
67
|
+
- bin/wolf
|
68
|
+
- LICENSE.txt
|
69
|
+
- CHANGELOG.rdoc
|
70
|
+
- README.rdoc
|
71
|
+
- deps.rip
|
72
|
+
- Rakefile
|
73
|
+
- .gemspec
|
74
|
+
has_rdoc: true
|
75
|
+
homepage: http://github.com/cldwalker/wolf
|
76
|
+
licenses:
|
77
|
+
- MIT
|
78
|
+
post_install_message:
|
79
|
+
rdoc_options: []
|
80
|
+
|
81
|
+
require_paths:
|
82
|
+
- lib
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
hash: 3
|
89
|
+
segments:
|
90
|
+
- 0
|
91
|
+
version: "0"
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
none: false
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
hash: 23
|
98
|
+
segments:
|
99
|
+
- 1
|
100
|
+
- 3
|
101
|
+
- 6
|
102
|
+
version: 1.3.6
|
103
|
+
requirements: []
|
104
|
+
|
105
|
+
rubyforge_project: tagaholic
|
106
|
+
rubygems_version: 1.3.7
|
107
|
+
signing_key:
|
108
|
+
specification_version: 3
|
109
|
+
summary: Devour wolfram's computational knowledge in your shell
|
110
|
+
test_files: []
|
111
|
+
|