module Livetext::Standard SimpleFormats = # Move this? { b: %w[ ], i: %w[ ], t: ["", ""], s: %w[ ] } attr_reader :_data def data=(val) @_data = val.chomp @_args = val.split rescue [] @_mixins = [] end def bits # dumb name - bold, italic, teletype, striketrough b0, b1, i0, i1, t0, t1, s0, s1 = *@_args SimpleFormats[:b] = [b0, b1] SimpleFormats[:i] = [i0, i1] SimpleFormats[:t] = [t0, t1] SimpleFormats[:s] = [s0, s1] end def backtrace arg = @_args.first @backtrace = true @backtrace = false if arg == "off" end def comment _body end def shell cmd = @_data.chomp # _errout("Running: #{cmd}") system(cmd) end def func funcname = @_args[0] _error! "Illegal name '#{funcname}'" if _disallowed?(funcname) func_def = <<-EOS def #{funcname}(param) #{_body_text(true)} end EOS Livetext::Functions.class_eval func_def end def h1; _out "

#{@_data}

"; end def h2; _out "

#{@_data}

"; end def h3; _out "

#{@_data}

"; end def h4; _out "

#{@_data}

"; end def h5; _out "
#{@_data}
"; end def h6; _out "
#{@_data}
"; end def shell! cmd = @_data.chomp system(cmd) end def errout TTY.puts @_data.chomp end def say str = _format(@_data.chomp) TTY.puts str _optional_blank_line end def banner str = _format(@_data.chomp) n = str.length - 1 puts "-"*n puts str puts "-"*n end def quit puts @body @body = "" @output.close # exit! end def cleanup @_args.each do |item| if ::File.directory?(item) system("rm -f #{item}/*") else ::FileUtils.rm(item) end end end def _def name = @_args[0] str = "def #{name}\n" raise "Illegal name '#{name}'" if _disallowed?(name) str += _body(true).join("\n") str += "\nend\n" eval str rescue => err _error!(err) end def set # FIXME bug -- .set var="RIP, Hope Gallery" assigns = @_data.chomp.split(/, */) # Do a better way? # FIXME *Must* allow for vars/functions assigns.each do |a| var, val = a.split("=") var.strip! val.strip! val = val[1..-2] if val[0] == ?" && val[-1] == ?" val = val[1..-2] if val[0] == ?' && val[-1] == ?' val = FormatLine.var_func_parse(val) @parent._setvar(var, val) end _optional_blank_line end def _assign_get_var(c, e) name = c loop do c = e.peek case c when /[a-zA-Z_\.0-9]/ name << e.next next when / =/ return name else raise "Error: did not expect #{c.inspect} in variable name" end end raise "Error: loop ended parsing variable name" end def _assign_skip_equal(e) loop { break if e.peek != " "; e.next } if e.peek == "=" e.next # skip spaces too loop { break if e.peek != " "; e.next } else raise "Error: expect equal sign" end end def _quoted_value(quote, e) value = "" loop do c = e.next break if c == quote value << c end value end def _unquoted_value(e) value = "" loop do c = e.next break if c == " " || c == "," value << c end value end def _assign_get_value c = e.peek value = "" case c when ?", ?' value = _quoted_value(c, e) else value = _unquoted_value(e) end c = e.peek value end def set_NEW line = _data.chomp e = line.each_char # enum loop do c = e.next case c when /a-z/i _assign_get_var(c, e) _assign_skip_equal when " " next else raise "set: Huh? line = #{line}" end end end def variables prefix = _args[0] file = _args[1] prefix = nil if prefix == "-" # FIXME dumb hack if file here = ::Livetext::Vars[:FileDir] + "/" lines = File.readlines(here + file) else lines = _body end lines.map! {|x| x.sub(/# .*/, "").strip } # strip comments lines.each do |line| next if line.strip.empty? var, val = line.split(" ", 2) val = FormatLine.var_func_parse(val) var = prefix + "." + var if prefix @parent._setvar(var, val) end end def reval eval _data.chomp end def heredoc var = @_args[0] str = _body.join("\n") s2 = "" str.each_line do |s| str = FormatLine.var_func_parse(s.chomp) s2 << str # + "
" end indent = @parent.indentation.last indented = " " * indent @parent._setvar(var, s2.chomp) _optional_blank_line end def _seek(file) require 'pathname' # ;) value = nil if File.exist?(file) return file else count = 1 loop do front = "../" * count count += 1 here = Pathname.new(front).expand_path.dirname.to_s break if here == "/" path = front + file value = path if File.exist?(path) break if value end end return value rescue return nil end def seek # like include, but search upward as needed file = @_args.first file = _seek(file) _error!(file, "No such include file '#{file}'") unless file @parent.process_file(file) _optional_blank_line end def in_out # FIXME dumb name! file, dest = *@_args _check_existence(file, "No such include file '#{file}'") @parent.process_file(file, dest) _optional_blank_line end def _include file = @_args.first _check_existence(file, "No such include file '#{file}'") @parent.process_file(file) _optional_blank_line end def _include_file(file) @_args = [file] _include end def inherit file = @_args.first upper = "../#{file}" good = (File.exist?(upper) || File.exist?(file)) _error!("File #{file} not found (local or parent)") unless good @parent.process_file(upper) if File.exist?(upper) @parent.process_file(file) if File.exist?(file) _optional_blank_line end # def include! # FIXME huh? # file = @_args.first # return unless File.exist?(file) # # lines = @parent.process_file(file) # #? File.delete(file) # _optional_blank_line # end def _mixin(name) @_args = [name] mixin end def mixin name = @_args.first # Expect a module name file = "#{Plugins}/" + name.downcase + ".rb" return if @_mixins.include?(name) file = "./#{name}.rb" unless File.exist?(file) if File.exist?(file) # Just keep going... else if File.dirname(File.expand_path(".")) != "/" Dir.chdir("..") { mixin } return else STDERR.puts "No such mixin '#{name}" puts @body exit! end end @_mixins << name meths = grab_file(file) modname = name.gsub("/","_").capitalize string = "module ::#{modname}; #{meths}\nend" eval(string) newmod = Object.const_get("::" + modname) self.extend(newmod) init = "init_#{name}" self.send(init) if self.respond_to? init _optional_blank_line end def copy file = @_args.first _check_existence(file, "No such file '#{file}' to copy") _out grab_file(file) _optional_blank_line end def r _out @_data.chomp # No processing at all end def raw # No processing at all (terminate with __EOF__) _raw_body {|x| _out x } # no formatting end def debug arg = @_args.first self._debug = true self._debug = false if arg == "off" end def passthru # FIXME - add check for args size (helpers); _onoff helper?? onoff = _args.first case onoff when nil; @_nopass = false when "on"; @_nopass = false when "off"; @_nopass = true else _error!("Unknown arg '#{onoff}'") end end def nopass @_nopass = true end def para # FIXME - add check for args size (helpers); _onoff helper?? onoff = _args.first case onoff when nil; @_nopara = false when "on"; @_nopara = false when "off"; @_nopara = true else _error!("Unknown arg '#{onoff}'") end end def nopara @_nopara = true end def heading _print "
" _print @_data.chomp _print "
" end def newpage _out '

' _out "

" end def invoke(str) end def mono _out "

"
    _body(true) {|line| _out line }
    _out "
" _optional_blank_line end def dlist delim = _args.first _out "
" _body do |line| line = _format(line) term, defn = line.split(delim) _out "
#{term}
" _out "
#{defn}
" end _out "
" end def old_dlist delim = _args.first _out "" _body do |line| line = _format(line) term, defn = line.split(delim) _out "" _out "" _out "" end _out "
#{term}#{defn}
" end def link url = _args.first text = _args[2..-1].join(" ") _out "#{text}" end def xtable # Borrowed from bookish - FIXME title = @_data.chomp delim = " :: " _out "
" lines = _body(true) maxw = nil lines.each do |line| line = _format(line) line.gsub!(/\n+/, "
") cells = line.split(delim) wide = cells.map {|x| x.length } maxw = [0] * cells.size maxw = maxw.map.with_index {|x, i| [x, wide[i]].max } end sum = maxw.inject(0, :+) maxw.map! {|x| (x/sum*100).floor } lines.each do |line| cells = line.split(delim) _out "" cells.each.with_index do |cell, i| _out " " end _out "" end _out "
#{cell}
" end def image name = @_args[0] _out "" end def br n = _args.first || "1" out = "" n.to_i.times { out << "
" } _out out end end