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)


254
255
256
257
258
259
260
# File 'lib/tbmx.rb', line 254

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.



252
253
254
# File 'lib/tbmx.rb', line 252

def command
  @command
end

#expressionsObject (readonly)

Returns the value of attribute expressions.



252
253
254
# File 'lib/tbmx.rb', line 252

def expressions
  @expressions
end

Class Method Details

.action_view=(new) ⇒ Object



496
497
498
# File 'lib/tbmx.rb', line 496

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

.controller=(new) ⇒ Object



500
501
502
# File 'lib/tbmx.rb', line 500

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

.parse(tokens) ⇒ Object

Raises:



465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
# File 'lib/tbmx.rb', line 465

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



457
458
459
# File 'lib/tbmx.rb', line 457

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

#command_error(message) ⇒ Object



262
263
264
# File 'lib/tbmx.rb', line 262

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

#folder_id_command_handlerObject



453
454
455
# File 'lib/tbmx.rb', line 453

def folder_id_command_handler
  id_command_handler Folder
end

#html_tag(tag) ⇒ Object



366
367
368
# File 'lib/tbmx.rb', line 366

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



420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
# File 'lib/tbmx.rb', line 420

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



389
390
391
# File 'lib/tbmx.rb', line 389

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


445
446
447
# File 'lib/tbmx.rb', line 445

def link_id_command_handler
  id_command_handler Link
end

#math_function_handler(function) ⇒ Object



397
398
399
# File 'lib/tbmx.rb', line 397

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

#number_from_expressionObject



385
386
387
# File 'lib/tbmx.rb', line 385

def number_from_expression
  numbers_from_expressions.first
end

#numbers_from_expressionsObject



374
375
376
377
378
379
380
381
382
383
# File 'lib/tbmx.rb', line 374

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



393
394
395
# File 'lib/tbmx.rb', line 393

def reducable_math_function_handler(function)
  numbers_from_expressions.reduce function
end

#tag_id_command_handlerObject



449
450
451
# File 'lib/tbmx.rb', line 449

def tag_id_command_handler
  id_command_handler Tag
end

#tb_href(target, string) ⇒ Object



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

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

#to_htmlObject



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
351
352
353
354
355
356
357
358
359
360
361
362
363
364
# File 'lib/tbmx.rb', line 266

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",
    "log10", "log2",
    "sqrt"
    math_function_handler command.word.to_sym
  when "d2r", "deg->rad", "degrees->radians"
    MathFunctions::degrees2radians number_from_expression
  when "r2d", "rad->deg", "radians->degrees"
    MathFunctions::radians2degrees number_from_expression
  when "lgamma"
    MathFunctions::lgamma number_from_expression
  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



401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
# File 'lib/tbmx.rb', line 401

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