eggshell 1.0.3 → 1.1.1

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.
@@ -1,10 +1,13 @@
1
1
  module Eggshell
2
2
  class Processor
3
- BLOCK_MATCH = /^([a-z0-9_-]+\.)/
4
- BLOCK_MATCH_PARAMS = /^([a-z0-9_-]+)\(/
3
+ BLOCK_MATCH = /^([a-zA-Z_][a-z0-9_-]*\.)/
4
+ BLOCK_MATCH_PARAMS = /^([a-zA-Z_][a-z0-9_-]*)\s*\(/
5
+
6
+ @@ee = Eggshell::ExpressionEvaluator.new
5
7
 
6
- def initialize
7
- @context = Eggshell::ProcessorContext.new
8
+ def initialize(context = nil)
9
+ @context = context
10
+ @context = Eggshell::ProcessorContext.new if !context.is_a?(Eggshell::ProcessorContext)
8
11
  @vars = @context.vars
9
12
  @funcs = @context.funcs
10
13
  @macros = @context.macros
@@ -14,6 +17,9 @@ module Eggshell
14
17
  @expr_cache = @context.expr_cache
15
18
  @fmt_handlers = @context.fmt_handlers
16
19
  @ee = Eggshell::ExpressionEvaluator.new(@vars, @funcs)
20
+
21
+ @vars[:include_paths] = [] if !@vars[:include_paths]
22
+ @vars[:include_paths] << File.realdirpath(Dir.pwd())
17
23
 
18
24
  @noop_macro = Eggshell::MacroHandler::Defaults::NoOpHandler.new
19
25
  @noop_block = Eggshell::BlockHandler::Defaults::NoOpHandler.new
@@ -29,6 +35,10 @@ module Eggshell
29
35
  end
30
36
  end
31
37
 
38
+ def get_block_handler(name)
39
+ @blocks_map[name]
40
+ end
41
+
32
42
  def rem_block_handler(*names)
33
43
  _trace "rem_block_handler: #{names.inspect}"
34
44
  names.each do |name|
@@ -44,6 +54,10 @@ module Eggshell
44
54
  end
45
55
  end
46
56
 
57
+ def get_macro_handler(name)
58
+ @macros[name]
59
+ end
60
+
47
61
  def rem_macro_handler(*names)
48
62
  _trace "rem_macro_handler: #{names.inspect}"
49
63
  names.each do |name|
@@ -51,17 +65,8 @@ module Eggshell
51
65
  end
52
66
  end
53
67
 
54
- # Registers a function for embedded expressions. Functions are grouped into namespaces,
55
- # and a handler can be assigned to handle all function calls within that namespace, or
56
- # a specific set of functions within the namespace. The root namespace is a blank string.
57
- #
58
- # @param String func_key In the form `ns` or `ns:func_name`. For functions in the
59
- # root namespace, do `:func_name`.
60
- # @param Object handler
61
- # @param Array func_names If `func_key` only refers to a namespace but the handler
62
- # needs to only handle a subset of functions, supply the list of function names here.
63
- def register_functions(func_key, handler, func_names = nil)
64
- @ee.register_functions(func_key, handler, func_names)
68
+ def register_functions(handler, names = nil, ns = '')
69
+ @ee.register_functions(handler, names, ns)
65
70
  end
66
71
 
67
72
  def _error(msg)
@@ -90,7 +95,7 @@ module Eggshell
90
95
  attr_reader :vars
91
96
 
92
97
  def expr_eval(struct)
93
- return Eggshell::ExpressionEvaluator.expr_eval(struct, @vars, @funcs)
98
+ return @ee.evaluate(struct)
94
99
  end
95
100
 
96
101
  # Expands expressions (`\${}`) and macro calls (`\@@macro\@@`).
@@ -135,7 +140,7 @@ module Eggshell
135
140
  struct = @expr_cache[expr_str]
136
141
 
137
142
  if !struct
138
- struct = Eggshell::ExpressionEvaluator.struct(expr_str)
143
+ struct = @ee.parse(expr_str)
139
144
  @expr_cache[expr_str] = struct
140
145
  end
141
146
 
@@ -188,41 +193,6 @@ module Eggshell
188
193
  TAB = "\t"
189
194
  TAB_SPACE = ' '
190
195
 
191
- # @param Boolean is_default If true, associates these parameters with the
192
- # `block_type` used in `get_block_param()` or explicitly in third parameter.
193
- # @param String block_type
194
- def set_block_params(params, is_default = false, block_type = nil)
195
- if block_type && is_default
196
- @block_params[block_type] = params
197
- else
198
- @block_params[:pending] = params
199
- @block_param_default = is_default
200
- end
201
- end
202
-
203
- # Gets the block parameters for a block type, and merges default values if available.
204
- def get_block_params(block_type)
205
- bp = @block_params.delete(:pending)
206
- if @block_params_default
207
- if block_type && bp
208
- @block_params[block_type] = bp if bp
209
- end
210
- @block_params_default = false
211
- bp = {} if !bp
212
- else
213
- bp = {} if !bp
214
- default = @block_params[block_type]
215
- if default
216
- default.each do |key,val|
217
- if !bp.has_key?(key) && val
218
- bp[key] = val.clone
219
- end
220
- end
221
- end
222
- end
223
- return bp
224
- end
225
-
226
196
  # Sets the default output object. Must support {{<<}} and {{join(String)}}.
227
197
  #
228
198
  # If {{out}} is a `Class`, must support empty initialization.
@@ -337,11 +307,18 @@ module Eggshell
337
307
  stat = parse_tree.collect(line_norm)
338
308
  next if stat != BH::RETRY
339
309
  parse_tree.push_block
310
+ elsif parse_tree.mode == :macro_raw
311
+ if !parse_tree.macro_delim_match(line_norm, line_count)
312
+ parse_tree.collect_macro_raw(line_norm)
313
+ end
314
+ next
340
315
  end
341
316
 
342
317
  # macro processing
343
318
  if line[0] == '@'
344
- parse_tree.new_macro(line_norm, line_count)
319
+ macro, args, delim = parse_macro_start(line)
320
+ mhandler = get_macro_handler(macro)
321
+ parse_tree.new_macro(line_norm, line_count, macro, args, delim, mhandler ? mhandler.collection_type(macro) : nil)
345
322
  next
346
323
  elsif parse_tree.macro_delim_match(line_norm, line_count)
347
324
  next
@@ -367,7 +344,7 @@ module Eggshell
367
344
  stat = handler.can_handle(line)
368
345
  next if stat == BH::RETRY
369
346
 
370
- parse_tree.new_block(handler, handler.current_type, line_norm, stat, line_count)
347
+ parse_tree.new_block(handler, handler.current_type, line_norm, stat, line_count, self)
371
348
  found = true
372
349
  _trace "(#{handler.current_type}->#{handler}) #{line} -> #{stat}"
373
350
  break
@@ -375,7 +352,7 @@ module Eggshell
375
352
 
376
353
  if !found
377
354
  @blocks_map['p'].can_handle('p.')
378
- parse_tree.new_block(@blocks_map['p'], 'p', line_norm, BH::COLLECT, line_count)
355
+ parse_tree.new_block(@blocks_map['p'], 'p', line_norm, BH::COLLECT, line_count, self)
379
356
  end
380
357
  end
381
358
  parse_tree.push_block
@@ -417,11 +394,11 @@ module Eggshell
417
394
  joiner = opts[:join] || "\n"
418
395
 
419
396
  parse_tree = parse_tree.tree if parse_tree.is_a?(Eggshell::ParseTree)
420
- raise Exception.new("input not an array or ParseTree (depth=#{call_depth}") if !parse_tree.is_a?(Array)
421
- # @todo defer process to next unit so macro can inject lines back into previous block
422
-
397
+ raise Exception.new("input not an array or ParseTree (depth=#{call_depth})") if !parse_tree.is_a?(Array)
398
+
423
399
  last_type = nil
424
400
  last_line = 0
401
+ last_macro = nil
425
402
  deferred = nil
426
403
 
427
404
  parse_tree.each do |unit|
@@ -445,13 +422,12 @@ module Eggshell
445
422
  args_o = unit[2] || []
446
423
  args = []
447
424
  args_o.each do |arg|
448
- args << expr_eval(arg)
425
+ args << (arg.is_a?(Array) ? @@ee.evaluate([:array, arg]) : arg)
449
426
  end
450
-
427
+
451
428
  lines = unit[ParseTree::IDX_LINES]
452
429
  lines_start = unit[ParseTree::IDX_LINES_START]
453
430
  lines_end = unit[ParseTree::IDX_LINES_END]
454
-
455
431
  _handler, _name, _args, _lines = deferred
456
432
 
457
433
  if unit[0] == :block
@@ -522,7 +498,7 @@ module Eggshell
522
498
 
523
499
  def process(lines, line_count = 0, call_depth = 0)
524
500
  parse_tree = preprocess(lines, line_count)
525
- assemble(parse_tree.tree, call_depth)
501
+ assemble(Eggshell::ParseTree.condense(self, parse_tree.tree), call_depth)
526
502
  end
527
503
 
528
504
  # Register inline format handlers with opening and closing tags.
@@ -612,21 +588,22 @@ module Eggshell
612
588
  buff.join('')
613
589
  end
614
590
 
615
- def self.parse_block_start(line)
591
+ def parse_block_start(line)
616
592
  block_type = nil
617
593
  args = []
618
594
 
619
595
  bt = line.match(BLOCK_MATCH_PARAMS)
620
596
  if bt
621
597
  idx0 = bt[0].length
622
- idx1 = line.index(').', idx0)
598
+ idx1 = line.index(')', idx0)
623
599
  if idx1
624
600
  block_type = line[0..idx0-2]
625
601
  params = line[0...idx1+1].strip
626
602
  line = line[idx1+2..line.length] || ''
627
603
  if params != ''
628
- struct = ExpressionEvaluator.struct(params)
604
+ struct = @ee.parse(params)
629
605
  args = struct[0][2]
606
+ #args = @ee.evaluate([[:array, struct[0][2]]])
630
607
  end
631
608
  end
632
609
  else
@@ -644,7 +621,7 @@ module Eggshell
644
621
  [block_type, args, line]
645
622
  end
646
623
 
647
- def self.parse_macro_start(line)
624
+ def parse_macro_start(line)
648
625
  macro = nil
649
626
  args = []
650
627
  delim = nil
@@ -652,11 +629,12 @@ module Eggshell
652
629
  # either macro is a plain '@macro' or it has parameters/opening brace
653
630
  if line.index(' ') || line.index('(') || line.index('{')
654
631
  # since the macro statement is essentially a function call, parse the line as an expression to get components
655
- expr_struct = ExpressionEvaluator.struct(line)
632
+ expr_struct = @ee.parse(line)
656
633
  fn = expr_struct.shift
657
- if fn.is_a?(Array) && (fn[0] == :fn || fn[0] == :var)
658
- macro = fn[1][1..fn[1].length]
659
- args = fn[2]
634
+
635
+ if fn.is_a?(Array) && (fn[0] == :func || fn[0] == :var)
636
+ macro = fn[1]
637
+ args = fn[2] # @@ee.evaluate([:array, fn[2]])
660
638
  if expr_struct[-1].is_a?(Array) && expr_struct[-1][0] == :brace_op
661
639
  delim = expr_struct[-1][1]
662
640
  end
@@ -0,0 +1,43 @@
1
+ # Interfaces and helper classes to have processor-friendly streams.
2
+ module Eggshell; module Stream;
3
+ def <<(str)
4
+ end
5
+
6
+ def join(str)
7
+ end
8
+
9
+ def write(str)
10
+ end
11
+
12
+ def [](index)
13
+ end
14
+
15
+ class IOWrapper
16
+ include Stream
17
+
18
+ def initialize(stream)
19
+ @stream = stream
20
+ @buff = []
21
+ end
22
+
23
+ def <<(str)
24
+ @buff << str
25
+ end
26
+
27
+ def write(str)
28
+ @stream.write(str)
29
+ end
30
+
31
+ def join(str)
32
+ @buff.join(str)
33
+ end
34
+
35
+ def [](index)
36
+ @buff[index]
37
+ end
38
+
39
+ def flush
40
+ @stream.write(@buff.join("\n"))
41
+ end
42
+ end
43
+ end; end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eggshell
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kaiser Shahid
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-20 00:00:00.000000000 Z
11
+ date: 2017-08-16 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: From fast and basic HTML to complex decouments and more, Eggshell aims
14
14
  to provide you with all the document generation power you need through simple markup.
@@ -22,15 +22,21 @@ files:
22
22
  - lib/eggshell/block-handler.rb
23
23
  - lib/eggshell/block.rb
24
24
  - lib/eggshell/bundles.rb
25
+ - lib/eggshell/bundles/basic-functions.rb
25
26
  - lib/eggshell/bundles/basics-old.rb
26
27
  - lib/eggshell/bundles/basics.rb
27
28
  - lib/eggshell/bundles/loader.rb
29
+ - lib/eggshell/compiler.rb
28
30
  - lib/eggshell/expression-evaluator.rb
31
+ - lib/eggshell/expression-evaluator/evaluator.rb
32
+ - lib/eggshell/expression-evaluator/lexer.rb
33
+ - lib/eggshell/expression-evaluator/parser.rb
29
34
  - lib/eggshell/format-handler.rb
30
35
  - lib/eggshell/macro-handler.rb
31
36
  - lib/eggshell/parse-tree.rb
32
37
  - lib/eggshell/processor-context.rb
33
38
  - lib/eggshell/processor.rb
39
+ - lib/eggshell/stream.rb
34
40
  homepage: https://acmedinotech.com/products/eggshell
35
41
  licenses:
36
42
  - MIT