livetext 0.9.09 → 0.9.14

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 (143) hide show
  1. checksums.yaml +4 -4
  2. data/bin/livetext +0 -1
  3. data/lib/errors.rb +15 -0
  4. data/lib/formatline.rb +3 -5
  5. data/lib/functions.rb +6 -2
  6. data/lib/helpers.rb +25 -0
  7. data/lib/html.rb +32 -0
  8. data/lib/livetext/importable.rb +2 -0
  9. data/lib/livetext.rb +60 -48
  10. data/lib/parser/general.rb +38 -0
  11. data/lib/parser/import.rb +17 -0
  12. data/lib/parser/mixin.rb +40 -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 +22 -23
  17. data/lib/standard.rb +145 -298
  18. data/lib/userapi.rb +2 -5
  19. data/livetext.gemspec +1 -2
  20. data/test/all.rb +4 -0
  21. data/test/formatting-tests.rb +35 -0
  22. data/test/formatting.rb +2 -9
  23. data/test/snapshots/OMIT.txt +10 -0
  24. data/test/{data → snapshots}/basic_formatting/expected-error.txt +0 -0
  25. data/test/{data → snapshots}/basic_formatting/expected-output.txt +0 -0
  26. data/test/{data → snapshots}/basic_formatting/source.lt3 +0 -0
  27. data/test/{data → snapshots}/block_comment/expected-error.txt +0 -0
  28. data/test/{data → snapshots}/block_comment/expected-output.txt +0 -0
  29. data/test/{data → snapshots}/block_comment/source.lt3 +0 -0
  30. data/test/{data → snapshots}/comments_ignored_1/expected-error.txt +0 -0
  31. data/test/{data → snapshots}/comments_ignored_1/expected-output.txt +0 -0
  32. data/test/{data → snapshots}/comments_ignored_1/source.lt3 +0 -0
  33. data/test/{data → snapshots}/copy_is_raw/expected-error.txt +0 -0
  34. data/test/{data → snapshots}/copy_is_raw/expected-output.txt +0 -0
  35. data/test/{data → snapshots}/copy_is_raw/rawtext.inc +0 -0
  36. data/test/{data → snapshots}/copy_is_raw/source.lt3 +0 -0
  37. data/test/{data → snapshots}/crap +0 -0
  38. data/test/{data → snapshots}/def_method/expected-error.txt +0 -0
  39. data/test/{data → snapshots}/def_method/expected-output.txt +0 -0
  40. data/test/{data → snapshots}/def_method/source.lt3 +0 -0
  41. data/test/{data → snapshots}/error_inc_line_num/expected-output.txt +6 -0
  42. data/test/{data → snapshots}/error_inc_line_num/file2.lt3 +0 -0
  43. data/test/snapshots/error_inc_line_num/match-error.txt +1 -0
  44. data/test/{data → snapshots}/error_inc_line_num/source.lt3 +0 -0
  45. data/test/{data → snapshots}/error_invalid_name/expected-output.txt +0 -0
  46. data/test/snapshots/error_invalid_name/match-error.txt +1 -0
  47. data/test/{data → snapshots}/error_invalid_name/source.lt3 +0 -0
  48. data/test/{data → snapshots}/error_line_num/expected-output.txt +0 -0
  49. data/test/snapshots/error_line_num/match-error.txt +1 -0
  50. data/test/{data → snapshots}/error_line_num/source.lt3 +0 -0
  51. data/test/{data → snapshots}/error_mismatched_end/expected-output.txt +0 -0
  52. data/test/snapshots/error_mismatched_end/match-error.txt +1 -0
  53. data/test/{data → snapshots}/error_mismatched_end/source.lt3 +0 -0
  54. data/test/{data → snapshots}/error_missing_end/expected-output.txt +1 -0
  55. data/test/snapshots/error_missing_end/match-error.txt +1 -0
  56. data/test/{data → snapshots}/error_missing_end/source.lt3 +0 -0
  57. data/test/{data/error_no_such_mixin → snapshots/error_name_not_permitted}/expected-output.txt +0 -0
  58. data/test/snapshots/error_name_not_permitted/match-error.txt +1 -0
  59. data/test/{data → snapshots}/error_name_not_permitted/source.lt3 +0 -0
  60. data/test/{data → snapshots}/error_no_such_copy/expected-output.txt +0 -1
  61. data/test/snapshots/error_no_such_copy/match-error.txt +1 -0
  62. data/test/{data → snapshots}/error_no_such_copy/source.lt3 +1 -0
  63. data/test/{data → snapshots}/error_no_such_inc/expected-output.txt +0 -0
  64. data/test/snapshots/error_no_such_inc/match-error.txt +1 -0
  65. data/test/{data → snapshots}/error_no_such_inc/source.lt3 +0 -0
  66. data/test/snapshots/error_no_such_mixin/expected-output.txt +5 -0
  67. data/test/snapshots/error_no_such_mixin/match-error.txt +1 -0
  68. data/test/{data → snapshots}/error_no_such_mixin/source.lt3 +0 -0
  69. data/test/{data → snapshots}/example_alpha/expected-error.txt +0 -0
  70. data/test/{data → snapshots}/example_alpha/expected-output.txt +0 -0
  71. data/test/{data → snapshots}/example_alpha/source.lt3 +0 -0
  72. data/test/{data → snapshots}/example_alpha2/expected-error.txt +0 -0
  73. data/test/{data → snapshots}/example_alpha2/expected-output.txt +0 -0
  74. data/test/{data → snapshots}/example_alpha2/source.lt3 +0 -0
  75. data/test/{data → snapshots}/fixit +0 -0
  76. data/test/{data/lines.txt → snapshots/formatting-tests.txt} +4 -0
  77. data/test/{data → snapshots}/functions/expected-error.txt +0 -0
  78. data/test/{data → snapshots}/functions/expected-output.txt +0 -0
  79. data/test/{data → snapshots}/functions/source.lt3 +0 -0
  80. data/test/{data → snapshots}/hello_world/expected-error.txt +0 -0
  81. data/test/{data → snapshots}/hello_world/expected-output.txt +0 -0
  82. data/test/{data → snapshots}/hello_world/source.lt3 +0 -0
  83. data/test/{data → snapshots}/more_complex_vars/expected-error.txt +0 -0
  84. data/test/{data → snapshots}/more_complex_vars/expected-output.txt +0 -0
  85. data/test/{data → snapshots}/more_complex_vars/source.lt3 +0 -0
  86. data/test/{data/raw_lines → snapshots/predef_vars}/expected-error.txt +0 -0
  87. data/test/snapshots/predef_vars/match-output.txt +6 -0
  88. data/test/snapshots/predef_vars/source.lt3 +6 -0
  89. data/test/{data/raw_text_block → snapshots/raw_lines}/expected-error.txt +0 -0
  90. data/test/{data → snapshots}/raw_lines/expected-output.txt +0 -0
  91. data/test/{data → snapshots}/raw_lines/source.lt3 +0 -0
  92. data/test/{data/simple_copy → snapshots/raw_text_block}/expected-error.txt +0 -0
  93. data/test/{data → snapshots}/raw_text_block/expected-output.txt +0 -0
  94. data/test/{data → snapshots}/raw_text_block/rawtext.inc +0 -0
  95. data/test/{data → snapshots}/raw_text_block/source.lt3 +0 -0
  96. data/test/{data/simple_include → snapshots/simple_copy}/expected-error.txt +0 -0
  97. data/test/{data → snapshots}/simple_copy/expected-output.txt +0 -0
  98. data/test/{data → snapshots}/simple_copy/simplefile.inc +0 -0
  99. data/test/{data → snapshots}/simple_copy/source.lt3 +0 -0
  100. data/test/{data/simple_mixin → snapshots/simple_include}/expected-error.txt +0 -0
  101. data/test/{data → snapshots}/simple_include/expected-output.txt +0 -0
  102. data/test/{data → snapshots}/simple_include/simplefile.inc +0 -0
  103. data/test/{data → snapshots}/simple_include/source.lt3 +0 -0
  104. data/test/{data/simple_vars → snapshots/simple_mixin}/expected-error.txt +0 -0
  105. data/test/{data → snapshots}/simple_mixin/expected-output.txt +0 -0
  106. data/test/{data → snapshots}/simple_mixin/simple_mixin.rb +0 -0
  107. data/test/{data → snapshots}/simple_mixin/source.lt3 +0 -0
  108. data/test/{data/single_raw_line → snapshots/simple_vars}/expected-error.txt +0 -0
  109. data/test/{data → snapshots}/simple_vars/expected-output.txt +0 -0
  110. data/test/{data → snapshots}/simple_vars/source.lt3 +0 -0
  111. data/test/{data/table_with_heredocs → snapshots/single_raw_line}/expected-error.txt +0 -0
  112. data/test/{data → snapshots}/single_raw_line/expected-output.txt +0 -0
  113. data/test/{data → snapshots}/single_raw_line/source.lt3 +0 -0
  114. data/test/{data → snapshots}/subset.txt +0 -0
  115. data/test/snapshots/table_with_heredocs/expected-error.txt +0 -0
  116. data/test/{data → snapshots}/table_with_heredocs/expected-output.txt +0 -0
  117. data/test/{data → snapshots}/table_with_heredocs/source.lt3 +0 -0
  118. data/test/snapshots.rb +168 -0
  119. data/test/testlines.rb +17 -7
  120. data/test/unit/all.rb +3 -0
  121. data/test/unit/html.rb +38 -0
  122. data/test/unit/parser/all.rb +3 -0
  123. data/test/unit/parser/general.rb +59 -0
  124. data/test/unit/parser/importable.rb +19 -0
  125. data/test/unit/parser/mixin.rb +19 -0
  126. data/test/unit/parser/set.rb +157 -0
  127. data/test/unit/parser/string.rb +130 -0
  128. data/test/unit/parser.rb +6 -0
  129. data/test/unit/standard.rb +23 -0
  130. data/test/unit/stringparser.rb +140 -0
  131. metadata +122 -96
  132. data/test/data/error_inc_line_num/expected-err-line1match.txt +0 -1
  133. data/test/data/error_invalid_name/expected-err-line1match.txt +0 -1
  134. data/test/data/error_line_num/expected-err-line1match.txt +0 -1
  135. data/test/data/error_mismatched_end/expected-err-line1match.txt +0 -1
  136. data/test/data/error_missing_end/expected-err-line1match.txt +0 -1
  137. data/test/data/error_name_not_permitted/expected-error.txt +0 -1
  138. data/test/data/error_name_not_permitted/expected-output.txt +0 -4
  139. data/test/data/error_no_such_copy/expected-err-line1match.txt +0 -1
  140. data/test/data/error_no_such_inc/expected-err-line1match.txt +0 -1
  141. data/test/data/error_no_such_mixin/expected-err-line1match.txt +0 -1
  142. data/test/extratests.txt +0 -20
  143. 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 remove it soonish
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,135 +118,44 @@ 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
 
157
+ # FIXME really these should be one method...
158
+
228
159
  def variables! # cwd, not FileDir - weird, fix later
229
160
  prefix = _args[0]
230
161
  file = _args[1]
@@ -235,14 +166,8 @@ EOS
235
166
  else
236
167
  lines = _body
237
168
  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
169
+ pairs = Livetext::ParseGeneral.parse_vars(prefix, lines)
170
+ set_variables(pairs)
246
171
  end
247
172
 
248
173
  def variables
@@ -255,90 +180,56 @@ EOS
255
180
  else
256
181
  lines = _body
257
182
  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)
183
+ pairs = Livetext::ParseGeneral.parse_vars(prefix, lines)
184
+ set_variables(pairs)
274
185
  end
275
186
 
276
187
  def heredoc
277
- _heredoc
278
- end
279
-
280
- def _heredoc(bang=false)
281
188
  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>"
189
+ text = _body.join("\n")
190
+ rhs = ""
191
+ text.each_line do |line|
192
+ str = FormatLine.var_func_parse(line.chomp)
193
+ rhs << str + "<br>"
287
194
  end
288
195
  indent = @parent.indentation.last
289
196
  indented = " " * indent
290
- @parent._setvar(var, s2.chomp)
197
+ @parent._setvar(var, rhs.chomp)
291
198
  _optional_blank_line
292
199
  end
293
200
 
294
201
  def _seek(file)
295
- require 'pathname' # ;)
296
202
  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
203
+ return file if File.exist?(file)
204
+
205
+ count = 1
206
+ loop do
207
+ front = "../" * count
208
+ count += 1
209
+ here = Pathname.new(front).expand_path.dirname.to_s
210
+ break if here == "/"
211
+ path = front + file
212
+ value = path if File.exist?(path)
213
+ break if value
214
+ end
311
215
  STDERR.puts "Cannot find #{file.inspect} from #{Dir.pwd}" unless value
312
216
  return value
313
217
  rescue
314
218
  STDERR.puts "Can't find #{file.inspect} from #{Dir.pwd}"
315
219
  return nil
316
220
  end
317
-
318
- def seek
319
- # like include, but search upward as needed
221
+
222
+ def seek # like include, but search upward as needed
320
223
  file = @_args.first
321
224
  file = _seek(file)
322
- _error!("No such include file #{file.inspect}") unless file
225
+ check_file_exists(file)
323
226
  @parent.process_file(file)
324
227
  _optional_blank_line
325
- rescue => err
326
- STDERR.puts ".seek error - #{err}"
327
- STDERR.puts err.inspect
328
- return nil
329
228
  end
330
229
 
331
- def in_out # FIXME dumb name!
332
- file, dest = *@_args
333
- _check_existence(file, "No such include file #{file.inspect}")
334
- @parent.process_file(file, dest)
335
- _optional_blank_line
336
- end
337
-
338
- def _include
339
- STDERR.puts "_include: vars View/ViewDir #{::Livetext::Vars[:View]} #{::Livetext::Vars[:ViewDir]} "
230
+ def _include # dot command
340
231
  file = _format(@_args.first) # allows for variables
341
- _check_existence(file, "No such include file #{file.inspect}")
232
+ check_file_exists(file)
342
233
  @parent.process_file(file)
343
234
  _optional_blank_line
344
235
  end
@@ -351,62 +242,37 @@ STDERR.puts "_include: vars View/ViewDir #{::Livetext::Vars[:View]} #{::Livetext
351
242
  def inherit
352
243
  file = @_args.first
353
244
  upper = "../#{file}"
354
- good = (File.exist?(upper) || File.exist?(file))
245
+ got_upper, got_file = File.exist?(upper), File.exist?(file)
246
+ good = got_upper || got_file
355
247
  _error!("File #{file} not found (local or parent)") unless good
356
248
 
357
- @parent.process_file(upper) if File.exist?(upper)
358
- @parent.process_file(file) if File.exist?(file)
249
+ @parent.process_file(upper) if got_upper
250
+ @parent.process_file(file) if got_file
359
251
  _optional_blank_line
360
252
  end
361
253
 
362
- # def include! # FIXME huh?
363
- # file = @_args.first
364
- # return unless File.exist?(file)
365
- #
366
- # lines = @parent.process_file(file)
367
- # #? File.delete(file)
368
- # _optional_blank_line
369
- # end
370
-
371
- def _mixin(name)
372
- @_args = [name]
373
- mixin
374
- end
375
-
376
254
  def mixin
377
255
  name = @_args.first # Expect a module name
378
- file = "#{Plugins}/" + name.downcase + ".rb"
379
256
  return if @_mixins.include?(name)
380
- file = "./#{name}.rb" unless File.exist?(file)
381
- if File.exist?(file)
382
- # Just keep going...
383
- else
384
- if File.dirname(File.expand_path(".")) != "/"
385
- Dir.chdir("..") { mixin }
386
- return
387
- else
388
- STDERR.puts "No such mixin '#{name}'"
389
- puts @body
390
- exit!
391
- end
392
- end
257
+ @_mixins << name
258
+ parse = Livetext::ParseMixin.new # (name) # FIXME??
259
+ file = parse.find_mixin(name)
260
+ parse.use_mixin(name, file)
261
+ _optional_blank_line
262
+ end
393
263
 
264
+ def import
265
+ name = @_args.first # Expect a module name
266
+ return if @_mixins.include?(name)
394
267
  @_mixins << name
395
- meths = grab_file(file)
396
- modname = name.gsub("/","_").capitalize
397
- string = "module ::#{modname}; #{meths}\nend"
398
-
399
- eval(string)
400
- newmod = Object.const_get("::" + modname)
401
- self.extend(newmod)
402
- init = "init_#{name}"
403
- self.send(init) if self.respond_to? init
268
+ parse = Livetext::ParseImport.new(name)
269
+ parse.use_import(name)
404
270
  _optional_blank_line
405
271
  end
406
272
 
407
273
  def copy
408
274
  file = @_args.first
409
- _check_existence(file, "No such file '#{file}' to copy")
275
+ check_file_exists(file)
410
276
  _out grab_file(file)
411
277
  _optional_blank_line
412
278
  end
@@ -417,24 +283,16 @@ STDERR.puts "_include: vars View/ViewDir #{::Livetext::Vars[:View]} #{::Livetext
417
283
 
418
284
  def raw
419
285
  # No processing at all (terminate with __EOF__)
420
- _raw_body {|x| _out x } # no formatting
286
+ _raw_body {|line| _out line } # no formatting
421
287
  end
422
288
 
423
289
  def debug
424
- arg = @_args.first
425
- self._debug = true
426
- self._debug = false if arg == "off"
290
+ self._debug = onoff(@_args.first)
427
291
  end
428
292
 
429
293
  def passthru
430
- # FIXME - add check for args size (helpers); _onoff helper??
431
- onoff = _args.first
432
- case onoff
433
- when nil; @_nopass = false
434
- when "on"; @_nopass = false
435
- when "off"; @_nopass = true
436
- else _error!("Unknown arg '#{onoff}'")
437
- end
294
+ # FIXME - add check for args size? (helpers)
295
+ @_nopass = ! onoff(_args.first)
438
296
  end
439
297
 
440
298
  def nopass
@@ -442,13 +300,20 @@ STDERR.puts "_include: vars View/ViewDir #{::Livetext::Vars[:View]} #{::Livetext
442
300
  end
443
301
 
444
302
  def para
445
- # FIXME - add check for args size (helpers); _onoff helper??
446
- onoff = _args.first
447
- case onoff
448
- when nil; @_nopara = false
449
- when "on"; @_nopara = false
450
- when "off"; @_nopara = true
451
- else _error!("Unknown arg '#{onoff}'")
303
+ # FIXME - add check for args size? (helpers)
304
+ @_nopara = ! onoff(_args.first)
305
+ end
306
+
307
+ def onoff(arg) # helper
308
+ arg ||= "on"
309
+ raise ExpectedOnOff unless String === arg
310
+ case arg.downcase
311
+ when "on"
312
+ return true
313
+ when "off"
314
+ return false
315
+ else
316
+ raise ExpectedOnOff
452
317
  end
453
318
  end
454
319
 
@@ -467,39 +332,23 @@ STDERR.puts "_include: vars View/ViewDir #{::Livetext::Vars[:View]} #{::Livetext
467
332
  _out "<p/>"
468
333
  end
469
334
 
470
- def invoke(str)
471
- end
472
-
473
335
  def mono
474
- _out "<pre>"
475
- _body(true) {|line| _out line }
476
- _out "</pre>"
336
+ wrap ":pre" do
337
+ _body(true) {|line| _out line }
338
+ end
477
339
  _optional_blank_line
478
340
  end
479
341
 
480
342
  def dlist
481
343
  delim = _args.first
482
- _out "<dl>"
483
- _body do |line|
484
- line = _format(line)
485
- term, defn = line.split(delim)
486
- _out "<dt>#{term}</dt>"
487
- _out "<dd>#{defn}</dd>"
488
- end
489
- _out "</dl>"
490
- end
491
-
492
- def old_dlist
493
- delim = _args.first
494
- _out "<table>"
495
- _body do |line|
496
- line = _format(line)
497
- term, defn = line.split(delim)
498
- _out "<tr>"
499
- _out "<td width=3%><td width=10%>#{term}</td><td>#{defn}</td>"
500
- _out "</tr>"
344
+ wrap(:dl) do
345
+ _body do |line|
346
+ line = _format(line)
347
+ term, defn = line.split(delim)
348
+ _out wrapped(term, :dt)
349
+ _out wrapped(defn, :dd)
350
+ end
501
351
  end
502
- _out "</table>"
503
352
  end
504
353
 
505
354
  def link
@@ -518,21 +367,19 @@ STDERR.puts "_include: vars View/ViewDir #{::Livetext::Vars[:View]} #{::Livetext
518
367
  line = _format(line)
519
368
  line.gsub!(/\n+/, "<br>")
520
369
  cells = line.split(delim)
521
- wide = cells.map {|x| x.length }
370
+ wide = cells.map {|cell| cell.length }
522
371
  maxw = [0] * cells.size
523
372
  maxw = maxw.map.with_index {|x, i| [x, wide[i]].max }
524
373
  end
525
-
374
+
526
375
  sum = maxw.inject(0, :+)
527
376
  maxw.map! {|x| (x/sum*100).floor }
528
-
377
+
529
378
  lines.each do |line|
530
379
  cells = line.split(delim)
531
- _out "<tr>"
532
- cells.each.with_index do |cell, i|
533
- _out " <td valign=top>#{cell}</td>"
380
+ wrap :tr do
381
+ cells.each {|cell| _out " <td valign=top>#{cell}</td>" }
534
382
  end
535
- _out "</tr>"
536
383
  end
537
384
  _out "</table></center>"
538
385
  end
@@ -543,10 +390,10 @@ STDERR.puts "_include: vars View/ViewDir #{::Livetext::Vars[:View]} #{::Livetext
543
390
  end
544
391
 
545
392
  def br
546
- n = _args.first || "1"
393
+ num = _args.first || "1"
547
394
  out = ""
548
- n.to_i.times { out << "<br>" }
395
+ num.to_i.times { out << "<br>" }
549
396
  _out out
550
397
  end
551
398
 
552
- end
399
+ 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,6 @@ 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)
100
97
  end
101
98
 
102
99
  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,4 @@
1
+
2
+ require_relative 'unit/all'
3
+ require_relative 'snapshots' # snapshots
4
+ require_relative 'formatting-tests' # one-liners in input