Module: Luoma

Defined in:
lib/luoma/expression.rb,
lib/luoma.rb,
lib/luoma/fnv.rb,
lib/luoma/drop.rb,
lib/luoma/cache.rb,
lib/luoma/lexer.rb,
lib/luoma/token.rb,
lib/luoma/errors.rb,
lib/luoma/escape.rb,
lib/luoma/filter.rb,
lib/luoma/loader.rb,
lib/luoma/markup.rb,
lib/luoma/parser.rb,
lib/luoma/context.rb,
lib/luoma/tags/if.rb,
lib/luoma/version.rb,
lib/luoma/tags/for.rb,
lib/luoma/tags/raw.rb,
lib/luoma/template.rb,
lib/luoma/tags/case.rb,
lib/luoma/tags/else.rb,
lib/luoma/tags/with.rb,
lib/luoma/chain_hash.rb,
lib/luoma/tags/break.rb,
lib/luoma/drops/block.rb,
lib/luoma/drops/range.rb,
lib/luoma/environment.rb,
lib/luoma/tags/assign.rb,
lib/luoma/tags/define.rb,
lib/luoma/tags/import.rb,
lib/luoma/tags/output.rb,
lib/luoma/tags/render.rb,
lib/luoma/filters/date.rb,
lib/luoma/filters/json.rb,
lib/luoma/filters/math.rb,
lib/luoma/filters/size.rb,
lib/luoma/filters/sort.rb,
lib/luoma/lexer_legacy.rb,
lib/luoma/tags/capture.rb,
lib/luoma/tags/comment.rb,
lib/luoma/tags/include.rb,
lib/luoma/filters/array.rb,
lib/luoma/filters/slice.rb,
lib/luoma/lexer_unified.rb,
lib/luoma/tags/continue.rb,
lib/luoma/filters/string.rb,
lib/luoma/loaders/mixins.rb,
lib/luoma/parser_unified.rb,
lib/luoma/drops/html_safe.rb,
lib/luoma/drops/undefined.rb,
lib/luoma/filters/default.rb,
lib/luoma/predicates/type.rb,
lib/luoma/static_analysis.rb,
lib/luoma/drops/expression.rb,
lib/luoma/predicates/blank.rb,
lib/luoma/predicates/empty.rb,
lib/luoma/predicates/defined.rb,
lib/luoma/loaders/choice_loader.rb,
lib/luoma/loaders/file_system_loader.rb,
sig/luoma.rbs,
sig/luoma/fnv.rbs,
sig/luoma/drop.rbs,
sig/luoma/cache.rbs,
sig/luoma/lexer.rbs,
sig/luoma/token.rbs,
sig/luoma/errors.rbs,
sig/luoma/escape.rbs,
sig/luoma/filter.rbs,
sig/luoma/loader.rbs,
sig/luoma/markup.rbs,
sig/luoma/parser.rbs,
sig/luoma/context.rbs,
sig/luoma/tags/if.rbs,
sig/luoma/tags/for.rbs,
sig/luoma/tags/raw.rbs,
sig/luoma/template.rbs,
sig/luoma/tags/case.rbs,
sig/luoma/tags/else.rbs,
sig/luoma/tags/with.rbs,
sig/luoma/chain_hash.rbs,
sig/luoma/expression.rbs,
sig/luoma/tags/break.rbs,
sig/luoma/drops/block.rbs,
sig/luoma/drops/range.rbs,
sig/luoma/environment.rbs,
sig/luoma/tags/assign.rbs,
sig/luoma/tags/define.rbs,
sig/luoma/tags/import.rbs,
sig/luoma/tags/output.rbs,
sig/luoma/tags/render.rbs,
sig/luoma/filters/date.rbs,
sig/luoma/filters/json.rbs,
sig/luoma/filters/math.rbs,
sig/luoma/filters/size.rbs,
sig/luoma/filters/sort.rbs,
sig/luoma/lexer_legacy.rbs,
sig/luoma/tags/capture.rbs,
sig/luoma/tags/comment.rbs,
sig/luoma/tags/include.rbs,
sig/luoma/filters/array.rbs,
sig/luoma/filters/slice.rbs,
sig/luoma/lexer_unified.rbs,
sig/luoma/tags/continue.rbs,
sig/luoma/filters/string.rbs,
sig/luoma/loaders/mixins.rbs,
sig/luoma/parser_unified.rbs,
sig/luoma/drops/html_safe.rbs,
sig/luoma/drops/undefined.rbs,
sig/luoma/filters/default.rbs,
sig/luoma/predicates/type.rbs,
sig/luoma/static_analysis.rbs,
sig/luoma/drops/expression.rbs,
sig/luoma/predicates/blank.rbs,
sig/luoma/predicates/empty.rbs,
sig/luoma/predicates/defined.rbs,
sig/luoma/loaders/choice_loader.rbs,
sig/luoma/loaders/file_system_loader.rbs

Overview

rubocop:disable Naming/PredicateMethod

Defined Under Namespace

Modules: CachingLoaderMixin, Filters, Predicates, StaticAnalysis, _Lexer, _Namespace, _Parser, _Tag, _Traversable Classes: AddExpression, AndExpression, ArrayLiteral, AssignTag, BaseLexer, BlockDrop, BooleanLiteral, BreakTag, CachingFileSystemLoader, CaptureTag, CaseTag, ChainHash, ChoiceLoader, CoalesceExpression, Comment, ContainsExpression, ContextDepthError, ContinueTag, DefineTag, DetailedLuomaError, DisabledTagError, DivExpression, Drop, ElseBlock, Environment, EqExpression, Expression, ExpressionDrop, FalsyStrictUndefinedDrop, FileSystemLoader, Filter, FilterArgumentError, FilterContext, FilterNotFoundError, FilteredExpression, FloatLiteral, ForTag, GeExpression, GroupExpression, GtExpression, HTMLSafe, HashLoader, IfBlock, IfTag, ImportTag, InExpression, IncludeTag, IncomparableValuesError, IndexSelector, InfixExpression, IntegerLiteral, Item, KeywordArgument, LRUCache, Lambda, LambdaExpr, LeExpression, LegacyLexer, LtExpression, LuomaError, Markup, ModExpression, MulExpression, Name, NeExpression, NegExpression, NoSuchTemplateError, NotExpression, NullLiteral, ObjectLiteral, OrExpression, OutputStatement, Parser, Partial, PosExpression, Predicate, PredicateFunction, PredicateNotFoundError, PrefixExpression, RangeDrop, RangeLiteral, RawTag, RenderContext, RenderTag, RequiredBlockError, ResourceLimitError, Spread, StrictUndefinedDrop, StringLiteral, SubExpression, Template, TemplateInheritanceError, TemplateLoader, TemplateNotFoundError, TemplateSource, TemplateSyntaxError, TemplateTypeError, TernaryExpression, ThreadSafeLRUCache, UndefinedDrop, UndefinedVariableError, UnifiedLexer, UnifiedParser, Variable, WhenBlock, WithTag

Constant Summary collapse

DEFAULT_ENVIRONMENT =

Returns:

Environment.new
TOKEN_KIND_MAP =

Returns:

  • (Hash[t_token_kind, String])
{
  token_add: "ADD",
  token_and: "AND",
  token_arrow: "ARROW",
  token_assign: "ASSIGN",
  token_colon: "COLON",
  token_comma: "COMMA",
  token_comment: "COMMENT",
  token_comment_end: "COMMENT_END",
  token_comment_start: "COMMENT_START",
  token_contains: "CONTAINS",
  token_div: "DIV",
  token_dot: "DOT",
  token_double_dot: "DOUBLE_DOT",
  token_double_escaped: "DOUBLE_ESCAPED",
  token_double_quote: "DOUBLE_QUOTE",
  token_double_quoted: "DOUBLE_QUOTED",
  token_else: "ELSE",
  token_eq: "EQ",
  token_false: "FALSE",
  token_float: "FLOAT",
  token_ge: "GE",
  token_gt: "GT",
  token_ident: "IDENT",
  token_if: "IF",
  token_in: "IN",
  token_int: "INT",
  token_interpolation_end: "INTERPOLATION_END",
  token_interpolation_start: "INTERPOLATION_START",
  token_lbrace: "LBRACE",
  token_lbracket: "LBRACKET",
  token_le: "LE",
  token_lparen: "LPAREN",
  token_lt: "LT",
  token_mod: "MOD",
  token_mul: "MUL",
  token_ne: "NE",
  token_nil: "NIL",
  token_not: "NOT",
  token_null: "NULL",
  token_or_else: "OR_ELSE",
  token_or: "OR",
  token_out_end: "OUT_END",
  token_out_start: "OUT_START",
  token_pipe: "PIPE",
  token_question: "QUESTION",
  token_rbrace: "RBRACE",
  token_rbracket: "RBRACKET",
  token_rparen: "RPAREN",
  token_single_escaped: "SINGLE_ESCAPED",
  token_single_quote: "SINGLE_QUOTE",
  token_single_quoted: "SINGLE_QUOTED",
  token_sub: "SUB",
  token_tag_end: "TAG_END",
  token_tag_name: "TAG_NAME",
  token_tag_start: "TAG_START",
  token_text: "TEXT",
  token_triple_dot: "TRIPLE_DOT",
  token_true: "TRUE",
  token_wc: "WC",
  token_eoi: "EOI",
  token_unknown: "UNKNOWN",
  token_hash: "HASH",
  token_span: "SPAN",
  token_blank: "BLANK",
  token_empty: "EMPTY",
  token_for: "FOR",
  token_with: "WITH"
}.freeze
RE_ESCAPE =

Returns:

  • (::Regexp)
/["&'<>`]/
ESCAPE_MAP =

Returns:

  • (Hash[String, String])
{
  '"' => "&#34;",
  "&" => "&amp;",
  "'" => "&#39;",
  "<" => "&lt;",
  ">" => "&gt;",
  "`" => "&#96;"
}.freeze
RE_UNESCAPE =

Signature:

  • Hash[String, String]

Returns:

  • (::Regexp)
/&(#34|amp|#39|lt|gt|#96);/i
UNESCAPE_MAP =

Returns:

  • (Hash[String, String])
{
  "&#34;": '"',
  "&amp;" => "&",
  "&#39;" => "'",
  "&lt;" => "<",
  "&gt;" => ">",
  "&#96;" => "`"
}.freeze
VERSION =

Returns:

  • (String)
"0.2.0"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Attribute Details

#pathString (readonly)

Returns the value of attribute path.

Returns:

  • (String)


4
5
6
# File 'lib/luoma/drops/undefined.rb', line 4

def path
  @path
end

Class Method Details

.blank_block?(block) ⇒ Boolean

(t_block) -> bool

Parameters:

  • block (t_block)

Returns:

  • (Boolean)


106
107
108
# File 'lib/luoma/markup.rb', line 106

def self.blank_block?(block)
  block.all? { |node| node.is_a?(String) ? node.match?(/\A\s*\Z/) : node.blank }
end

.escape(s) ⇒ String

(String) -> String

Parameters:

  • s (String)

Returns:

  • (String)


27
28
29
# File 'lib/luoma/escape.rb', line 27

def self.escape(s)
  s.gsub(RE_ESCAPE) { |m| ESCAPE_MAP[m] }
end

.fnv1a32(s) ⇒ Integer

Parameters:

  • s (String)

Returns:

  • (Integer)


4
5
6
7
8
9
10
11
12
13
14
# File 'lib/luoma/fnv.rb', line 4

def self.fnv1a32(s)
  hash = 0x811c9dc5 # offset basis for 32 bit hash

  s.bytes do |b|
    hash ^= b
    hash *= 0x01000193 # FNV prime for 32 bit hash
    hash &= (1 << 32) - 1
  end

  hash
end

.get_token_value(token, source) ⇒ String

Signature:

  • (t_token, String) -> String

Parameters:

  • token (t_token)
  • source (String)

Returns:

  • (String)


5
6
7
# File 'lib/luoma/token.rb', line 5

def self.get_token_value(token, source)
  source.byteslice(token[1]..token[2]) || raise
end

.parse(source, globals: nil) ⇒ Object

Signature:

  • (String, ?globals: Hash[String, untyped]?) -> Template

Parameters:

  • source (Object)
  • globals: (Object, nil) (defaults to: nil)

Returns:

  • (Object)


65
66
67
# File 'lib/luoma.rb', line 65

def self.parse(source, globals: nil)
  DEFAULT_ENVIRONMENT.parse(source, globals: globals)
end

.render(source, data = nil) ⇒ Object

Signature:

  • (String, ?Hash[String, untyped]?) -> String

Parameters:

  • source (Object)
  • data (Object, nil) (defaults to: nil)

Returns:

  • (Object)


72
73
74
# File 'lib/luoma.rb', line 72

def self.render(source, data = nil)
  DEFAULT_ENVIRONMENT.render(source, data)
end

.render_block(block, context, buffer, root: false) ⇒ void

This method returns an undefined value.

(t_block, RenderContext, String) -> void

Parameters:

  • block (t_block)
  • context (RenderContext)
  • buffer (String)
  • root: (Boolean) (defaults to: false)


59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/luoma/markup.rb', line 59

def self.render_block(block, context, buffer, root: false)
  if context.env.max_render_score || context.env.max_render_score_cumulative
    context.render_score += block.length
    context.render_score_cumulative += block.length

    if (context.env.max_render_score && context.render_score > context.env.max_render_score) ||
       (context.env.max_render_score_cumulative &&
        context.render_score_cumulative > context.env.max_render_score_cumulative)
      raise ResourceLimitError.new("memory limits reached")
    end
  end

  block.each do |node|
    if node.is_a?(String)
      buffer << node
    else
      if context.disabled_tags&.include?(node.tag_name)
        raise DisabledTagError.new(
          "#{node.tag_name.inspect} is not allowed in this context",
          node.token,
          context.template.source,
          context.template.name
        )
      end

      node.render(context, buffer)

      # TODO: disable these when strict is false?
      if root && !context.interrupts.empty?
        raise TemplateSyntaxError.new(
          "unexpected #{context.interrupts.last}",
          node.token,
          context.template.source,
          context.template.name
        )
      end
    end

    if context.env.max_render_size && buffer.bytesize > context.env.max_render_size
      raise ResourceLimitError.new("memory limits exceeded")
    end

    break unless context.interrupts.empty?
  end
end

.span(start, stop) ⇒ t_token

Return a new token spanning start and stop.

Signature:

  • (t_token, t_token) -> t_token

Parameters:

  • start (t_token)
  • stop (t_token)

Returns:

  • (t_token)


11
12
13
# File 'lib/luoma/token.rb', line 11

def self.span(start, stop)
  [:token_span, start[1], stop[2]]
end

.tree_view(e) ⇒ String

(Expression) -> String

Parameters:

Returns:

  • (String)


1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
# File 'lib/luoma/expression.rb', line 1232

def self.tree_view(e)
  # (prefix, connector, class_name, inspect_value)
  nodes = [] # : Array[[String, String, String, String]]

  # @type var visit: ^(_Traversable, String, bool) -> void
  visit = lambda do |node, prefix, is_last|
    connector = if prefix.empty?
                  ""
                elsif is_last
                  "└── "
                else
                  "├── "
                end

    nodes << [prefix, connector, node.class.to_s, node.to_s]
    child_prefix = prefix + (is_last ? "    " : "")
    node.children.each_with_index do |child, i|
      last = i == node.children.length - 1
      visit.call(child, child_prefix, last)
    end
  end

  visit.call(e, "", true)

  widths = nodes.map { |prefix, connector, cls| (prefix + connector + cls).length }
  max_width = widths.max || 0

  lines = [] # : Array[String]
  nodes.zip(widths).each do |node, width|
    prefix, connector, cls, val = node
    left = prefix + connector + cls
    padding = " " * (max_width - (width || raise) + 4)
    lines << (left + padding + val)
  end

  lines.join("\n")
end

.unescape(s) ⇒ String

(String) -> String

Parameters:

  • s (String)

Returns:

  • (String)


32
33
34
# File 'lib/luoma/escape.rb', line 32

def self.unescape(s)
  s.gsub(RE_UNESCAPE) { |m| UNESCAPE_MAP[m] }
end