teepee 0.6.0 → 0.7.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 +4 -4
- data/lib/teepee.rb +17 -529
- data/lib/teepee/actionable-commander.rb +89 -0
- data/lib/teepee/command-parser.rb +268 -0
- data/lib/teepee/commander.rb +320 -0
- data/lib/teepee/constants.rb +40 -0
- data/lib/teepee/errors.rb +41 -0
- data/lib/teepee/number-token.rb +68 -0
- data/lib/teepee/paragraph-parser.rb +80 -0
- data/lib/teepee/parser-node.rb +41 -0
- data/lib/teepee/parser.rb +77 -0
- data/lib/teepee/single-character-token.rb +72 -0
- data/lib/teepee/string-token.rb +123 -0
- data/lib/teepee/token.rb +53 -0
- data/lib/teepee/tokenizer.rb +75 -0
- metadata +15 -2
@@ -0,0 +1,89 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# -*- mode: Ruby -*-
|
3
|
+
|
4
|
+
# Copyright © 2013-2015, Christopher Mark Gore,
|
5
|
+
# Soli Deo Gloria,
|
6
|
+
# All rights reserved.
|
7
|
+
#
|
8
|
+
# 2317 South River Road, Saint Charles, Missouri 63303 USA.
|
9
|
+
# Web: http://cgore.com
|
10
|
+
# Email: cgore@cgore.com
|
11
|
+
#
|
12
|
+
# Redistribution and use in source and binary forms, with or without
|
13
|
+
# modification, are permitted provided that the following conditions are met:
|
14
|
+
#
|
15
|
+
# * Redistributions of source code must retain the above copyright
|
16
|
+
# notice, this list of conditions and the following disclaimer.
|
17
|
+
#
|
18
|
+
# * Redistributions in binary form must reproduce the above copyright
|
19
|
+
# notice, this list of conditions and the following disclaimer in the
|
20
|
+
# documentation and/or other materials provided with the distribution.
|
21
|
+
#
|
22
|
+
# * Neither the name of Christopher Mark Gore nor the names of other
|
23
|
+
# contributors may be used to endorse or promote products derived from
|
24
|
+
# this software without specific prior written permission.
|
25
|
+
#
|
26
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
27
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
28
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
29
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
30
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
31
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
32
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
33
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
34
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
35
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
36
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
37
|
+
|
38
|
+
require 'active_support/all'
|
39
|
+
require 'monkey-patch'
|
40
|
+
|
41
|
+
require 'teepee/constants'
|
42
|
+
require 'teepee/errors'
|
43
|
+
require 'teepee/commander'
|
44
|
+
|
45
|
+
include ERB::Util
|
46
|
+
|
47
|
+
module Teepee
|
48
|
+
class ActionableCommander < Commander
|
49
|
+
def initialize action_view, controller
|
50
|
+
@action_view = action_view
|
51
|
+
@controller = controller
|
52
|
+
end
|
53
|
+
|
54
|
+
def id_command_handler(id,
|
55
|
+
klass,
|
56
|
+
singular = klass.to_s.camelcase_to_snakecase,
|
57
|
+
plural = singular.pluralize,
|
58
|
+
partial = "#{plural}/inline",
|
59
|
+
view="")
|
60
|
+
if not id
|
61
|
+
command_error "#{singular}_id: error: no #{singular} ID specified"
|
62
|
+
elsif not id.to_s =~ /\A[0-9]+\z/
|
63
|
+
command_error "#{singular}_id: error: invalid #{singular} ID specified"
|
64
|
+
else
|
65
|
+
thing = klass.find Integer(id.to_s)
|
66
|
+
if thing
|
67
|
+
@@action_view.render partial: partial,
|
68
|
+
locals: {singular.to_sym => thing}
|
69
|
+
else
|
70
|
+
command_error "unknown #{singular} ID #{id.to_s}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def user user
|
76
|
+
if not user
|
77
|
+
command_error "user: error: no user specified"
|
78
|
+
else
|
79
|
+
the_user = User.smart_find user.to_s
|
80
|
+
if the_user
|
81
|
+
@action_view.render partial: 'users/name_link',
|
82
|
+
locals: {the_user: the_user}
|
83
|
+
else
|
84
|
+
command_error "unknown user #{user.to_s}"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,268 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# -*- mode: Ruby -*-
|
3
|
+
|
4
|
+
# Copyright © 2013-2015, Christopher Mark Gore,
|
5
|
+
# Soli Deo Gloria,
|
6
|
+
# All rights reserved.
|
7
|
+
#
|
8
|
+
# 2317 South River Road, Saint Charles, Missouri 63303 USA.
|
9
|
+
# Web: http://cgore.com
|
10
|
+
# Email: cgore@cgore.com
|
11
|
+
#
|
12
|
+
# Redistribution and use in source and binary forms, with or without
|
13
|
+
# modification, are permitted provided that the following conditions are met:
|
14
|
+
#
|
15
|
+
# * Redistributions of source code must retain the above copyright
|
16
|
+
# notice, this list of conditions and the following disclaimer.
|
17
|
+
#
|
18
|
+
# * Redistributions in binary form must reproduce the above copyright
|
19
|
+
# notice, this list of conditions and the following disclaimer in the
|
20
|
+
# documentation and/or other materials provided with the distribution.
|
21
|
+
#
|
22
|
+
# * Neither the name of Christopher Mark Gore nor the names of other
|
23
|
+
# contributors may be used to endorse or promote products derived from
|
24
|
+
# this software without specific prior written permission.
|
25
|
+
#
|
26
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
27
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
28
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
29
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
30
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
31
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
32
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
33
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
34
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
35
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
36
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
37
|
+
|
38
|
+
require 'active_support/all'
|
39
|
+
require 'monkey-patch'
|
40
|
+
|
41
|
+
require 'teepee/constants'
|
42
|
+
require 'teepee/errors'
|
43
|
+
require 'teepee/parser-node'
|
44
|
+
require 'teepee/commander'
|
45
|
+
require 'teepee/actionable-commander'
|
46
|
+
|
47
|
+
module Teepee
|
48
|
+
class CommandParser < ParserNode
|
49
|
+
attr_reader :command, :expressions
|
50
|
+
|
51
|
+
def initialize(command, expressions)
|
52
|
+
raise ArgumentError if not command.is_a? WordToken
|
53
|
+
@command = command
|
54
|
+
raise ArgumentError if not expressions.is_a? Array
|
55
|
+
expressions.each do |expression|
|
56
|
+
raise ArgumentError if not expression.kind_of? ParserNode
|
57
|
+
end
|
58
|
+
@expressions = expressions
|
59
|
+
end
|
60
|
+
|
61
|
+
def command_error(message)
|
62
|
+
%{<span style="color: red">[#{message}]</span>}
|
63
|
+
end
|
64
|
+
|
65
|
+
def to_html
|
66
|
+
case command.word
|
67
|
+
when "backslash", "bslash"
|
68
|
+
@@commander.backslash
|
69
|
+
when "left-brace",
|
70
|
+
"left_brace",
|
71
|
+
"leftbrace",
|
72
|
+
"lbrace",
|
73
|
+
"opening-brace",
|
74
|
+
"opening_brace",
|
75
|
+
"openingbrace",
|
76
|
+
"obrace"
|
77
|
+
@@commander.left_brace
|
78
|
+
when "right-brace",
|
79
|
+
"right_brace",
|
80
|
+
"rightbrace",
|
81
|
+
"rbrace",
|
82
|
+
"closing-brace",
|
83
|
+
"closing_brace",
|
84
|
+
"closingbrace",
|
85
|
+
"cbrace"
|
86
|
+
@@commander.right_brace
|
87
|
+
when "br", "newline"
|
88
|
+
@@commander.br
|
89
|
+
when "bold", "b", "textbf"
|
90
|
+
@@commander.b expressions
|
91
|
+
when "del",
|
92
|
+
"s",
|
93
|
+
"strike",
|
94
|
+
"strikethrough",
|
95
|
+
"strikeout"
|
96
|
+
@@commander.del expressions
|
97
|
+
when "i"
|
98
|
+
@@commander.i
|
99
|
+
when "italic",
|
100
|
+
"textit",
|
101
|
+
"it"
|
102
|
+
@@commander.it expressions
|
103
|
+
when "underline",
|
104
|
+
"u"
|
105
|
+
@@commander.u expressions
|
106
|
+
when "tt",
|
107
|
+
"texttt",
|
108
|
+
"teletype",
|
109
|
+
"typewriter"
|
110
|
+
@@commander.tt expressions
|
111
|
+
when "small"
|
112
|
+
@@commander.small expressions
|
113
|
+
when "big"
|
114
|
+
@@commander.big expressions
|
115
|
+
when "subscript",
|
116
|
+
"sub"
|
117
|
+
@@commander.sub expressions
|
118
|
+
when "superscript",
|
119
|
+
"sup"
|
120
|
+
@@commander.sup expressions
|
121
|
+
when "user",
|
122
|
+
"user-id",
|
123
|
+
"user_id"
|
124
|
+
@@commander.user first_word_token
|
125
|
+
when "link-id",
|
126
|
+
"link_id"
|
127
|
+
@@commander.link_id first_word_token
|
128
|
+
when "keyword-id",
|
129
|
+
"keyword_id"
|
130
|
+
@@commander.keyword_id first_word_token
|
131
|
+
when "tag-id",
|
132
|
+
"tag_id"
|
133
|
+
@@commander.tag_id first_word_token
|
134
|
+
when "forum-id",
|
135
|
+
"forum_id"
|
136
|
+
@@commander.forum_id first_word_token
|
137
|
+
when "folder-id",
|
138
|
+
"folder_id"
|
139
|
+
@@commander.folder_id first_word_token
|
140
|
+
when "bookmarks-folder-id",
|
141
|
+
"bookmarks_folder_id",
|
142
|
+
"bookmarks_folder-id",
|
143
|
+
"bookmarks-folder_id",
|
144
|
+
"bookmark-folder-id",
|
145
|
+
"bookmark_folder_id",
|
146
|
+
"bookmark_folder-id",
|
147
|
+
"bookmark-folder_id"
|
148
|
+
@@commander.bookmarks_folder_id first_word_token
|
149
|
+
when "pi"
|
150
|
+
@@commander.pi
|
151
|
+
when "e"
|
152
|
+
@@commander.e
|
153
|
+
when "+"
|
154
|
+
@@commander.+ *numbers_from_expressions
|
155
|
+
when "-"
|
156
|
+
@@commander.- *numbers_from_expressions
|
157
|
+
when "*"
|
158
|
+
@@commander.* *numbers_from_expressions
|
159
|
+
when "/"
|
160
|
+
@@commander./ *numbers_from_expressions
|
161
|
+
when "%"
|
162
|
+
@@commander.% *numbers_from_expressions
|
163
|
+
when "^", "**"
|
164
|
+
@@commander.** *numbers_from_expressions
|
165
|
+
when "sin", "cos", "tan",
|
166
|
+
"asin", "acos", "atan",
|
167
|
+
"sinh", "cosh", "tanh",
|
168
|
+
"asinh", "acosh", "atanh",
|
169
|
+
"erf", "erfc",
|
170
|
+
"gamma", "log10", "sqrt"
|
171
|
+
@@commander.send command.word.to_sym, number_from_expression
|
172
|
+
when "d2r",
|
173
|
+
"deg->rad",
|
174
|
+
"degrees->radians"
|
175
|
+
@@commander.degrees2radians number_from_expression
|
176
|
+
when "r2d",
|
177
|
+
"rad->deg",
|
178
|
+
"radians->degrees"
|
179
|
+
@@commander.radians2degrees number_from_expression
|
180
|
+
when "lgamma"
|
181
|
+
@@commander.lgamma number_from_expression
|
182
|
+
when "ld",
|
183
|
+
"log2"
|
184
|
+
@@commander.ld number_from_expression
|
185
|
+
when "ln"
|
186
|
+
@@commander.ln number_from_expression
|
187
|
+
when "log"
|
188
|
+
base, number = numbers_from_expressions
|
189
|
+
@@commander.log base, number
|
190
|
+
when "ldexp"
|
191
|
+
fraction, exponent = numbers_from_expressions
|
192
|
+
@@commander.ldexp fraction, exponent
|
193
|
+
when "hypot"
|
194
|
+
@@commander.hypot numbers_from_expressions
|
195
|
+
else
|
196
|
+
command_error "unknown command #{command.to_html}"
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def html_tag(tag)
|
201
|
+
"<#{tag}>" + expressions.map(&:to_html).join + "</#{tag}>"
|
202
|
+
end
|
203
|
+
|
204
|
+
def tb_href(target, string)
|
205
|
+
%{<a href="#{TB_COM}/#{target}">#{string}</a>}
|
206
|
+
end
|
207
|
+
|
208
|
+
def first_word_token
|
209
|
+
expressions.select {|expr| expr.is_a? WordToken}.first
|
210
|
+
end
|
211
|
+
|
212
|
+
def numbers_from_expressions
|
213
|
+
expressions
|
214
|
+
.map do |number|
|
215
|
+
begin
|
216
|
+
Float(number.to_html)
|
217
|
+
rescue ArgumentError
|
218
|
+
nil
|
219
|
+
end
|
220
|
+
end.reject &:nil?
|
221
|
+
end
|
222
|
+
|
223
|
+
def number_from_expression
|
224
|
+
numbers_from_expressions.first
|
225
|
+
end
|
226
|
+
|
227
|
+
class << self
|
228
|
+
@@commander = Commander.new
|
229
|
+
@@action_view = nil
|
230
|
+
@@controller = nil
|
231
|
+
|
232
|
+
def parse(tokens)
|
233
|
+
expressions = []
|
234
|
+
rest = tokens
|
235
|
+
backslash, command, left_brace = rest.shift(3)
|
236
|
+
right_brace = nil
|
237
|
+
raise ParseError if not backslash.is_a? BackslashToken
|
238
|
+
raise ParseError if not command.is_a? WordToken
|
239
|
+
if not left_brace.is_a? LeftBraceToken # A command with no interior.
|
240
|
+
rest.unshift left_brace if not left_brace.is_a? WhitespaceToken
|
241
|
+
return [CommandParser.new(command, []), rest]
|
242
|
+
end
|
243
|
+
while rest.length > 0
|
244
|
+
if rest.first.is_a? WordToken
|
245
|
+
expressions << rest.shift
|
246
|
+
elsif rest.first.is_a? WhitespaceToken
|
247
|
+
expressions << rest.shift
|
248
|
+
elsif rest.first.is_a? BackslashToken
|
249
|
+
result, rest = CommandParser.parse(rest)
|
250
|
+
expressions << result
|
251
|
+
elsif rest.first.is_a? RightBraceToken
|
252
|
+
right_brace = rest.shift
|
253
|
+
return [CommandParser.new(command, expressions), rest]
|
254
|
+
else
|
255
|
+
raise ParseError
|
256
|
+
end
|
257
|
+
end
|
258
|
+
if right_brace.nil? # Allow a forgotten final right brace.
|
259
|
+
return [CommandParser.new(command, expressions), rest]
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
def commander= new
|
264
|
+
@@commander = new
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
@@ -0,0 +1,320 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# -*- mode: Ruby -*-
|
3
|
+
|
4
|
+
# Copyright © 2013-2015, Christopher Mark Gore,
|
5
|
+
# Soli Deo Gloria,
|
6
|
+
# All rights reserved.
|
7
|
+
#
|
8
|
+
# 2317 South River Road, Saint Charles, Missouri 63303 USA.
|
9
|
+
# Web: http://cgore.com
|
10
|
+
# Email: cgore@cgore.com
|
11
|
+
#
|
12
|
+
# Redistribution and use in source and binary forms, with or without
|
13
|
+
# modification, are permitted provided that the following conditions are met:
|
14
|
+
#
|
15
|
+
# * Redistributions of source code must retain the above copyright
|
16
|
+
# notice, this list of conditions and the following disclaimer.
|
17
|
+
#
|
18
|
+
# * Redistributions in binary form must reproduce the above copyright
|
19
|
+
# notice, this list of conditions and the following disclaimer in the
|
20
|
+
# documentation and/or other materials provided with the distribution.
|
21
|
+
#
|
22
|
+
# * Neither the name of Christopher Mark Gore nor the names of other
|
23
|
+
# contributors may be used to endorse or promote products derived from
|
24
|
+
# this software without specific prior written permission.
|
25
|
+
#
|
26
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
27
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
28
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
29
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
30
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
31
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
32
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
33
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
34
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
35
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
36
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
37
|
+
|
38
|
+
require 'active_support/all'
|
39
|
+
require 'monkey-patch'
|
40
|
+
|
41
|
+
require 'teepee/constants'
|
42
|
+
require 'teepee/errors'
|
43
|
+
|
44
|
+
include ERB::Util
|
45
|
+
|
46
|
+
module Teepee
|
47
|
+
class Commander
|
48
|
+
def command_error message
|
49
|
+
%{<span style="color: red">[#{message}]</span>}
|
50
|
+
end
|
51
|
+
|
52
|
+
def command_not_yet_implemented command
|
53
|
+
command_error "The command #{command} is not yet implemented."
|
54
|
+
end
|
55
|
+
|
56
|
+
def ensure_numeric number
|
57
|
+
if number.kind_of? Complex
|
58
|
+
command_error "Complex numbers are not yet supported."
|
59
|
+
elsif not number.kind_of? Numeric
|
60
|
+
command_error "Non-numeric result."
|
61
|
+
else
|
62
|
+
number
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def html_tag tag, expressions
|
67
|
+
"<#{tag}>" + expressions.map(&:to_html).join + "</#{tag}>"
|
68
|
+
end
|
69
|
+
|
70
|
+
def tb_href target, string
|
71
|
+
%{<a href="#{TB_COM}/#{target}">#{string}</a>}
|
72
|
+
end
|
73
|
+
|
74
|
+
def id_command_handler(id,
|
75
|
+
klass,
|
76
|
+
singular = klass.to_s.camelcase_to_snakecase,
|
77
|
+
plural = singular.pluralize,
|
78
|
+
partial = "#{plural}/inline",
|
79
|
+
view="")
|
80
|
+
if not id
|
81
|
+
command_error "#{singular}_id: error: no #{singular} ID specified"
|
82
|
+
elsif not id.to_s =~ /\A[0-9]+\z/
|
83
|
+
command_error "#{singular}_id: error: invalid #{singular} ID specified"
|
84
|
+
else
|
85
|
+
tb_href "/#{plural}/#{id.to_s}/#{view}", "#{klass} ##{id.to_s}"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
#----------------------------------------------------------------------------
|
90
|
+
|
91
|
+
def + *numbers
|
92
|
+
ensure_numeric numbers.inject 0, :+
|
93
|
+
end
|
94
|
+
|
95
|
+
def - *numbers
|
96
|
+
if numbers.length == 1
|
97
|
+
ensure_numeric -numbers.first
|
98
|
+
else
|
99
|
+
ensure_numeric numbers.reduce :-
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def * *numbers
|
104
|
+
ensure_numeric numbers.inject 1, :*
|
105
|
+
end
|
106
|
+
|
107
|
+
def / *numbers
|
108
|
+
if numbers.length == 1
|
109
|
+
ensure_numeric 1 / numbers.first
|
110
|
+
else
|
111
|
+
ensure_numeric numbers.reduce :/
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def % *numbers
|
116
|
+
ensure_numeric numbers.reduce :%
|
117
|
+
end
|
118
|
+
|
119
|
+
def ** *numbers
|
120
|
+
ensure_numeric numbers.reduce :**
|
121
|
+
end
|
122
|
+
|
123
|
+
def acos number
|
124
|
+
ensure_numeric Math.acos number
|
125
|
+
end
|
126
|
+
|
127
|
+
def acosh number
|
128
|
+
ensure_numeric Math.acosh number
|
129
|
+
end
|
130
|
+
|
131
|
+
def asin number
|
132
|
+
ensure_numeric Math.asin number
|
133
|
+
end
|
134
|
+
|
135
|
+
def asinh number
|
136
|
+
ensure_numeric Math.asinh number
|
137
|
+
end
|
138
|
+
|
139
|
+
def atan number
|
140
|
+
ensure_numeric Math.atan number
|
141
|
+
end
|
142
|
+
|
143
|
+
def atanh number
|
144
|
+
ensure_numeric Math.atanh number
|
145
|
+
end
|
146
|
+
|
147
|
+
def b expressions
|
148
|
+
html_tag :b, expressions
|
149
|
+
end
|
150
|
+
|
151
|
+
def backslash
|
152
|
+
"\\"
|
153
|
+
end
|
154
|
+
|
155
|
+
def big expressions
|
156
|
+
html_tag :big, expressions
|
157
|
+
end
|
158
|
+
|
159
|
+
def bookmarks_folder_id id
|
160
|
+
id_command_handler id, Folder, "folder", "folders", "folders/bookmarks_inline", "bookmarks"
|
161
|
+
end
|
162
|
+
|
163
|
+
def br
|
164
|
+
"\n</br>\n"
|
165
|
+
end
|
166
|
+
|
167
|
+
def cos angle
|
168
|
+
ensure_numeric Math.cos angle
|
169
|
+
end
|
170
|
+
|
171
|
+
def cosh number
|
172
|
+
ensure_numeric Math.cosh number
|
173
|
+
end
|
174
|
+
|
175
|
+
def degrees2radians degrees
|
176
|
+
ensure_numeric degrees * Math::PI / 180.0
|
177
|
+
end
|
178
|
+
|
179
|
+
def del expressions
|
180
|
+
html_tag :del, expressions
|
181
|
+
end
|
182
|
+
|
183
|
+
def e
|
184
|
+
Math::E
|
185
|
+
end
|
186
|
+
|
187
|
+
def erf number
|
188
|
+
ensure_numeric Math.erf number
|
189
|
+
end
|
190
|
+
|
191
|
+
def erfc number
|
192
|
+
ensure_numeric Math.erfc number
|
193
|
+
end
|
194
|
+
|
195
|
+
def folder_id id
|
196
|
+
id_command_handler id, Folder
|
197
|
+
end
|
198
|
+
|
199
|
+
def forum_id id
|
200
|
+
id_command_handler id, Forum
|
201
|
+
end
|
202
|
+
|
203
|
+
def gamma number
|
204
|
+
ensure_numeric Math.gamma number
|
205
|
+
end
|
206
|
+
|
207
|
+
def i
|
208
|
+
command_error "Complex numbers are not yet supported."
|
209
|
+
end
|
210
|
+
|
211
|
+
def it expressions
|
212
|
+
html_tag :i, expressions
|
213
|
+
end
|
214
|
+
|
215
|
+
def hypot numbers
|
216
|
+
ensure_numeric Math.sqrt numbers.map {|n| n**2}
|
217
|
+
end
|
218
|
+
|
219
|
+
def ld n
|
220
|
+
ensure_numeric Math.log2 n
|
221
|
+
end
|
222
|
+
|
223
|
+
def ldexp fraction, exponent
|
224
|
+
ensure_numeric Math.ldexp fraction, exponent
|
225
|
+
end
|
226
|
+
|
227
|
+
def left_brace
|
228
|
+
"{"
|
229
|
+
end
|
230
|
+
|
231
|
+
def lgamma n
|
232
|
+
ensure_numeric Math::lgamma(n).first
|
233
|
+
end
|
234
|
+
|
235
|
+
def link_id
|
236
|
+
id_command_handler id, Link
|
237
|
+
end
|
238
|
+
|
239
|
+
def ln number
|
240
|
+
ensure_numeric Math.log number
|
241
|
+
end
|
242
|
+
|
243
|
+
def log base, number
|
244
|
+
if number.nil?
|
245
|
+
number, base = base, number
|
246
|
+
ensure_numeric Math.log number # default to natural logarithm
|
247
|
+
else
|
248
|
+
ensure_numeric Math.log number, base
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
def log10 number
|
253
|
+
ensure_numeric Math.log10 number
|
254
|
+
end
|
255
|
+
|
256
|
+
def pi
|
257
|
+
Math::PI
|
258
|
+
end
|
259
|
+
|
260
|
+
def radians2degrees radians
|
261
|
+
ensure_numeric(radians * 180.0 / Math::PI)
|
262
|
+
end
|
263
|
+
|
264
|
+
def right_brace
|
265
|
+
"}"
|
266
|
+
end
|
267
|
+
|
268
|
+
def sin angle
|
269
|
+
ensure_numeric Math.sin angle
|
270
|
+
end
|
271
|
+
|
272
|
+
def sinh number
|
273
|
+
ensure_numeric Math.sinh number
|
274
|
+
end
|
275
|
+
|
276
|
+
def small expressions
|
277
|
+
html_tag :small, expressions
|
278
|
+
end
|
279
|
+
|
280
|
+
def sqrt number
|
281
|
+
ensure_numeric Math.sqrt number
|
282
|
+
end
|
283
|
+
|
284
|
+
def sub expressions
|
285
|
+
html_tag :sub, expressions
|
286
|
+
end
|
287
|
+
|
288
|
+
def sup expressions
|
289
|
+
html_tag :sup, expressions
|
290
|
+
end
|
291
|
+
|
292
|
+
def tag_id id
|
293
|
+
id_command_handler id, Tag
|
294
|
+
end
|
295
|
+
|
296
|
+
def tan angle
|
297
|
+
ensure_numeric Math.tan angle
|
298
|
+
end
|
299
|
+
|
300
|
+
def tanh number
|
301
|
+
ensure_numeric Math.tanh number
|
302
|
+
end
|
303
|
+
|
304
|
+
def tt expressions
|
305
|
+
html_tag :tt, expressions
|
306
|
+
end
|
307
|
+
|
308
|
+
def u expressions
|
309
|
+
html_tag :u, expressions
|
310
|
+
end
|
311
|
+
|
312
|
+
def user user
|
313
|
+
if not user
|
314
|
+
command_error "user: error: no user specified"
|
315
|
+
else
|
316
|
+
tb_href "users/#{user}", user.to_s
|
317
|
+
end
|
318
|
+
end
|
319
|
+
end
|
320
|
+
end
|