livetext 0.9.08 → 0.9.13

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 (167) hide show
  1. checksums.yaml +4 -4
  2. data/bin/livetext +0 -1
  3. data/lib/errors.rb +13 -0
  4. data/lib/formatline.rb +3 -5
  5. data/lib/functions.rb +6 -2
  6. data/lib/helpers.rb +21 -0
  7. data/lib/html.rb +32 -0
  8. data/lib/livetext/importable.rb +2 -0
  9. data/lib/livetext.rb +52 -46
  10. data/lib/parser/general.rb +38 -0
  11. data/lib/parser/import.rb +17 -0
  12. data/lib/parser/mixin.rb +46 -0
  13. data/lib/parser/set.rb +136 -0
  14. data/lib/parser/string.rb +55 -0
  15. data/lib/parser.rb +5 -0
  16. data/lib/processor.rb +26 -18
  17. data/lib/standard.rb +145 -292
  18. data/lib/userapi.rb +6 -5
  19. data/livetext.gemspec +1 -2
  20. data/test/all.rb +3 -0
  21. data/test/formatting.rb +2 -9
  22. data/test/{data → snapshots}/basic_formatting/expected-error.txt +0 -0
  23. data/test/{data → snapshots}/basic_formatting/expected-output.txt +0 -0
  24. data/test/{data → snapshots}/basic_formatting/source.lt3 +0 -0
  25. data/test/{data → snapshots}/block_comment/expected-error.txt +0 -0
  26. data/test/{data → snapshots}/block_comment/expected-output.txt +0 -0
  27. data/test/{data → snapshots}/block_comment/source.lt3 +0 -0
  28. data/test/{data → snapshots}/comments_ignored_1/expected-error.txt +0 -0
  29. data/test/{data → snapshots}/comments_ignored_1/expected-output.txt +0 -0
  30. data/test/{data → snapshots}/comments_ignored_1/source.lt3 +0 -0
  31. data/test/{data → snapshots}/copy_is_raw/expected-error.txt +0 -0
  32. data/test/{data → snapshots}/copy_is_raw/expected-output.txt +0 -0
  33. data/test/{data → snapshots}/copy_is_raw/rawtext.inc +0 -0
  34. data/test/{data → snapshots}/copy_is_raw/source.lt3 +0 -0
  35. data/test/{data → snapshots}/crap +0 -0
  36. data/test/{data → snapshots}/def_method/expected-error.txt +0 -0
  37. data/test/{data → snapshots}/def_method/expected-output.txt +0 -0
  38. data/test/{data → snapshots}/def_method/source.lt3 +0 -0
  39. data/test/{data/error_inc_line_num/expected-err-line1match.txt → snapshots/error_inc_line_num/actual-error.txt} +0 -0
  40. data/test/snapshots/error_inc_line_num/actual-output.txt +13 -0
  41. data/test/{data/error_line_num → snapshots/error_inc_line_num}/expected-err-line1match.txt +0 -0
  42. data/test/{data → snapshots}/error_inc_line_num/expected-output.txt +6 -0
  43. data/test/{data → snapshots}/error_inc_line_num/file2.lt3 +0 -0
  44. data/test/snapshots/error_inc_line_num/out-sdiff.txt +14 -0
  45. data/test/{data → snapshots}/error_inc_line_num/source.lt3 +0 -0
  46. data/test/snapshots/error_invalid_name/actual-error.txt +10 -0
  47. data/test/{data/error_no_such_mixin/expected-output.txt → snapshots/error_invalid_name/actual-output.txt} +0 -0
  48. data/test/{data → snapshots}/error_invalid_name/expected-err-line1match.txt +0 -0
  49. data/test/{data → snapshots}/error_invalid_name/expected-output.txt +0 -0
  50. data/test/snapshots/error_invalid_name/out-sdiff.txt +6 -0
  51. data/test/{data → snapshots}/error_invalid_name/source.lt3 +0 -0
  52. data/test/snapshots/error_line_num/actual-error.txt +1 -0
  53. data/test/snapshots/error_line_num/actual-output.txt +5 -0
  54. data/test/snapshots/error_line_num/expected-err-line1match.txt +1 -0
  55. data/test/{data → snapshots}/error_line_num/expected-output.txt +0 -0
  56. data/test/snapshots/error_line_num/out-sdiff.txt +6 -0
  57. data/test/{data → snapshots}/error_line_num/source.lt3 +0 -0
  58. data/test/snapshots/error_mismatched_end/actual-error.txt +1 -0
  59. data/test/snapshots/error_mismatched_end/actual-output.txt +8 -0
  60. data/test/{data → snapshots}/error_mismatched_end/expected-err-line1match.txt +0 -0
  61. data/test/{data → snapshots}/error_mismatched_end/expected-output.txt +2 -0
  62. data/test/snapshots/error_mismatched_end/out-sdiff.txt +9 -0
  63. data/test/{data → snapshots}/error_mismatched_end/source.lt3 +0 -0
  64. data/test/{data/error_missing_end/expected-err-line1match.txt → snapshots/error_missing_end/actual-error.txt} +0 -0
  65. data/test/snapshots/error_missing_end/actual-output.txt +5 -0
  66. data/test/snapshots/error_missing_end/expected-err-line1match.txt +1 -0
  67. data/test/{data → snapshots}/error_missing_end/expected-output.txt +1 -0
  68. data/test/snapshots/error_missing_end/out-sdiff.txt +6 -0
  69. data/test/{data → snapshots}/error_missing_end/source.lt3 +0 -0
  70. data/test/{data/error_name_not_permitted/expected-output.txt → snapshots/error_name_not_permitted/OLD-exp-out} +0 -0
  71. data/test/{data/example_alpha/expected-error.txt → snapshots/error_name_not_permitted/expected-output.txt} +0 -0
  72. data/test/snapshots/error_name_not_permitted/match-error.txt +1 -0
  73. data/test/{data → snapshots}/error_name_not_permitted/source.lt3 +0 -0
  74. data/test/snapshots/error_no_such_copy/actual-error.txt +10 -0
  75. data/test/{data/example_alpha2/expected-error.txt → snapshots/error_no_such_copy/actual-output.txt} +0 -0
  76. data/test/snapshots/error_no_such_copy/expected-err-line1match.txt +1 -0
  77. data/test/{data → snapshots}/error_no_such_copy/expected-output.txt +0 -1
  78. data/test/snapshots/error_no_such_copy/out-sdiff.txt +5 -0
  79. data/test/{data → snapshots}/error_no_such_copy/source.lt3 +1 -0
  80. data/test/snapshots/error_no_such_inc/actual-error.txt +10 -0
  81. data/test/{data/functions/expected-error.txt → snapshots/error_no_such_inc/actual-output.txt} +0 -0
  82. data/test/snapshots/error_no_such_inc/expected-err-line1match.txt +1 -0
  83. data/test/{data → snapshots}/error_no_such_inc/expected-output.txt +0 -0
  84. data/test/snapshots/error_no_such_inc/out-sdiff.txt +6 -0
  85. data/test/{data → snapshots}/error_no_such_inc/source.lt3 +0 -0
  86. data/test/snapshots/error_no_such_mixin/actual-error.txt +1 -0
  87. data/test/snapshots/error_no_such_mixin/actual-output.txt +11 -0
  88. data/test/{data → snapshots}/error_no_such_mixin/expected-err-line1match.txt +0 -0
  89. data/test/snapshots/error_no_such_mixin/expected-output.txt +5 -0
  90. data/test/snapshots/error_no_such_mixin/out-sdiff.txt +12 -0
  91. data/test/{data → snapshots}/error_no_such_mixin/source.lt3 +0 -0
  92. data/test/{data/hello_world → snapshots/example_alpha}/expected-error.txt +0 -0
  93. data/test/{data → snapshots}/example_alpha/expected-output.txt +0 -0
  94. data/test/{data → snapshots}/example_alpha/source.lt3 +0 -0
  95. data/test/{data/more_complex_vars → snapshots/example_alpha2}/expected-error.txt +0 -0
  96. data/test/{data → snapshots}/example_alpha2/expected-output.txt +0 -0
  97. data/test/{data → snapshots}/example_alpha2/source.lt3 +0 -0
  98. data/test/{data → snapshots}/fixit +0 -0
  99. data/test/{data/raw_lines → snapshots/functions}/expected-error.txt +0 -0
  100. data/test/{data → snapshots}/functions/expected-output.txt +0 -0
  101. data/test/{data → snapshots}/functions/source.lt3 +0 -0
  102. data/test/{data/raw_text_block → snapshots/hello_world}/expected-error.txt +0 -0
  103. data/test/{data → snapshots}/hello_world/expected-output.txt +0 -0
  104. data/test/{data → snapshots}/hello_world/source.lt3 +0 -0
  105. data/test/{data → snapshots}/lines.txt +4 -0
  106. data/test/{data/simple_copy → 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_include/expected-error.txt → snapshots/predef_vars/actual-error.txt} +0 -0
  110. data/test/snapshots/predef_vars/actual-output.txt +6 -0
  111. data/test/{data/simple_mixin → snapshots/predef_vars}/expected-error.txt +0 -0
  112. data/test/snapshots/predef_vars/expected-output.txt +6 -0
  113. data/test/snapshots/predef_vars/out-sdiff.txt +7 -0
  114. data/test/snapshots/predef_vars/source.lt3 +6 -0
  115. data/test/{data/simple_vars → snapshots/raw_lines}/expected-error.txt +0 -0
  116. data/test/{data → snapshots}/raw_lines/expected-output.txt +0 -0
  117. data/test/{data → snapshots}/raw_lines/source.lt3 +0 -0
  118. data/test/{data/single_raw_line → snapshots/raw_text_block}/expected-error.txt +0 -0
  119. data/test/{data → snapshots}/raw_text_block/expected-output.txt +0 -0
  120. data/test/{data → snapshots}/raw_text_block/rawtext.inc +0 -0
  121. data/test/{data → snapshots}/raw_text_block/source.lt3 +0 -0
  122. data/test/{data/table_with_heredocs → snapshots/simple_copy}/expected-error.txt +0 -0
  123. data/test/{data → snapshots}/simple_copy/expected-output.txt +0 -0
  124. data/test/{data → snapshots}/simple_copy/simplefile.inc +0 -0
  125. data/test/{data → snapshots}/simple_copy/source.lt3 +0 -0
  126. data/test/{data/subset.txt → snapshots/simple_include/expected-error.txt} +0 -0
  127. data/test/{data → snapshots}/simple_include/expected-output.txt +0 -0
  128. data/test/{data → snapshots}/simple_include/simplefile.inc +0 -0
  129. data/test/{data → snapshots}/simple_include/source.lt3 +0 -0
  130. data/test/snapshots/simple_mixin/actual-error.txt +2 -0
  131. data/test/snapshots/simple_mixin/actual-output.txt +4 -0
  132. data/test/snapshots/simple_mixin/expected-error.txt +0 -0
  133. data/test/{data → snapshots}/simple_mixin/expected-output.txt +0 -0
  134. data/test/snapshots/simple_mixin/out-sdiff.txt +6 -0
  135. data/test/{data → snapshots}/simple_mixin/simple_mixin.rb +0 -0
  136. data/test/{data → snapshots}/simple_mixin/source.lt3 +0 -0
  137. data/test/snapshots/simple_vars/expected-error.txt +0 -0
  138. data/test/{data → snapshots}/simple_vars/expected-output.txt +0 -0
  139. data/test/{data → snapshots}/simple_vars/source.lt3 +0 -0
  140. data/test/snapshots/single_raw_line/expected-error.txt +0 -0
  141. data/test/{data → snapshots}/single_raw_line/expected-output.txt +0 -0
  142. data/test/{data → snapshots}/single_raw_line/source.lt3 +0 -0
  143. data/test/snapshots/subset.txt +0 -0
  144. data/test/snapshots/table_with_heredocs/expected-error.txt +0 -0
  145. data/test/{data → snapshots}/table_with_heredocs/expected-output.txt +0 -0
  146. data/test/{data → snapshots}/table_with_heredocs/source.lt3 +0 -0
  147. data/test/snapshots.rb +219 -0
  148. data/test/testlines.rb +17 -7
  149. data/test/unit/all.rb +3 -0
  150. data/test/unit/html.rb +38 -0
  151. data/test/unit/parse_misc.rb +60 -0
  152. data/test/unit/parse_set.rb +157 -0
  153. data/test/unit/parser/all.rb +3 -0
  154. data/test/unit/parser/general.rb +59 -0
  155. data/test/unit/parser/importable.rb +19 -0
  156. data/test/unit/parser/mixin.rb +19 -0
  157. data/test/unit/parser/set.rb +157 -0
  158. data/test/unit/parser/string.rb +130 -0
  159. data/test/unit/parser.rb +4 -0
  160. data/test/unit/standard.rb +23 -0
  161. data/test/unit/stringparser.rb +140 -0
  162. metadata +152 -95
  163. data/test/data/error_name_not_permitted/expected-error.txt +0 -1
  164. data/test/data/error_no_such_copy/expected-err-line1match.txt +0 -1
  165. data/test/data/error_no_such_inc/expected-err-line1match.txt +0 -1
  166. data/test/extratests.txt +0 -20
  167. data/test/test.rb +0 -140
data/lib/standard.rb CHANGED
@@ -1,5 +1,21 @@
1
+ require 'pathname' # For _seek - remove later??
2
+
3
+ require_relative 'parser' # nested requires
4
+ require_relative 'html'
5
+ require_relative 'helpers'
6
+
7
+ make_exception(:ExpectedOnOff, "Error: expected 'on' or 'off'")
8
+ make_exception(:DisallowedName, "Error: name %1 is invalid")
9
+ make_exception(:FileNotFound, "Error: file %1 not found")
10
+
11
+
12
+ # Module Standard comprises most of the standard or "common" methods.
13
+
1
14
  module Livetext::Standard
2
15
 
16
+ include HTMLHelper
17
+ include Helpers
18
+
3
19
  SimpleFormats = # Move this?
4
20
  { b: %w[<b> </b>],
5
21
  i: %w[<i> </i>],
@@ -8,7 +24,7 @@ module Livetext::Standard
8
24
 
9
25
  attr_reader :_data
10
26
 
11
- def data=(val)
27
+ def data=(val) # FIXME this is weird, let's not do it
12
28
  @_data = val.chomp
13
29
  @_args = val.split rescue []
14
30
  @_mixins = []
@@ -23,69 +39,75 @@ module Livetext::Standard
23
39
  end
24
40
 
25
41
  def backtrace
26
- arg = @_args.first
27
- @backtrace = true
28
- @backtrace = false if arg == "off"
42
+ @backtrace = onoff(@_args.first)
43
+ _optional_blank_line
29
44
  end
30
45
 
31
46
  def comment
32
47
  _body
48
+ _optional_blank_line
33
49
  end
34
50
 
35
51
  def shell
36
52
  cmd = @_data.chomp
37
- # _errout("Running: #{cmd}")
38
53
  system(cmd)
54
+ _optional_blank_line
39
55
  end
40
56
 
41
57
  def func
42
58
  funcname = @_args[0]
43
- _error! "Illegal name '#{funcname}'" if _disallowed?(funcname)
44
- func_def = <<-EOS
59
+ check_disallowed(funcname)
60
+ func_def = <<~EOS
45
61
  def #{funcname}(param)
46
62
  #{_body.to_a.join("\n")}
47
63
  end
48
- EOS
64
+ EOS
49
65
  _optional_blank_line
50
-
66
+
51
67
  Livetext::Functions.class_eval func_def
52
68
  end
53
69
 
54
- def h1; _out "<h1>#{@_data}</h1>"; end
55
- def h2; _out "<h2>#{@_data}</h2>"; end
56
- def h3; _out "<h3>#{@_data}</h3>"; end
57
- def h4; _out "<h4>#{@_data}</h4>"; end
58
- def h5; _out "<h5>#{@_data}</h5>"; end
59
- def h6; _out "<h6>#{@_data}</h6>"; end
70
+ def h1; _out wrapped(@_data, :h1); end
71
+ def h2; _out wrapped(@_data, :h2); end
72
+ def h3; _out wrapped(@_data, :h3); end
73
+ def h4; _out wrapped(@_data, :h4); end
74
+ def h5; _out wrapped(@_data, :h5); end
75
+ def h6; _out wrapped(@_data, :h6); end
60
76
 
61
77
  def list
62
- _out "<ul>"
63
- _body {|line| _out "<li>#{line}</li>" }
64
- _out "</ul>"
78
+ wrap :ul do
79
+ _body {|line| _out wrapped(line, :li) }
80
+ end
81
+ _optional_blank_line
65
82
  end
66
83
 
67
84
  def list!
68
- _out "<ul>"
69
- lines = _body.each # {|line| _out "<li>#{line}</li>" }
70
- loop do
71
- line = lines.next
72
- line = _format(line)
73
- if line[0] == " "
74
- _out line
75
- else
76
- _out "<li>#{line}</li>"
85
+ wrap(:ul) do
86
+ lines = _body.each # enumerator
87
+ loop do
88
+ line = lines.next
89
+ line = _format(line)
90
+ str = line[0] == " " ? line : wrapped(line, :li)
91
+ _out str
77
92
  end
78
93
  end
79
- _out "</ul>"
94
+ _optional_blank_line
80
95
  end
81
96
 
82
97
  def shell!
83
98
  cmd = @_data.chomp
84
99
  system(cmd)
100
+ _optional_blank_line
85
101
  end
86
102
 
87
103
  def errout
104
+ STDERR.puts @_data.chomp
105
+ _optional_blank_line
106
+ end
107
+
108
+ def ttyout
88
109
  TTY.puts @_data.chomp
110
+ _optional_blank_line
89
111
  end
90
112
 
91
113
  def say
@@ -96,133 +118,40 @@ EOS
96
118
 
97
119
  def banner
98
120
  str = _format(@_data.chomp)
99
- n = str.length - 1
100
- puts "-"*n
101
- puts str
102
- puts "-"*n
121
+ num = str.length - 1
122
+ decor = "-"*num + "\n"
123
+ puts decor + str + "\n" + decor
103
124
  end
104
125
 
105
126
  def quit
106
127
  puts @body
107
128
  @body = ""
108
129
  @output.close
109
- # exit!
110
130
  end
111
131
 
112
-
113
132
  def cleanup
114
- @_args.each do |item|
115
- if ::File.directory?(item)
116
- system("rm -f #{item}/*")
117
- else
118
- ::FileUtils.rm(item)
119
- end
133
+ @_args.each do |item|
134
+ cmd = ::File.directory?(item) ? "rm -f #{item}/*" : "rm #{item}"
135
+ system(cmd)
120
136
  end
121
137
  end
122
138
 
123
139
  def _def
124
140
  name = @_args[0]
125
141
  str = "def #{name}\n"
126
- raise "Illegal name '#{name}'" if _disallowed?(name)
127
- str += _body(true).join("\n")
128
- str += "\nend\n"
142
+ check_disallowed(name)
143
+ # Difficult to avoid eval here
144
+ str << _body(true).join("\n")
145
+ str << "\nend\n"
129
146
  eval str
130
- rescue => err
131
- _error!(err)
147
+ # rescue => err
148
+ # _error!(err)
132
149
  end
133
150
 
134
151
  def set
135
- # FIXME bug -- .set var="RIP, Hope Gallery"
136
- assigns = @_data.chomp.split(/, */)
137
- # Do a better way?
138
- # FIXME *Must* allow for vars/functions
139
- assigns.each do |a|
140
- var, val = a.split("=")
141
- var.strip!
142
- val.strip!
143
- val = val[1..-2] if val[0] == ?" && val[-1] == ?"
144
- val = val[1..-2] if val[0] == ?' && val[-1] == ?'
145
- val = FormatLine.var_func_parse(val)
146
- @parent._setvar(var, val)
147
- end
148
- _optional_blank_line
149
- end
150
-
151
- def _assign_get_var(c, e)
152
- name = c
153
- loop do
154
- c = e.peek
155
- case c
156
- when /[a-zA-Z_\.0-9]/
157
- name << e.next
158
- next
159
- when / =/
160
- return name
161
- else
162
- raise "Error: did not expect #{c.inspect} in variable name"
163
- end
164
- end
165
- raise "Error: loop ended parsing variable name"
166
- end
167
-
168
- def _assign_skip_equal(e)
169
- loop { break if e.peek != " "; e.next }
170
- if e.peek == "="
171
- e.next # skip spaces too
172
- loop { break if e.peek != " "; e.next }
173
- else
174
- raise "Error: expect equal sign"
175
- end
176
- end
177
-
178
- def _quoted_value(quote, e)
179
- value = ""
180
- loop do
181
- c = e.next
182
- break if c == quote
183
- value << c
184
- end
185
- value
186
- end
187
-
188
- def _unquoted_value(e)
189
- value = ""
190
- loop do
191
- c = e.next
192
- break if c == " " || c == ","
193
- value << c
194
- end
195
- value
196
- end
197
-
198
- def _assign_get_value
199
- c = e.peek
200
- value = ""
201
- case c
202
- when ?", ?'
203
- value = _quoted_value(c, e)
204
- else
205
- value = _unquoted_value(e)
206
- end
207
- c = e.peek
208
- value
209
- end
210
-
211
- def set_NEW
212
152
  line = _data.chomp
213
- e = line.each_char # enum
214
- loop do
215
- c = e.next
216
- case c
217
- when /a-z/i
218
- _assign_get_var(c, e)
219
- _assign_skip_equal
220
- when " "
221
- next
222
- else
223
- raise "set: Huh? line = #{line}"
224
- end
225
- end
153
+ pairs = Livetext::ParseSet.new(line).parse
154
+ set_variables(pairs)
226
155
  end
227
156
 
228
157
  def variables! # cwd, not FileDir - weird, fix later
@@ -235,14 +164,8 @@ EOS
235
164
  else
236
165
  lines = _body
237
166
  end
238
- lines.map! {|x| x.sub(/# .*/, "").strip } # strip comments
239
- lines.each do |line|
240
- next if line.strip.empty?
241
- var, val = line.split(" ", 2)
242
- val = FormatLine.var_func_parse(val)
243
- var = prefix + "." + var if prefix
244
- @parent._setvar(var, val)
245
- end
167
+ pairs = Livetext::ParseMisc.parse_vars(prefix, lines)
168
+ set_variables(pairs)
246
169
  end
247
170
 
248
171
  def variables
@@ -255,89 +178,63 @@ EOS
255
178
  else
256
179
  lines = _body
257
180
  end
258
- lines.map! {|x| x.sub(/# .*/, "").strip } # strip comments
259
- lines.each do |line|
260
- next if line.strip.empty?
261
- var, val = line.split(" ", 2)
262
- val = FormatLine.var_func_parse(val)
263
- var = prefix + "." + var if prefix
264
- @parent._setvar(var, val)
265
- end
266
- end
267
-
268
- def reval
269
- eval _data.chomp
270
- end
271
-
272
- def heredoc! # adds <br>...
273
- _heredoc(true)
181
+ pairs = Livetext::ParseMisc.parse_vars(prefix, lines)
182
+ set_variables(pairs)
274
183
  end
275
184
 
276
185
  def heredoc
277
- _heredoc
278
- end
279
-
280
- def _heredoc(bang=false)
281
186
  var = @_args[0]
282
- str = _body.join("\n")
283
- s2 = ""
284
- str.each_line do |s|
285
- str = FormatLine.var_func_parse(s.chomp)
286
- s2 << str + "<br>"
187
+ text = _body.join("\n")
188
+ rhs = ""
189
+ text.each_line do |line|
190
+ str = FormatLine.var_func_parse(line.chomp)
191
+ rhs << str + "<br>"
287
192
  end
288
193
  indent = @parent.indentation.last
289
194
  indented = " " * indent
290
- @parent._setvar(var, s2.chomp)
195
+ @parent._setvar(var, rhs.chomp)
291
196
  _optional_blank_line
292
197
  end
293
198
 
294
199
  def _seek(file)
295
- require 'pathname' # ;)
296
200
  value = nil
297
- if File.exist?(file)
298
- return file
299
- else
300
- count = 1
301
- loop do
302
- front = "../" * count
303
- count += 1
304
- here = Pathname.new(front).expand_path.dirname.to_s
305
- break if here == "/"
306
- path = front + file
307
- value = path if File.exist?(path)
308
- break if value
309
- end
310
- end
201
+ return file if File.exist?(file)
202
+
203
+ count = 1
204
+ loop do
205
+ front = "../" * count
206
+ count += 1
207
+ here = Pathname.new(front).expand_path.dirname.to_s
208
+ break if here == "/"
209
+ path = front + file
210
+ value = path if File.exist?(path)
211
+ break if value
212
+ end
311
213
  STDERR.puts "Cannot find #{file.inspect} from #{Dir.pwd}" unless value
312
214
  return value
313
215
  rescue
314
216
  STDERR.puts "Can't find #{file.inspect} from #{Dir.pwd}"
315
217
  return nil
316
218
  end
317
-
318
- def seek
319
- # like include, but search upward as needed
219
+
220
+ def seek # like include, but search upward as needed
320
221
  file = @_args.first
321
222
  file = _seek(file)
322
- _error!("No such include file #{file.inspect}") unless file
223
+ check_file_exists(file)
323
224
  @parent.process_file(file)
324
225
  _optional_blank_line
325
- rescue => err
326
- STDERR.puts ".seek error - #{err}"
327
- STDERR.puts err.inspect
328
- return nil
329
226
  end
330
227
 
331
228
  def in_out # FIXME dumb name!
332
229
  file, dest = *@_args
333
- _check_existence(file, "No such include file #{file.inspect}")
230
+ check_file_exists(file)
334
231
  @parent.process_file(file, dest)
335
232
  _optional_blank_line
336
233
  end
337
234
 
338
- def _include
339
- file = @_args.first
340
- _check_existence(file, "No such include file #{file.inspect}")
235
+ def _include # dot command
236
+ file = _format(@_args.first) # allows for variables
237
+ check_file_exists(file)
341
238
  @parent.process_file(file)
342
239
  _optional_blank_line
343
240
  end
@@ -350,62 +247,37 @@ EOS
350
247
  def inherit
351
248
  file = @_args.first
352
249
  upper = "../#{file}"
353
- good = (File.exist?(upper) || File.exist?(file))
250
+ got_upper, got_file = File.exist?(upper), File.exist?(file)
251
+ good = got_upper || got_file
354
252
  _error!("File #{file} not found (local or parent)") unless good
355
253
 
356
- @parent.process_file(upper) if File.exist?(upper)
357
- @parent.process_file(file) if File.exist?(file)
254
+ @parent.process_file(upper) if got_upper
255
+ @parent.process_file(file) if got_file
358
256
  _optional_blank_line
359
257
  end
360
258
 
361
- # def include! # FIXME huh?
362
- # file = @_args.first
363
- # return unless File.exist?(file)
364
- #
365
- # lines = @parent.process_file(file)
366
- # #? File.delete(file)
367
- # _optional_blank_line
368
- # end
369
-
370
- def _mixin(name)
371
- @_args = [name]
372
- mixin
373
- end
374
-
375
259
  def mixin
376
260
  name = @_args.first # Expect a module name
377
- file = "#{Plugins}/" + name.downcase + ".rb"
378
261
  return if @_mixins.include?(name)
379
- file = "./#{name}.rb" unless File.exist?(file)
380
- if File.exist?(file)
381
- # Just keep going...
382
- else
383
- if File.dirname(File.expand_path(".")) != "/"
384
- Dir.chdir("..") { mixin }
385
- return
386
- else
387
- STDERR.puts "No such mixin '#{name}'"
388
- puts @body
389
- exit!
390
- end
391
- end
262
+ @_mixins << name
263
+ parse = Livetext::ParseMixin.new(name) # FIXME??
264
+ file = parse.find_mixin(name)
265
+ parse.use_mixin(name, file)
266
+ _optional_blank_line
267
+ end
392
268
 
269
+ def import
270
+ name = @_args.first # Expect a module name
271
+ return if @_mixins.include?(name)
393
272
  @_mixins << name
394
- meths = grab_file(file)
395
- modname = name.gsub("/","_").capitalize
396
- string = "module ::#{modname}; #{meths}\nend"
397
-
398
- eval(string)
399
- newmod = Object.const_get("::" + modname)
400
- self.extend(newmod)
401
- init = "init_#{name}"
402
- self.send(init) if self.respond_to? init
273
+ parse = Livetext::ParseImport.new(name)
274
+ parse.use_import(name)
403
275
  _optional_blank_line
404
276
  end
405
277
 
406
278
  def copy
407
279
  file = @_args.first
408
- _check_existence(file, "No such file '#{file}' to copy")
280
+ check_file_exists(file)
409
281
  _out grab_file(file)
410
282
  _optional_blank_line
411
283
  end
@@ -416,24 +288,16 @@ EOS
416
288
 
417
289
  def raw
418
290
  # No processing at all (terminate with __EOF__)
419
- _raw_body {|x| _out x } # no formatting
291
+ _raw_body {|line| _out line } # no formatting
420
292
  end
421
293
 
422
294
  def debug
423
- arg = @_args.first
424
- self._debug = true
425
- self._debug = false if arg == "off"
295
+ self._debug = onoff(@_args.first)
426
296
  end
427
297
 
428
298
  def passthru
429
- # FIXME - add check for args size (helpers); _onoff helper??
430
- onoff = _args.first
431
- case onoff
432
- when nil; @_nopass = false
433
- when "on"; @_nopass = false
434
- when "off"; @_nopass = true
435
- else _error!("Unknown arg '#{onoff}'")
436
- end
299
+ # FIXME - add check for args size? (helpers)
300
+ @_nopass = ! onoff(_args.first)
437
301
  end
438
302
 
439
303
  def nopass
@@ -441,13 +305,20 @@ EOS
441
305
  end
442
306
 
443
307
  def para
444
- # FIXME - add check for args size (helpers); _onoff helper??
445
- onoff = _args.first
446
- case onoff
447
- when nil; @_nopara = false
448
- when "on"; @_nopara = false
449
- when "off"; @_nopara = true
450
- else _error!("Unknown arg '#{onoff}'")
308
+ # FIXME - add check for args size? (helpers)
309
+ @_nopara = ! onoff(_args.first)
310
+ end
311
+
312
+ def onoff(arg) # helper
313
+ arg ||= "on"
314
+ raise ExpectedOnOff unless String === arg
315
+ case arg.downcase
316
+ when "on"
317
+ return true
318
+ when "off"
319
+ return false
320
+ else
321
+ raise ExpectedOnOff
451
322
  end
452
323
  end
453
324
 
@@ -466,39 +337,23 @@ EOS
466
337
  _out "<p/>"
467
338
  end
468
339
 
469
- def invoke(str)
470
- end
471
-
472
340
  def mono
473
- _out "<pre>"
474
- _body(true) {|line| _out line }
475
- _out "</pre>"
341
+ wrap ":pre" do
342
+ _body(true) {|line| _out line }
343
+ end
476
344
  _optional_blank_line
477
345
  end
478
346
 
479
347
  def dlist
480
348
  delim = _args.first
481
- _out "<dl>"
482
- _body do |line|
483
- line = _format(line)
484
- term, defn = line.split(delim)
485
- _out "<dt>#{term}</dt>"
486
- _out "<dd>#{defn}</dd>"
487
- end
488
- _out "</dl>"
489
- end
490
-
491
- def old_dlist
492
- delim = _args.first
493
- _out "<table>"
494
- _body do |line|
495
- line = _format(line)
496
- term, defn = line.split(delim)
497
- _out "<tr>"
498
- _out "<td width=3%><td width=10%>#{term}</td><td>#{defn}</td>"
499
- _out "</tr>"
349
+ wrap(:dl) do
350
+ _body do |line|
351
+ line = _format(line)
352
+ term, defn = line.split(delim)
353
+ _out wrapped(term, :dt)
354
+ _out wrapped(defn, :dd)
355
+ end
500
356
  end
501
- _out "</table>"
502
357
  end
503
358
 
504
359
  def link
@@ -517,21 +372,19 @@ EOS
517
372
  line = _format(line)
518
373
  line.gsub!(/\n+/, "<br>")
519
374
  cells = line.split(delim)
520
- wide = cells.map {|x| x.length }
375
+ wide = cells.map {|cell| cell.length }
521
376
  maxw = [0] * cells.size
522
377
  maxw = maxw.map.with_index {|x, i| [x, wide[i]].max }
523
378
  end
524
-
379
+
525
380
  sum = maxw.inject(0, :+)
526
381
  maxw.map! {|x| (x/sum*100).floor }
527
-
382
+
528
383
  lines.each do |line|
529
384
  cells = line.split(delim)
530
- _out "<tr>"
531
- cells.each.with_index do |cell, i|
532
- _out " <td valign=top>#{cell}</td>"
385
+ wrap :tr do
386
+ cells.each {|cell| _out " <td valign=top>#{cell}</td>" }
533
387
  end
534
- _out "</tr>"
535
388
  end
536
389
  _out "</table></center>"
537
390
  end
@@ -542,10 +395,10 @@ EOS
542
395
  end
543
396
 
544
397
  def br
545
- n = _args.first || "1"
398
+ num = _args.first || "1"
546
399
  out = ""
547
- n.to_i.times { out << "<br>" }
400
+ num.to_i.times { out << "<br>" }
548
401
  _out out
549
402
  end
550
403
 
551
- end
404
+ end
data/lib/userapi.rb CHANGED
@@ -1,7 +1,8 @@
1
1
  # User API
2
2
 
3
- require 'formatline'
3
+ require_relative 'formatline'
4
4
 
5
+ # UserAPI deals mostly with user-level methods.
5
6
  module Livetext::UserAPI
6
7
 
7
8
  def setvar(var, val)
@@ -93,10 +94,10 @@ module Livetext::UserAPI
93
94
  else
94
95
  lines
95
96
  end
96
- rescue => err
97
- str = err.inspect + "\n"
98
- str << err.backtrace.map {|x| " " + x }.join("\n")
99
- _error!(str)
97
+ # rescue => err
98
+ # str = err.inspect + "\n"
99
+ # str << err.backtrace.map {|x| " " + x }.join("\n")
100
+ # _error!(str)
100
101
  end
101
102
 
102
103
  def _body_text(raw=false)
data/livetext.gemspec CHANGED
@@ -1,8 +1,7 @@
1
1
  require 'date'
2
2
  require 'find'
3
3
 
4
- $: << "."
5
- require "lib/livetext"
4
+ require_relative "lib/livetext"
6
5
 
7
6
  Gem::Specification.new do |s|
8
7
  system("rm -f *.gem")
data/test/all.rb ADDED
@@ -0,0 +1,3 @@
1
+
2
+ require_relative 'unit/all'
3
+ require_relative 'snapshots' # snapshots
data/test/formatting.rb CHANGED
@@ -1,13 +1,6 @@
1
- def minitest?
2
- require 'minitest/autorun'
3
- end
4
-
5
- abort "minitest gem is not installed" unless minitest?
6
-
7
-
8
- $LOAD_PATH << "./lib"
1
+ require 'minitest/autorun'
9
2
 
10
- require 'livetext'
3
+ require_relative '../lib/livetext'
11
4
 
12
5
  class TestingLivetext < MiniTest::Test
13
6