livetext 0.9.30 → 0.9.31

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ee3796664666616d6b5428f4b27f81c3f902171fc8afc8fd351631c6c774e730
4
- data.tar.gz: 5dd5250915ef13d930dca6b147e84b5e04e42d1a7b9c0f4b1e95d510ea49e476
3
+ metadata.gz: 769c4da93282df68e38011277d71ee8334fd14d4f87061c803d3d9643564afc7
4
+ data.tar.gz: 9b8611007ecbc2d4e899575cf504e6f87c9b1887df2b59ef8ff56a072f5e9e92
5
5
  SHA512:
6
- metadata.gz: d0e81ca1d3990468ae49f3c5e23ab608160f7db301f692757200fe57b5434f125bd83b3a7af80dd22ea8cc278972dcb39fe3b408f3a800871f3fb243e6c3639c
7
- data.tar.gz: 4bc7641f62f63215fbcf52192a74956991e540a2282922da21a5b0ea2a5d959420a9226c52745c635fc91521d860921b4d7d69defb8b540868d73df9b8fbfd99
6
+ metadata.gz: 2904613247a614b01a8b80ecefb9197ba070e69ebad4d292e3ce77b3f4ddf5b60850ad554333c1e2f8a54cf56b765c799ae52fd7491fd24648b570313ba401c6
7
+ data.tar.gz: e698ca1431dc18d64d1b44fc9edebe033c382dcc49252602cbf74c398c8f6fc38fea2dbe3d3a056fe550eca6291157bfba53e240d416a97bd1f3cca8ea4ec141
data/imports/bookish.rb CHANGED
@@ -173,7 +173,7 @@ module Bookish
173
173
  lines = api.body(true)
174
174
  maxw = nil
175
175
  lines.each do |line|
176
- api.format(line)
176
+ # line = api.format(line)
177
177
  cells = line.split(delim)
178
178
  wide = cells.map {|x| x.length }
179
179
  maxw = [0] * cells.size
@@ -12,21 +12,23 @@ class Livetext::Expansion
12
12
  @live = instance
13
13
  end
14
14
 
15
- def format(line) # new/experimental
15
+ def format(line)
16
16
  return "" if line == "\n" || line.nil?
17
- formatted = Formatter.format(line)
18
- with_vars = expand_variables(formatted)
17
+ with_vars = expand_variables(line)
19
18
  with_func = expand_function_calls(with_vars)
19
+ formatted = Formatter.format(with_func)
20
20
  end
21
21
 
22
22
  def expand_variables(str)
23
23
  rx = Regexp.compile("(?<result>" + Var + Dotted + ")")
24
- enum = str.each_char
25
24
  buffer = ""
26
25
  loop do |i|
27
26
  case # var or func or false alarm
28
27
  when str.empty? # end of string
29
28
  break
29
+ when str.slice(0..1) == "\\$" # escaped, ignore it
30
+ str.slice!(0..1)
31
+ buffer << "$"
30
32
  when str.slice(0..1) == "$$" # func?
31
33
  buffer << str.slice!(0..1)
32
34
  when str.slice(0) == "$" # var?
@@ -41,7 +43,8 @@ class Livetext::Expansion
41
43
  vars = @live.vars
42
44
  buffer << vars.get(vsym)
43
45
  else # other
44
- buffer << str.slice!(0)
46
+ char = str.slice!(0)
47
+ buffer << char
45
48
  end
46
49
  end
47
50
  buffer
@@ -82,14 +85,12 @@ class Livetext::Expansion
82
85
  param = fmatch["param"] # may be nil
83
86
  full = fmatch["full_param"]
84
87
  fsym = fname[2..-1] # no $$
85
- =begin
86
- puts "rx = #{rx.inspect}"
87
- puts "fmatch = #{fmatch.inspect}"
88
- puts "fname = #{fname.inspect}"
89
- puts "param = #{param.inspect}"
90
- puts "full = #{full.inspect}"
91
- puts "fsym = #{fsym.inspect}"
92
- =end
88
+ #STDERR.puts "rx = #{rx.inspect}"
89
+ #STDERR.puts "fmatch = #{fmatch.inspect}"
90
+ #STDERR.puts "fname = #{fname.inspect}"
91
+ #STDERR.puts "param = #{param.inspect}"
92
+ #STDERR.puts "full = #{full.inspect}"
93
+ #STDERR.puts "fsym = #{fsym.inspect}"
93
94
  str.sub!(fname, "")
94
95
  str.sub!(full, "") if full
95
96
  retval = funcall(fsym, param)
@@ -100,6 +101,7 @@ puts "fsym = #{fsym.inspect}"
100
101
  buffer << char
101
102
  end
102
103
  end
104
+ # STDERR.puts "buffer = #{buffer.inspect}"
103
105
  buffer
104
106
  end
105
107
  end
@@ -1,104 +1,223 @@
1
1
  module Formatter
2
-
3
- Start = /(?<start>(^| ))/
4
- Stop = /(?<stop> |$)/
5
2
 
6
- def self.make_regex(sigil, cdata, stop = Stop)
7
- rx = /#{Start}#{sigil}#{cdata}#{stop}/
3
+ ## Hmmm...
4
+ #
5
+ # Double: b, i, t, s
6
+ # Single: bits
7
+ # Brackt: bits
8
+ #
9
+
10
+
11
+ def self.format(str)
12
+ str = str.chomp
13
+ s2 = Double.process(str.chomp)
14
+ s3 = Bracketed.process(s2)
15
+ s4 = Single.process(s3)
16
+ s4
8
17
  end
18
+
19
+ class Delimited
20
+ def initialize(str, marker, tag)
21
+ @str, @marker, @tag = str.dup, marker, tag
22
+ @buffer = ""
23
+ @cdata = ""
24
+ @state = :INITIAL
25
+ end
9
26
 
10
- def self.iterate(str, rx, tag)
11
- loop do
12
- str, more = make_string(str, rx, tag)
13
- break unless more
27
+ def status(where)
28
+ if $debug
29
+ STDERR.printf "%-11s %-7s #{@marker.inspect} \n #{' '*11} state = %-8s str = %-20s buffer = %-20s cdata = %-20s\n",
30
+ where, self.class, @state, @str.inspect, @buffer.inspect, @cdata.inspect
31
+ end
14
32
  end
15
- str
16
- end
17
33
 
18
- def self.double(str, char, tag)
19
- cdata = /(?<cdata>[^ \.,]*?)/
20
- stop = /(?<stop>[\.,]|$)/
21
- sigil = Regexp.escape(char+char)
22
- rx = make_regex(sigil, cdata, stop)
23
- str = iterate(str, rx, tag)
24
- str
25
- end
34
+ def front
35
+ @str[0]
36
+ end
26
37
 
27
- def self.single(str, char, tag)
28
- cdata = /((?<cdata>[^$ \[\*][^ ]*))/
29
- sigil = Regexp.escape(char)
30
- rx = make_regex(sigil, cdata)
31
- str = iterate(str, rx, tag)
32
- str
33
- end
38
+ def grab(n=1)
39
+ char = @str.slice!(0..(n-1)) # grab n chars
40
+ char
41
+ end
42
+
43
+ def grab_terminator
44
+ status("** grabterm 0")
45
+ @state = :LOOPING
46
+ # goes onto buffer by default
47
+ # Don't? what if searching for space_marker?
48
+ # @buffer << grab
49
+ end
50
+
51
+ def eol?
52
+ @str.empty?
53
+ end
54
+
55
+ def space?
56
+ front == " "
57
+ end
58
+
59
+ def escape?
60
+ front == "\\"
61
+ end
62
+
63
+ def terminated?
64
+ space? # Will be overridden except in Single
65
+ end
66
+
67
+ def marker?
68
+ @str.start_with?(@marker)
69
+ end
70
+
71
+ def space_marker?
72
+ @str.start_with?(" " + @marker)
73
+ end
34
74
 
35
- def self.bracket(str, char, tag)
36
- cdata = /(?<cdata>[^\]]*)\]/
37
- stop = /(?<stop> |$)/
38
- sigil = Regexp.escape(char + "[")
39
- rx = make_regex(sigil, cdata, stop)
40
- str = iterate(str, rx, tag)
41
- str
75
+ def wrap(text)
76
+ status("** wrap 0")
77
+ if text.empty?
78
+ result = @marker
79
+ result = "" if @marker[1] == "["
80
+ return result
81
+ end
82
+ "<#{@tag}>#{text}</#{@tag}>"
83
+ end
84
+
85
+ def initial
86
+ status("** init 0")
87
+ n = @marker.length
88
+ case
89
+ when escape?
90
+ status("** esc i0")
91
+ grab # backslash
92
+ status("** esc i1")
93
+ @buffer << grab # char
94
+ status("** esc i2")
95
+ when space_marker?
96
+ status("** init 1")
97
+ @buffer << grab # append the space
98
+ grab(n) # eat the marker
99
+ @state = :CDATA
100
+ when marker?
101
+ status("** init 2")
102
+ grab(n) # Eat the marker
103
+ @state = :CDATA
104
+ when eol?
105
+ status("** init 3")
106
+ @state = :FINAL
107
+ else
108
+ status("** init 4")
109
+ @state = :BUFFER
110
+ end
111
+ end
112
+
113
+ def buffer
114
+ status("** buffer 0")
115
+ @buffer << grab
116
+ @state = :LOOPING
117
+ end
118
+
119
+ def cdata
120
+ status("** cdata 0")
121
+ case
122
+ when eol?
123
+ status("** cdata 1")
124
+ if @cdata.empty?
125
+ status("** cdata 2")
126
+ @buffer << @marker unless @marker[1] == "["
127
+ else
128
+ status("** cdata 3")
129
+ @buffer << wrap(@cdata)
130
+ end
131
+ @state = :FINAL
132
+ when terminated?
133
+ status("** cdata 4")
134
+ @buffer << wrap(@cdata)
135
+ grab_terminator # "*a *b" case???
136
+ @cdata = ""
137
+ @state = :LOOPING
138
+ else
139
+ status("** cdata 5")
140
+ @cdata << grab
141
+ @state = :CDATA
142
+ end
143
+ end
144
+
145
+ def looping
146
+ n = @marker.length
147
+ case
148
+ when escape?
149
+ status("** esc l0")
150
+ grab # backslash
151
+ status("** esc l1")
152
+ @buffer << grab # char
153
+ status("** esc l2")
154
+ when space_marker?
155
+ @buffer << grab # append the space
156
+ grab(n) # eat the marker
157
+ @state = :CDATA
158
+ when eol?
159
+ @state = :FINAL
160
+ else # includes marker not preceded by space!
161
+ @buffer << grab
162
+ end
163
+ end
164
+
165
+ def handle
166
+ loop do
167
+ break if @state == :FINAL
168
+ meth = @state.downcase
169
+ send(meth)
170
+ end
171
+ return @buffer
172
+ end
173
+
174
+ def self.process(str)
175
+ bold = self.new(str, "*", "b")
176
+ sb = bold.handle
177
+ # return sb
178
+ ital = self.new(sb, "_", "i")
179
+ si = ital.handle
180
+ code = self.new(si, "`", "tt")
181
+ sc = code.handle
182
+ stri = self.new(sc, "~", "strike")
183
+ si = stri.handle
184
+ si
185
+ end
42
186
  end
43
187
 
44
- def self.make_string(str, rx, tag)
45
- md = rx.match(str)
46
- return [str, false] if md.nil?
47
- start, cdata, stop = md.values_at(:start, :cdata, :stop)
48
- str = str.sub(rx, start + "<#{tag}>" + cdata + "<\/#{tag}>" + stop)
49
- [str, true]
188
+ class Single < Delimited
189
+ # Yeah, this one is that simple
50
190
  end
51
-
52
- def self.handle(str, char, tag)
53
- s2 = double(str, char, tag) # in this order...
54
- s2 = single(s2, char, tag)
55
- s2 = bracket(s2, char, tag)
56
- s2
191
+
192
+ class Double < Delimited
193
+ def initialize(str, sigil, tag)
194
+ super
195
+ # Convention: marker is "**", sigil is "*"
196
+ @marker = sigil + sigil
197
+ end
198
+
199
+ def terminated?
200
+ terms = [" ", ".", ","]
201
+ terms.include?(front)
202
+ end
57
203
  end
58
204
 
59
- def self.format(str)
60
- s2 = str.chomp
61
- s2 = handle(s2, "*", "b")
62
- s2 = handle(s2, "_", "i")
63
- s2 = handle(s2, "`", "tt")
64
- s2 = handle(s2, "~", "strike")
65
- s2
205
+ class Bracketed < Delimited
206
+ def initialize(str, sigil, tag)
207
+ super
208
+ # Convention: marker is "*[", sigil is "*"
209
+ @marker = sigil + "["
210
+ end
211
+
212
+ def terminated?
213
+ front == "]" || eol?
214
+ end
215
+
216
+ def grab_terminator
217
+ @state = :LOOPING
218
+ grab
219
+ end
66
220
  end
67
- end
68
221
 
69
- if $0 == __FILE__
70
- # str = "**bold up front... This is **bold, __italic, and ``code."
71
- str = "*bold and *bold and **more, and even *[more boldface] and *[still more] "
72
- max = str.length
73
- # str = "*bold "
74
- s2 = Formatter.format(str)
75
- printf "%-#{max}s => %-#{max}s\n", str.inspect, s2.inspect
76
- exit
77
-
78
- strings = ["*bold",
79
- " *bold",
80
- " *bold ",
81
- "**bold.",
82
- "**bold,",
83
- "**bold",
84
- " **bold.",
85
- " **bold,",
86
- " **bold",
87
- " **bold. ",
88
- " **bold, ",
89
- " **bold ",
90
- "*[fiat lux]",
91
- " *[fiat lux]",
92
- " *[fiat lux] ",
93
- " *[fiat lux"
94
- ]
95
-
96
- max = strings.max_by {|s| s.length }
97
- max = max.length + 2
98
-
99
- strings.each do |str|
100
- s2 = Formatter.format(str)
101
- printf "%-#{max}s => %-#{max}s\n", str.inspect, s2.inspect
102
222
  end
103
223
 
104
- end
@@ -10,6 +10,8 @@ module Livetext::Helpers
10
10
  ESCAPING = { "'" => '&#39;', '&' => '&amp;', '"' => '&quot;',
11
11
  '<' => '&lt;', '>' => '&gt;' }
12
12
 
13
+ TTY = ::File.open("/dev/tty", "w")
14
+
13
15
  def friendly_error(err)
14
16
  return graceful_error(err) if self.respond_to?(:graceful_error)
15
17
  return self.parent.graceful_error(err) if self.respond_to?(:parent)
@@ -100,14 +102,14 @@ module Livetext::Helpers
100
102
  when DotCmd
101
103
  success = handle_dotcmd(line)
102
104
  when DollarDot
103
- success = handle_dollar_dot
105
+ success = handle_dollar_dot(line)
104
106
  else
105
107
  api.passthru(line) # must succeed?
106
108
  end
107
109
  success
108
110
  end
109
111
 
110
- def handle_dollar_dot
112
+ def handle_dollar_dot(line)
111
113
  indent = line.index("$") + 1
112
114
  @indentation.push(indent)
113
115
  line.sub!(/^ *\$/, "")
@@ -116,25 +118,27 @@ module Livetext::Helpers
116
118
  success
117
119
  end
118
120
 
119
- def invoke_dotcmd(name, *args)
121
+ def invoke_dotcmd(name, data="")
120
122
  # FIXME Add cmdargs stuff... depends on name, etc.
121
- retval = @main.send(name, *args)
123
+ api.data = data # should permit _ in function names at least
124
+ args = data.split
125
+ api.args = args
126
+ retval = @main.send(name) # , *args)
122
127
  retval
123
128
  rescue => err
124
129
  graceful_error(err)
125
130
  end
126
131
 
127
132
  def handle_dotcmd(line, indent = 0)
128
- # FIXME api.data is broken
129
133
  indent = @indentation.last # top of stack
130
134
  line = line.sub(/# .*$/, "") # FIXME Could be problematic?
131
- name = get_name(line)
135
+ name, data = get_name_data(line)
132
136
  success = true # Be optimistic... :P
133
137
  case
134
138
  when name == :end # special case
135
139
  graceful_error EndWithoutOpening()
136
140
  when @main.respond_to?(name)
137
- success = invoke_dotcmd(name)
141
+ success = invoke_dotcmd(name, data)
138
142
  else
139
143
  graceful_error UnknownMethod(name)
140
144
  end
@@ -145,14 +149,21 @@ module Livetext::Helpers
145
149
  return true
146
150
  end
147
151
 
148
- def get_name(line)
149
- name, data = line.split(" ", 2)
150
- name = name[1..-1] # chop off sigil
152
+ def get_name_data(line)
153
+ line = line.chomp
154
+ blank = line.index(" ")
155
+ if blank
156
+ name = line[1..(blank-1)]
157
+ data0 = line[(blank+1)..-1]
158
+ else
159
+ name = line[1..-1]
160
+ data0 = ""
161
+ end
151
162
  name = "dot_" + name if %w[include def].include?(name)
152
163
  @main.check_disallowed(name)
153
- @main.data = data
154
- @main.api.data = data
155
- name.to_sym
164
+ # @main.data = data # FIXME kill this
165
+ @main.api.data = data0 # FIXME kill this?
166
+ [name.to_sym, data0]
156
167
  end
157
168
 
158
169
  def check_disallowed(name)