Class: TBMX::CommandParser

Inherits:
ParserNode show all
Defined in:
lib/tbmx.rb

Constant Summary collapse

@@action_view =
nil
@@controller =
nil

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(command, expressions) ⇒ CommandParser

Returns a new instance of CommandParser.

Raises:

  • (ArgumentError)


238
239
240
241
242
243
244
# File 'lib/tbmx.rb', line 238

def initialize(command, expressions)
  raise ArgumentError if not command.is_a? WordToken
  @command = command
  raise ArgumentError if not expressions.is_a? Array
  expressions.each {|expression| raise ArgumentError if not expression.kind_of? ParserNode}
  @expressions = expressions
end

Instance Attribute Details

#commandObject (readonly)

Returns the value of attribute command.



236
237
238
# File 'lib/tbmx.rb', line 236

def command
  @command
end

#expressionsObject (readonly)

Returns the value of attribute expressions.



236
237
238
# File 'lib/tbmx.rb', line 236

def expressions
  @expressions
end

Class Method Details

.action_view=(new) ⇒ Object



482
483
484
# File 'lib/tbmx.rb', line 482

def action_view=(new)
  @@action_view = new
end

.controller=(new) ⇒ Object



486
487
488
# File 'lib/tbmx.rb', line 486

def controller=(new)
  @@controller = new
end

.parse(tokens) ⇒ Object

Raises:



451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
# File 'lib/tbmx.rb', line 451

def parse(tokens)
  expressions = []
  rest = tokens
  backslash, command, left_brace = rest.shift(3)
  right_brace = nil
  raise ParseError if not backslash.is_a? BackslashToken
  raise ParseError if not command.is_a? WordToken
  if not left_brace.is_a? LeftBraceToken # A command with no interior.
    rest.unshift left_brace if not left_brace.is_a? WhitespaceToken
    return [CommandParser.new(command, []), rest]
  end
  while rest.length > 0
    if rest.first.is_a? WordToken
      expressions << rest.shift
    elsif rest.first.is_a? WhitespaceToken
      expressions << rest.shift
    elsif rest.first.is_a? BackslashToken
      result, rest = CommandParser.parse(rest)
      expressions << result
    elsif rest.first.is_a? RightBraceToken
      right_brace = rest.shift
      return [CommandParser.new(command, expressions), rest]
    else
      raise ParseError
    end
  end
  if right_brace.nil? # Allow a forgotten final right brace.
    return [CommandParser.new(command, expressions), rest]
  end
end

Instance Method Details

#bookmarks_folder_id_command_handlerObject



443
444
445
# File 'lib/tbmx.rb', line 443

def bookmarks_folder_id_command_handler
  id_command_handler Folder, "folder", "folders", "folders/bookmarks_inline", "bookmarks"
end

#command_error(message) ⇒ Object



246
247
248
# File 'lib/tbmx.rb', line 246

def command_error(message)
  %{<span style="color: red">[#{message}]</span>}
end

#folder_id_command_handlerObject



439
440
441
# File 'lib/tbmx.rb', line 439

def folder_id_command_handler
  id_command_handler Folder
end

#html_tag(tag) ⇒ Object



352
353
354
# File 'lib/tbmx.rb', line 352

def html_tag(tag)
  "<#{tag}>" + expressions.map(&:to_html).join + "</#{tag}>"
end

#id_command_handler(klass, singular = klass.to_s.camelcase_to_snakecase, plural = singular.pluralize, partial = "#{plural}/inline", view = "") ⇒ Object



406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
# File 'lib/tbmx.rb', line 406

def id_command_handler(klass,
                       singular = klass.to_s.camelcase_to_snakecase,
                       plural = singular.pluralize,
                       partial = "#{plural}/inline",
                       view="")
  id = expressions.select {|expr| expr.is_a? WordToken}.first
  if not id
    command_error "#{singular}_id: error: no #{singular} ID specified"
  elsif not id.to_s =~ /\A[0-9]+\z/
    command_error "#{singular}_id: error: invalid #{singular} ID specified"
  else
    if @@action_view.kind_of? ActionView::Base
      thing = klass.find Integer(id.to_s)
      if thing
        @@action_view.render partial: partial,
                             locals: {singular.to_sym => thing}
      else
        command_error "unknown #{singular} ID #{id.to_s}"
      end
    else
      tb_href "/#{plural}/#{id.to_s}/#{view}", "#{klass} ##{id.to_s}"
    end
  end
end

#injectable_math_function_handler(initial, function) ⇒ Object



375
376
377
# File 'lib/tbmx.rb', line 375

def injectable_math_function_handler(initial, function)
  numbers_from_expressions.inject initial, function
end


431
432
433
# File 'lib/tbmx.rb', line 431

def link_id_command_handler
  id_command_handler Link
end

#math_function_handler(function) ⇒ Object



383
384
385
# File 'lib/tbmx.rb', line 383

def math_function_handler(function)
  Math.send function, numbers_from_expressions.first
end

#number_from_expressionObject



371
372
373
# File 'lib/tbmx.rb', line 371

def number_from_expression
  numbers_from_expressions.first
end

#numbers_from_expressionsObject



360
361
362
363
364
365
366
367
368
369
# File 'lib/tbmx.rb', line 360

def numbers_from_expressions
  expressions
    .map do |number|
      begin
        Float(number.to_html)
      rescue ArgumentError
        nil
      end
    end.reject &:nil?
end

#reducable_math_function_handler(function) ⇒ Object



379
380
381
# File 'lib/tbmx.rb', line 379

def reducable_math_function_handler(function)
  numbers_from_expressions.reduce function
end

#tag_id_command_handlerObject



435
436
437
# File 'lib/tbmx.rb', line 435

def tag_id_command_handler
  id_command_handler Tag
end

#tb_href(target, string) ⇒ Object



356
357
358
# File 'lib/tbmx.rb', line 356

def tb_href(target, string)
  %{<a href="#{TB_COM}/#{target}">#{string}</a>}
end

#to_htmlObject



250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
# File 'lib/tbmx.rb', line 250

def to_html
  case command.word
  when "backslash", "bslash"
    "\\"
  when "left-brace", "left_brace", "leftbrace", "lbrace", "opening-brace", "opening_brace",
       "openingbrace", "obrace"
    "{"
  when "right-brace", "right_brace", "rightbrace", "rbrace", "closing-brace", "closing_brace",
       "closingbrace", "cbrace"
    "}"
  when "br", "newline"
    "\n</br>\n"
  when "bold", "b", "textbf"
    html_tag :b
  when "del", "s", "strike", "strikethrough", "strikeout"
    html_tag :del
  when "italic", "i", "textit"
    html_tag :i
  when "underline", "u"
    html_tag :u
  when "tt", "texttt", "teletype", "typewriter"
    html_tag :tt
  when "small"
    html_tag :small
  when "big"
    html_tag :big
  when "subscript", "sub"
    html_tag :sub
  when "superscript", "sup"
    html_tag :sup
  when "user", "user-id", "user_id"
    user_command_handler
  when "link-id", "link_id"
    link_id_command_handler
  when "keyword-id", "keyword_id"
    keyword_id_command_handler
  when "tag-id", "tag_id"
    tag_id_command_handler
  when "folder-id", "folder_id"
    folder_id_command_handler
  when "bookmarks-folder-id", "bookmarks_folder_id", "bookmarks_folder-id", "bookmarks-folder_id",
       "bookmark-folder-id",  "bookmark_folder_id",  "bookmark_folder-id",  "bookmark-folder_id"
    bookmarks_folder_id_command_handler
  when "pi"
    "#{Math::PI}"
  when "e"
    "#{Math::E}"
  when "+"
    injectable_math_function_handler 0, :+
  when "-"
    if (numbers = numbers_from_expressions).length == 1
      injectable_math_function_handler 0, :-
    else
      reducable_math_function_handler :-
    end
  when "*"
    injectable_math_function_handler 1, :*
  when "/"
    if (numbers = numbers_from_expressions).length == 1
      1 / numbers.first
    else
      reducable_math_function_handler :/
    end
  when "%"
    injectable_math_function_handler numbers_from_expressions.first, :%
  when "^", "**"
    number, exponent = numbers_from_expressions
    number.send :**, exponent
  when "sin", "cos", "tan",
    "asin", "acos", "atan",
    "sinh", "cosh", "tanh",
    "asinh", "acosh", "atanh",
    "erf", "erfc",
    "gamma", "lgamma",
    "log10", "log2",
    "sqrt"
    math_function_handler command.word.to_sym
  when "d2r", "deg->rad", "degrees->radians"
    degrees = number_from_expression
    radians = degrees * Math::PI / 180.0
    radians
  when "r2d", "rad->deg", "radians->degrees"
    radians = number_from_expression
    degrees = radians * 180.0 / Math::PI
    degrees
  when "log"
    base, number = numbers_from_expressions
    if number.nil?
      Math.log base
    else
      Math.log number, base
    end
  when "ldexp"
    fraction, exponent = numbers_from_expressions
    Math.ldexp fraction, exponent
  when "hypot"
    Math.sqrt numbers_from_expressions.map {|n| n**2}
  else
    command_error "unknown command #{command.to_html}"
  end
end

#user_command_handlerObject



387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
# File 'lib/tbmx.rb', line 387

def user_command_handler
  user = expressions.select {|expr| expr.is_a? WordToken}.first
  if not user
    command_error "user: error: no user specified"
  else
    if @@action_view.kind_of? ActionView::Base
      the_user = User.smart_find user.to_s
      if the_user
        @@action_view.render partial: 'users/name_link',
                             locals: {the_user: the_user}
      else
        command_error "unknown user #{user.to_s}"
      end
    else
      tb_href "users/#{user}", user.to_s
    end
  end
end