livetext 0.9.10 → 0.9.15

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.
Files changed (177) hide show
  1. checksums.yaml +4 -4
  2. data/lib/cmdargs.rb +93 -0
  3. data/lib/errors.rb +15 -0
  4. data/lib/formatline.rb +59 -88
  5. data/lib/functions.rb +6 -2
  6. data/lib/helpers.rb +163 -0
  7. data/lib/html.rb +32 -0
  8. data/lib/livetext/importable.rb +2 -0
  9. data/lib/livetext.rb +30 -148
  10. data/lib/parser/file.rb +8 -0
  11. data/lib/parser/general.rb +38 -0
  12. data/lib/parser/import.rb +17 -0
  13. data/lib/parser/mixin.rb +53 -0
  14. data/lib/parser/set.rb +145 -0
  15. data/lib/parser/string.rb +70 -0
  16. data/lib/parser.rb +5 -0
  17. data/lib/processor.rb +23 -27
  18. data/lib/standard.rb +155 -348
  19. data/lib/userapi.rb +2 -5
  20. data/livetext.gemspec +1 -2
  21. data/plugin/bookish.rb +26 -22
  22. data/plugin/calibre.rb +1 -1
  23. data/plugin/livemagick.rb +10 -10
  24. data/plugin/markdown.rb +13 -11
  25. data/plugin/pyggish.rb +94 -84
  26. data/plugin/tutorial.rb +10 -5
  27. data/test/all.rb +3 -0
  28. data/test/snapshots/OMIT.txt +9 -0
  29. data/test/{data → snapshots}/basic_formatting/expected-error.txt +0 -0
  30. data/test/{data → snapshots}/basic_formatting/expected-output.txt +0 -0
  31. data/test/{data → snapshots}/basic_formatting/source.lt3 +0 -0
  32. data/test/{data → snapshots}/block_comment/expected-error.txt +0 -0
  33. data/test/{data → snapshots}/block_comment/expected-output.txt +0 -0
  34. data/test/{data → snapshots}/block_comment/source.lt3 +0 -0
  35. data/test/snapshots/clusion.txt +35 -0
  36. data/test/{data → snapshots}/comments_ignored_1/expected-error.txt +0 -0
  37. data/test/{data → snapshots}/comments_ignored_1/expected-output.txt +0 -0
  38. data/test/{data → snapshots}/comments_ignored_1/source.lt3 +0 -0
  39. data/test/{data → snapshots}/copy_is_raw/expected-error.txt +0 -0
  40. data/test/{data → snapshots}/copy_is_raw/expected-output.txt +0 -0
  41. data/test/{data → snapshots}/copy_is_raw/rawtext.inc +0 -0
  42. data/test/{data → snapshots}/copy_is_raw/source.lt3 +0 -0
  43. data/test/{data → snapshots}/crap +0 -0
  44. data/test/{data → snapshots}/def_method/expected-error.txt +0 -0
  45. data/test/{data → snapshots}/def_method/expected-output.txt +0 -0
  46. data/test/{data → snapshots}/def_method/source.lt3 +0 -0
  47. data/test/snapshots/error_inc_line_num/actual-error.txt +14 -0
  48. data/test/{data/error_inc_line_num/expected-output.txt → snapshots/error_inc_line_num/actual-output.txt} +0 -0
  49. data/test/snapshots/error_inc_line_num/expected-output.txt +13 -0
  50. data/test/{data → snapshots}/error_inc_line_num/file2.lt3 +0 -0
  51. data/test/snapshots/error_inc_line_num/match-error.txt +1 -0
  52. data/test/snapshots/error_inc_line_num/out-sdiff.txt +14 -0
  53. data/test/{data → snapshots}/error_inc_line_num/source.lt3 +0 -0
  54. data/test/snapshots/error_invalid_name/actual-error.txt +10 -0
  55. data/test/{data/error_no_such_mixin/expected-output.txt → snapshots/error_invalid_name/actual-output.txt} +0 -0
  56. data/test/{data → snapshots}/error_invalid_name/expected-output.txt +0 -0
  57. data/test/snapshots/error_invalid_name/match-error.txt +1 -0
  58. data/test/snapshots/error_invalid_name/out-sdiff.txt +6 -0
  59. data/test/{data → snapshots}/error_invalid_name/source.lt3 +0 -0
  60. data/test/{data → snapshots}/error_line_num/expected-output.txt +0 -0
  61. data/test/snapshots/error_line_num/match-error.txt +1 -0
  62. data/test/{data → snapshots}/error_line_num/source.lt3 +0 -0
  63. data/test/{data → snapshots}/error_mismatched_end/expected-output.txt +0 -0
  64. data/test/snapshots/error_mismatched_end/match-error.txt +1 -0
  65. data/test/{data → snapshots}/error_mismatched_end/source.lt3 +0 -0
  66. data/test/snapshots/error_missing_end/actual-error.txt +10 -0
  67. data/test/{data/example_alpha/expected-error.txt → snapshots/error_missing_end/actual-output.txt} +0 -0
  68. data/test/{data → snapshots}/error_missing_end/expected-output.txt +1 -0
  69. data/test/snapshots/error_missing_end/match-error.txt +1 -0
  70. data/test/snapshots/error_missing_end/out-sdiff.txt +6 -0
  71. data/test/{data → snapshots}/error_missing_end/source.lt3 +0 -0
  72. data/test/{data/example_alpha2/expected-error.txt → snapshots/error_name_not_permitted/expected-output.txt} +0 -0
  73. data/test/snapshots/error_name_not_permitted/match-error.txt +1 -0
  74. data/test/{data → snapshots}/error_name_not_permitted/source.lt3 +0 -0
  75. data/test/snapshots/error_no_such_copy/actual-error.txt +10 -0
  76. data/test/{data/functions/expected-error.txt → snapshots/error_no_such_copy/actual-output.txt} +0 -0
  77. data/test/{data → snapshots}/error_no_such_copy/expected-output.txt +0 -1
  78. data/test/snapshots/error_no_such_copy/match-error.txt +1 -0
  79. data/test/snapshots/error_no_such_copy/out-sdiff.txt +5 -0
  80. data/test/{data → snapshots}/error_no_such_copy/source.lt3 +0 -0
  81. data/test/snapshots/error_no_such_inc/actual-error.txt +10 -0
  82. data/test/{data/hello_world/expected-error.txt → snapshots/error_no_such_inc/actual-output.txt} +0 -0
  83. data/test/{data → snapshots}/error_no_such_inc/expected-output.txt +0 -0
  84. data/test/snapshots/error_no_such_inc/match-error.txt +1 -0
  85. data/test/snapshots/error_no_such_inc/out-sdiff.txt +6 -0
  86. data/test/{data → snapshots}/error_no_such_inc/source.lt3 +0 -0
  87. data/test/snapshots/error_no_such_mixin/actual-error.txt +37 -0
  88. data/test/{data/more_complex_vars/expected-error.txt → snapshots/error_no_such_mixin/actual-output.txt} +0 -0
  89. data/test/snapshots/error_no_such_mixin/expected-output.txt +5 -0
  90. data/test/snapshots/error_no_such_mixin/match-error.txt +1 -0
  91. data/test/snapshots/error_no_such_mixin/out-sdiff.txt +6 -0
  92. data/test/{data → snapshots}/error_no_such_mixin/source.lt3 +0 -0
  93. data/test/{data/raw_lines → snapshots/example_alpha}/expected-error.txt +0 -0
  94. data/test/{data → snapshots}/example_alpha/expected-output.txt +0 -0
  95. data/test/{data → snapshots}/example_alpha/source.lt3 +0 -0
  96. data/test/{data/raw_text_block → snapshots/example_alpha2}/expected-error.txt +0 -0
  97. data/test/{data → snapshots}/example_alpha2/expected-output.txt +0 -0
  98. data/test/{data → snapshots}/example_alpha2/source.lt3 +0 -0
  99. data/test/{data → snapshots}/fixit +0 -0
  100. data/test/{data/simple_copy → snapshots/functions}/expected-error.txt +0 -0
  101. data/test/{data → snapshots}/functions/expected-output.txt +0 -0
  102. data/test/{data → snapshots}/functions/source.lt3 +0 -0
  103. data/test/{data/simple_include → snapshots/hello_world}/expected-error.txt +0 -0
  104. data/test/{data → snapshots}/hello_world/expected-output.txt +0 -0
  105. data/test/{data → snapshots}/hello_world/source.lt3 +0 -0
  106. data/test/{data/simple_mixin → snapshots/more_complex_vars}/expected-error.txt +0 -0
  107. data/test/{data → snapshots}/more_complex_vars/expected-output.txt +0 -0
  108. data/test/{data → snapshots}/more_complex_vars/source.lt3 +0 -0
  109. data/test/{data/simple_vars → snapshots/predef_vars}/expected-error.txt +0 -0
  110. data/test/snapshots/predef_vars/match-output.txt +6 -0
  111. data/test/snapshots/predef_vars/source.lt3 +6 -0
  112. data/test/{data/single_raw_line → snapshots/raw_lines}/expected-error.txt +0 -0
  113. data/test/{data → snapshots}/raw_lines/expected-output.txt +0 -0
  114. data/test/{data → snapshots}/raw_lines/source.lt3 +0 -0
  115. data/test/{data/table_with_heredocs → snapshots/raw_text_block}/expected-error.txt +0 -0
  116. data/test/{data → snapshots}/raw_text_block/expected-output.txt +0 -0
  117. data/test/{data → snapshots}/raw_text_block/rawtext.inc +0 -0
  118. data/test/{data → snapshots}/raw_text_block/source.lt3 +0 -0
  119. data/test/{data/subset.txt → snapshots/simple_copy/expected-error.txt} +0 -0
  120. data/test/{data → snapshots}/simple_copy/expected-output.txt +0 -0
  121. data/test/{data → snapshots}/simple_copy/simplefile.inc +0 -0
  122. data/test/{data → snapshots}/simple_copy/source.lt3 +0 -0
  123. data/test/snapshots/simple_import/actual-error.txt +8 -0
  124. data/test/snapshots/simple_import/actual-output.txt +3 -0
  125. data/test/snapshots/simple_import/err-sdiff.txt +9 -0
  126. data/test/snapshots/simple_import/expected-error.txt +0 -0
  127. data/test/snapshots/simple_import/expected-output.txt +7 -0
  128. data/test/snapshots/simple_import/out-sdiff.txt +9 -0
  129. data/test/snapshots/simple_import/simple_import.rb +5 -0
  130. data/test/snapshots/simple_import/source.lt3 +7 -0
  131. data/test/snapshots/simple_include/expected-error.txt +0 -0
  132. data/test/{data → snapshots}/simple_include/expected-output.txt +0 -0
  133. data/test/{data → snapshots}/simple_include/simplefile.inc +0 -0
  134. data/test/{data → snapshots}/simple_include/source.lt3 +0 -1
  135. data/test/snapshots/simple_mixin/expected-error.txt +0 -0
  136. data/test/{data → snapshots}/simple_mixin/expected-output.txt +0 -0
  137. data/test/{data → snapshots}/simple_mixin/simple_mixin.rb +0 -0
  138. data/test/{data → snapshots}/simple_mixin/source.lt3 +0 -0
  139. data/test/snapshots/simple_vars/expected-error.txt +0 -0
  140. data/test/{data → snapshots}/simple_vars/expected-output.txt +0 -0
  141. data/test/{data → snapshots}/simple_vars/source.lt3 +0 -0
  142. data/test/snapshots/single_raw_line/expected-error.txt +0 -0
  143. data/test/{data → snapshots}/single_raw_line/expected-output.txt +0 -0
  144. data/test/{data → snapshots}/single_raw_line/source.lt3 +0 -0
  145. data/test/snapshots/subset.txt +0 -0
  146. data/test/snapshots/table_with_heredocs/expected-error.txt +0 -0
  147. data/test/{data → snapshots}/table_with_heredocs/expected-output.txt +0 -0
  148. data/test/{data → snapshots}/table_with_heredocs/source.lt3 +0 -0
  149. data/test/snapshots.rb +169 -0
  150. data/test/testlines.rb +17 -7
  151. data/test/unit/all.rb +4 -0
  152. data/test/unit/formatline.rb +650 -0
  153. data/test/unit/html.rb +38 -0
  154. data/test/unit/parser/all.rb +3 -0
  155. data/test/unit/parser/general.rb +59 -0
  156. data/test/unit/parser/importable.rb +19 -0
  157. data/test/unit/parser/mixin.rb +19 -0
  158. data/test/unit/parser/set.rb +164 -0
  159. data/test/unit/parser/string.rb +130 -0
  160. data/test/unit/parser.rb +6 -0
  161. data/test/unit/standard.rb +23 -0
  162. data/test/unit/stringparser.rb +140 -0
  163. metadata +150 -97
  164. data/test/data/error_inc_line_num/expected-err-line1match.txt +0 -1
  165. data/test/data/error_invalid_name/expected-err-line1match.txt +0 -1
  166. data/test/data/error_line_num/expected-err-line1match.txt +0 -1
  167. data/test/data/error_mismatched_end/expected-err-line1match.txt +0 -1
  168. data/test/data/error_missing_end/expected-err-line1match.txt +0 -1
  169. data/test/data/error_name_not_permitted/expected-error.txt +0 -1
  170. data/test/data/error_name_not_permitted/expected-output.txt +0 -4
  171. data/test/data/error_no_such_copy/expected-err-line1match.txt +0 -1
  172. data/test/data/error_no_such_inc/expected-err-line1match.txt +0 -1
  173. data/test/data/error_no_such_mixin/expected-err-line1match.txt +0 -1
  174. data/test/data/lines.txt +0 -120
  175. data/test/extratests.txt +0 -20
  176. data/test/formatting.rb +0 -110
  177. data/test/test.rb +0 -140
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 67d6ad974fae59754a4bf3d6c306e01a9028b8d5f0d86968fa2a3de5fbf97018
4
- data.tar.gz: d250929b203dbfe8bdec044b31abebfe6f7244e2dd19376b876c0daf2634b730
3
+ metadata.gz: a8d345a0f52ce0d7c62f40f8798793faf5136f8ce72cde8576a0284220c08082
4
+ data.tar.gz: 4e037527c3abd873c9cf8ca49685d99c68fffab9630a67c1193e898e961c4d48
5
5
  SHA512:
6
- metadata.gz: 20dfdad9784ef0bab8439b63d2dccac59f21a27ae57c178c8961bc5414a9dc87af4e78b0d7b5d2b61ca9809715e6fa6e1ee0cf6f8e9091053f724be3d1b7d505
7
- data.tar.gz: 7a8cc51ccf632a8ec43ee06669f54c39276e5d88fbeb990e4c2d23c33993eb308e83ae3aa5213a054d5e868cb5617eab2632cb480764ece197192d03f0a75618
6
+ metadata.gz: 5b2957b2fe57d0abeff6029c63e310b7d26d653e1e7848c4026d2c16f43e6c37f6c9bf2fb63f2dfcd4e719cc82113cf549413362da43c14ac12312cafad1a744
7
+ data.tar.gz: 696a9ff22bff7caae99534e1a9431e9914e9137be4212674598c2ee66a58c11bd37c56bc90c52dd0d0cae3450f8905081202fbdc08f05a6164abd2de2dc5e7ce
data/lib/cmdargs.rb ADDED
@@ -0,0 +1,93 @@
1
+ require_relative 'livetext'
2
+
3
+ =begin
4
+ Weird concepts to understand here...
5
+
6
+ 1. A Livetext dot-command (flush left) usually looks like:
7
+ .foobar
8
+ 2. A dot-command (left-indented) usually looks like:
9
+ $.foobar
10
+ 3. More generally, it may have any number of parameters (0, 1, ...)
11
+ .redirect somefile.txt append
12
+ 4. Variables and functions *can* appear (rare in practice??)
13
+ .redirect somefile$my_suffix $$my_mode
14
+ 5. A trailing # comment may appear
15
+ a. Stripped... saved in #raw ? #data ? #comment ? elsewhere?
16
+ b. NOT the "dot" as a comment!
17
+ 6. .foobar # This here is a comment
18
+ 7. #data accessor returns all data on the .foo line...
19
+ a. ...After the initial space
20
+ b. ...Including spaces
21
+ c. Including comment??
22
+ d. .foo This is o n l y a test.
23
+ # #data returns: "This is o n l y a test."
24
+ e. What about formatting???
25
+ f. What about: comments? variables? functions?
26
+
27
+ 7. Some commands have NO body while others have an OPTIONAL or REQUIRED body
28
+ a. Assume .cmd1 definition forbids a body (then a body is an error)
29
+ .cmd1 # may NOT have a body
30
+ b. Assume .cmd2 definition PERMITS a body
31
+ .cmd2 # may or MAY NOT have body/.end
32
+ c. Assume .cmd3 definition PERMITS a body
33
+ .cmd3 # REQUIRES a body/.end
34
+ . stuff...
35
+ .end
36
+ 8. Inside a body:
37
+ 8a. Leading dot has no special meaning (though the associated method may parse it!)
38
+ 8b. BUG? Currently leading dot is a comment INSIDE a body?
39
+ 8a. No leading char is special (though the associated method may parse it!)
40
+ 8a. No trailing #-comments (though the associated method may parse it!)
41
+ 8c. ?? We should or shouldn't look for variables/functions? or make it an option?
42
+ 8d. .end may naturally not be used (but see .raw where it may)
43
+ 9. the args accessor is a simple array of strings
44
+
45
+
46
+ =end
47
+
48
+ class Livetext::CmdData
49
+
50
+ attr_reader :data, :args, :nargs, :arity, :comment, :raw # , ...?
51
+
52
+ def initialize(data, body: false, arity: :N) # FIXME maybe just add **options ??
53
+ # arity: (num) fixed number 0 or more
54
+ # :N arbitrary number
55
+ # n1..n2 range
56
+ # body: true => this command has a body + .end
57
+ # how raw is raw?
58
+ # remove comment - always/sometimes/never?
59
+ # var_func_parse - always/sometimes/never?
60
+ # var_func_parse inside body??
61
+ @data = data.dup # comment? vars? funcs?
62
+ @raw = data.dup # comment? vars? funcs?
63
+ @args = data.split # simple array
64
+ @nargs = nargs # not really "needed"
65
+ check_num_args(nargs)
66
+
67
+ # @varfunc = _var_func_parse(data.dup)
68
+ end
69
+
70
+ def check_num_args(num)
71
+ num_range = /(\d{0,2})(\.\.)(\d{0,2})/
72
+ min, max = 0, 9999
73
+ md = num_range.match(@nargs).to_a
74
+ bad_args = nil
75
+ case
76
+ when @nargs == ":N" # arbitrary
77
+ # max already set
78
+ when md[2] == ".." # range: 4..6 1.. ..4
79
+ vmin, vmax = md.values_at(1, 2)
80
+ min = Integer(vmin) unless vmin.empty?
81
+ max = Integer(vmax) unless vmax.empty?
82
+ min, max = Integer(min), Integer(max)
83
+ when %r[^\d+$] =~ num
84
+ min = max = Integer(num) # can raise error
85
+ else
86
+ raise "Invalid value or range '#{num.inspect}'"
87
+ end
88
+
89
+ bad_args = @args.size.between?(min, max)
90
+ raise "Expected #{num} args but found #{@args.size}!" if bad_args
91
+ end
92
+
93
+ end
data/lib/errors.rb ADDED
@@ -0,0 +1,15 @@
1
+
2
+ # More later?
3
+
4
+ def make_exception(sym, str, target_class = Object)
5
+ return if target_class.constants.include?(sym)
6
+ klass = sym # :"#{sym}_Class"
7
+ target_class.const_set(klass, StandardError.dup)
8
+ define_method(sym) do |*args|
9
+ args = [] unless args.first
10
+ msg = str.dup
11
+ args.each.with_index {|arg, i| msg.sub!("%#{i+1}", arg) }
12
+ target_class.class_eval(klass.to_s).new(msg)
13
+ end
14
+ end
15
+
data/lib/formatline.rb CHANGED
@@ -1,4 +1,7 @@
1
- class FormatLine
1
+ # Class FormatLine handles the parsing of comments, dot commands, and
2
+ # simple formatting characters.
3
+
4
+ class FormatLine < StringParser
2
5
  SimpleFormats = {}
3
6
  SimpleFormats[:b] = %w[<b> </b>]
4
7
  SimpleFormats[:i] = %w[<i> </i>]
@@ -21,20 +24,11 @@ class FormatLine
21
24
 
22
25
  Syms = { "*" => :b, "_" => :i, "`" => :t, "~" => :s }
23
26
 
24
- def terminate?(terminators, ch)
25
- if terminators.is_a? Regexp
26
- terminators === ch
27
- else
28
- terminators.include?(ch)
29
- end
30
- end
31
-
32
27
  attr_reader :out
33
28
  attr_reader :tokenlist
34
29
 
35
30
  def initialize(line)
36
- @line = line
37
- @i = -1
31
+ super
38
32
  @token = Null.dup
39
33
  @tokenlist = []
40
34
  end
@@ -42,26 +36,27 @@ class FormatLine
42
36
  def self.parse!(line)
43
37
  return nil if line.nil?
44
38
  x = self.new(line.chomp)
45
- t = x.tokenize(line)
39
+ t = x.tokenize
40
+ # TTY.puts "tokens = \n#{t.inspect}\n "
46
41
  x.evaluate
47
42
  end
48
43
 
49
- def tokenize(line)
50
- grab
44
+ def tokenize
45
+ # add grab
51
46
  loop do
52
- case curr
53
- when Escape; grab; add curr; grab; add curr
47
+ case peek
48
+ when Escape; grab; add peek; grab; add peek
54
49
  when "$"
55
50
  dollar
56
51
  when "*", "_", "`", "~"
57
- marker curr
58
- add curr
52
+ marker peek
53
+ add peek
59
54
  when LF
60
55
  break if @i >= line.size - 1
61
56
  when nil
62
57
  break
63
58
  else
64
- add curr
59
+ add peek
65
60
  end
66
61
  grab
67
62
  end
@@ -69,24 +64,33 @@ class FormatLine
69
64
  @tokenlist
70
65
  end
71
66
 
67
+ def terminate?(terminators, ch)
68
+ if terminators.is_a? Regexp
69
+ terminators === ch
70
+ else
71
+ terminators.include?(ch)
72
+ end
73
+ end
74
+
72
75
  def self.var_func_parse(str)
73
76
  return nil if str.nil?
74
77
  x = self.new(str.chomp)
75
- x.grab
76
- loop do
77
- case x.curr
78
- when Escape; x.grab; x.add x.curr; x.grab
79
- when "$"
80
- x.dollar
81
- when LF, nil
82
- break
83
- else
84
- x.add x.curr
85
- end
86
- x.grab
78
+ char = x.peek
79
+ loop do
80
+ char = x.grab
81
+ break if char == LF || char == nil
82
+ x.handle_escaping if char == Escape
83
+ x.dollar if char == "$"
84
+ x.add char
87
85
  end
88
86
  x.add_token(:str)
89
- x.evaluate
87
+ result = x.evaluate
88
+ result
89
+ end
90
+
91
+ def handle_escaping
92
+ grab
93
+ add grab
90
94
  end
91
95
 
92
96
  def embed(sym, str)
@@ -127,27 +131,6 @@ class FormatLine
127
131
  @out
128
132
  end
129
133
 
130
- def curr
131
- @line[@i]
132
- end
133
-
134
- def prev
135
- return nil if @i <= 0
136
- @line[@i-1]
137
- end
138
-
139
- def next!
140
- @line[@i+1]
141
- end
142
-
143
- def grab
144
- @line[@i+=1]
145
- end
146
-
147
- def ungrab
148
- @line[@i-=1]
149
- end
150
-
151
134
  def grab_colon_param
152
135
  grab # grab :
153
136
  param = ""
@@ -184,7 +167,7 @@ class FormatLine
184
167
  end
185
168
  end
186
169
 
187
- add curr
170
+ add peek
188
171
  grab
189
172
  param = nil if param.empty?
190
173
  param
@@ -204,8 +187,8 @@ class FormatLine
204
187
  str = Null.dup
205
188
  grab
206
189
  loop do
207
- break if curr.nil?
208
- str << curr
190
+ break if eos?
191
+ str << peek
209
192
  break if terminate?(NoAlpha, next!)
210
193
  grab
211
194
  end
@@ -216,8 +199,8 @@ class FormatLine
216
199
  str = Null.dup
217
200
  grab
218
201
  loop do
219
- break if curr.nil?
220
- str << curr
202
+ break if eos? # peek.nil?
203
+ str << peek
221
204
  break if terminate?(NoAlphaDot, next!)
222
205
  grab
223
206
  end
@@ -226,7 +209,7 @@ class FormatLine
226
209
 
227
210
  def dollar
228
211
  grab
229
- case curr
212
+ case peek
230
213
  when LF; add "$"; add_token :str
231
214
  when " "; add "$ "; add_token :str
232
215
  when nil; add "$"; add_token :str
@@ -234,10 +217,10 @@ class FormatLine
234
217
  # when "."; dollar_dot
235
218
  when /[A-Za-z]/
236
219
  add_token :str
237
- var = curr + grab_alpha_dot
220
+ var = peek + grab_alpha_dot
238
221
  add_token(:var, var)
239
222
  else
240
- add "$" + curr
223
+ add "$" + peek
241
224
  add_token(:string)
242
225
  end
243
226
  end
@@ -255,7 +238,7 @@ class FormatLine
255
238
  when "["; param = grab_func_param; add_token(:brackets, param)
256
239
  end
257
240
  else
258
- grab; add_token :str, "$$" + curr; return
241
+ grab; add_token :str, "$$" + peek; return
259
242
  end
260
243
  end
261
244
 
@@ -272,7 +255,7 @@ class FormatLine
272
255
  end
273
256
 
274
257
  grab
275
- case curr
258
+ case peek
276
259
  when Space
277
260
  add char + " "
278
261
  add_token :str
@@ -283,7 +266,7 @@ class FormatLine
283
266
  when char; double_marker(char)
284
267
  when LBrack; long_marker(char)
285
268
  else
286
- str = curr + collect!(sym, Blank)
269
+ str = peek + collect!(sym, Blank)
287
270
  add str
288
271
  add_token sym, str
289
272
  grab
@@ -316,21 +299,19 @@ class FormatLine
316
299
  str = Null.dup # next is not " ","*","["
317
300
  grab # ZZZ
318
301
  loop do
319
- if curr == Escape
320
- str << grab # ch = escaped char
302
+ if peek == Escape
321
303
  grab
304
+ str << grab
322
305
  next
323
306
  end
324
- if terminate?(terminators, curr)
307
+ if terminate?(terminators, peek)
325
308
  break
326
309
  end
327
- # STDERR.puts "#{curr.inspect} is not a terminator"
328
- str << curr # not a terminator
310
+ str << peek # not a terminator
329
311
  grab
330
- # STDERR.puts "After grab, curr is #{curr.inspect}"
331
312
  end
332
313
 
333
- if curr == "]" # skip right bracket
314
+ if peek == "]" # skip right bracket
334
315
  grab
335
316
  end
336
317
  add str
@@ -341,8 +322,8 @@ class FormatLine
341
322
  end
342
323
 
343
324
  def escaped
344
- ch = grab
345
325
  grab
326
+ ch = grab
346
327
  ch
347
328
  end
348
329
 
@@ -353,15 +334,15 @@ class FormatLine
353
334
  grab # ZZZ
354
335
  loop do
355
336
  case
356
- when curr.nil?
337
+ when peek.nil?
357
338
  return str
358
- when curr == Escape
339
+ when peek == Escape
359
340
  str << escaped
360
341
  next
361
- when terminate?(terminators, curr)
342
+ when terminate?(terminators, peek)
362
343
  break
363
344
  else
364
- str << curr # not a terminator
345
+ str << peek # not a terminator
365
346
  end
366
347
  grab
367
348
  end
@@ -373,17 +354,14 @@ class FormatLine
373
354
  STDERR.puts "=== str = #{str.inspect}"
374
355
  end
375
356
 
376
- ############
377
-
378
- ### From FormatLine:
379
-
380
357
  def funcall(name, param)
358
+ err = "[Error evaluating $$#{name}(#{param})]"
381
359
  result =
382
360
  if self.respond_to?("func_" + name.to_s)
383
361
  self.send("func_" + name.to_s, param)
384
362
  else
385
363
  fobj = ::Livetext::Functions.new
386
- fobj.send(name, param)
364
+ fobj.send(name, param) rescue err
387
365
  end
388
366
  result
389
367
  end
@@ -393,13 +371,6 @@ class FormatLine
393
371
  result
394
372
  end
395
373
 
396
- #####
397
-
398
- def showme(tag)
399
- char = @line[@cc]
400
- puts "--- #{tag}: ch=#{@ch.inspect} next=#{@next.inspect} (cc=#@cc:#{char.inspect}) out=#{@out.inspect}"
401
- end
402
-
403
374
  def embedded?
404
375
  ! (['"', "'", " ", nil].include? prev)
405
376
  end
data/lib/functions.rb CHANGED
@@ -1,6 +1,10 @@
1
- require 'standard' # FIXME
2
1
 
3
- class Livetext::Functions # Functions will go here... user-def AND pre-def??
2
+ require_relative 'standard' # FIXME umm, why is this necessary??
3
+
4
+ # Class Functions is where '$$func' functions are stored dynamically...
5
+ # user-def AND pre-def??
6
+
7
+ class Livetext::Functions
4
8
  Formats = ::Livetext::Standard::SimpleFormats
5
9
 
6
10
  @param = nil
data/lib/helpers.rb ADDED
@@ -0,0 +1,163 @@
1
+
2
+ module Helpers
3
+
4
+ Space = " "
5
+ Sigil = "." # Can't change yet
6
+
7
+ def self.rx(str, space=nil)
8
+ Regexp.compile("^" + Regexp.escape(str) + "#{space}")
9
+ end
10
+
11
+ Comment = rx(Sigil, Space)
12
+ Dotcmd = rx(Sigil)
13
+ Ddotcmd = /^ *\$\.[A-Za-z]/
14
+
15
+ ## FIXME process_file[!] should call process[_text]
16
+
17
+ def process_file(fname, btrace=false)
18
+ setfile(fname)
19
+ text = File.readlines(fname)
20
+ enum = text.each
21
+ @backtrace = btrace
22
+ @main.source(enum, fname, 0)
23
+ line = nil
24
+ loop do
25
+ line = @main.nextline
26
+ break if line.nil?
27
+ process_line(line)
28
+ end
29
+ val = @main.finalize if @main.respond_to? :finalize
30
+ @body
31
+ end
32
+
33
+ def process_line(line) # FIXME inefficient?
34
+ nomarkup = true
35
+ case line # must apply these in order
36
+ when Comment
37
+ handle_scomment(line)
38
+ when Dotcmd
39
+ handle_dotcmd(line)
40
+ when Ddotcmd
41
+ indent = line.index("$") + 1
42
+ @indentation.push(indent)
43
+ line.sub!(/^ *\$/, "")
44
+ handle_dotcmd(line)
45
+ indentation.pop
46
+ else
47
+ @main._passthru(line)
48
+ end
49
+ end
50
+
51
+ def handle_dotcmd(line, indent = 0)
52
+ indent = @indentation.last # top of stack
53
+ line = line.sub(/# .*$/, "")
54
+ name = get_name(line).to_sym
55
+ result = nil
56
+ case
57
+ when name == :end # special case
58
+ puts @body
59
+ raise EndWithoutOpening()
60
+ when @main.respond_to?(name)
61
+ result = @main.send(name)
62
+ else
63
+ puts @body # earlier correct output, not flushed yet
64
+ raise "Name '#{name}' is unknown"
65
+ return
66
+ end
67
+ result
68
+ end
69
+
70
+ def handle_scomment(line)
71
+ end
72
+
73
+ def get_name(line)
74
+ name, data = line.split(" ", 2)
75
+ name = name[1..-1] # chop off sigil
76
+ name = "dot_" + name if %w[include def].include?(name)
77
+ @main.data = data
78
+ @main.check_disallowed(name)
79
+ name
80
+ end
81
+
82
+ def check_disallowed(name)
83
+ raise DisallowedName(name) if disallowed?(name)
84
+ end
85
+
86
+ def check_file_exists(file)
87
+ raise FileNotFound(file) unless File.exist?(file)
88
+ end
89
+
90
+ def set_variables(pairs)
91
+ pairs.each do |pair|
92
+ var, value = *pair
93
+ @parent.setvar(var, value)
94
+ end
95
+ end
96
+
97
+ def grab_file(fname)
98
+ File.read(fname)
99
+ end
100
+
101
+ def search_upward(file)
102
+ value = nil
103
+ return file if File.exist?(file)
104
+
105
+ count = 1
106
+ loop do
107
+ front = "../" * count
108
+ count += 1
109
+ here = Pathname.new(front).expand_path.dirname.to_s
110
+ break if here == "/"
111
+ path = front + file
112
+ value = path if File.exist?(path)
113
+ break if value
114
+ end
115
+ STDERR.puts "Cannot find #{file.inspect} from #{Dir.pwd}" unless value
116
+ return value
117
+ rescue
118
+ STDERR.puts "Can't find #{file.inspect} from #{Dir.pwd}"
119
+ return nil
120
+ end
121
+
122
+ def include_file(file)
123
+ @_args = [file]
124
+ dot_include
125
+ end
126
+
127
+ def onoff(arg) # helper
128
+ arg ||= "on"
129
+ raise ExpectedOnOff unless String === arg
130
+ case arg.downcase
131
+ when "on"
132
+ return true
133
+ when "off"
134
+ return false
135
+ else
136
+ raise ExpectedOnOff
137
+ end
138
+ end
139
+
140
+ def setvar(var, val)
141
+ str, sym = var.to_s, var.to_sym
142
+ Livetext::Vars[str] = val
143
+ Livetext::Vars[sym] = val
144
+ @_vars[str] = val
145
+ @_vars[sym] = val
146
+ end
147
+
148
+ def setfile(file)
149
+ if file
150
+ setvar(:File, file)
151
+ dir = File.dirname(File.expand_path(file))
152
+ setvar(:FileDir, dir)
153
+ else
154
+ setvar(:File, "[no file]")
155
+ setvar(:FileDir, "[no dir]")
156
+ end
157
+ end
158
+
159
+ def setfile!(file) # FIXME why does this variant exist?
160
+ setvar(:File, file)
161
+ end
162
+
163
+ end
data/lib/html.rb ADDED
@@ -0,0 +1,32 @@
1
+ module HTMLHelper
2
+
3
+ def wrapped(str, *tags) # helper
4
+ open, close = open_close_tags(*tags)
5
+ open + str + close
6
+ end
7
+
8
+ def wrapped!(str, tag, **extras) # helper
9
+ open, close = open_close_tags(tag)
10
+ extras.each_pair do |name, value|
11
+ open.sub!(">", " #{name}='#{value}'>")
12
+ end
13
+ open + str + close
14
+ end
15
+
16
+ def wrap(*tags) # helper
17
+ open, close = open_close_tags(*tags)
18
+ _out open
19
+ yield
20
+ _out close
21
+ end
22
+
23
+ def open_close_tags(*tags)
24
+ open, close = "", ""
25
+ tags.each do |tag|
26
+ open << "<#{tag}>"
27
+ close.prepend("</#{tag}>")
28
+ end
29
+ [open, close]
30
+ end
31
+
32
+ end
@@ -0,0 +1,2 @@
1
+ class LiveText::Importable
2
+ end