module Tracery
Constants
- VERSION
Public Class Methods
random()
click to toggle source
# File lib/tracery.rb, line 21 def self.random return @@rnd_proc.call end
resetRnd()
click to toggle source
# File lib/tracery.rb, line 17 def self.resetRnd setRnd(lambda { @@internal_rnd.rand }) end
setRnd(lambdaproc)
click to toggle source
# File lib/tracery.rb, line 13 def self.setRnd(lambdaproc) @@rnd_proc = lambdaproc end
Public Instance Methods
createGrammar(raw)
click to toggle source
Parses a plaintext rule in the tracery syntax
# File lib/tracery.rb, line 6 def createGrammar(raw) return Grammar.new(raw) end
createSection(start, finish, type, results, lastEscapedChar, escapedSubstring, rule, errors)
click to toggle source
TODO_: needs heavy refactoring – no nesting in ruby (ie. move entire parser to another class w/ shared state)
# File lib/tracery.rb, line 60 def createSection(start, finish, type, results, lastEscapedChar, escapedSubstring, rule, errors) if(finish - start < 1) then if(type == 1) then errors << "#{start}: empty tag" else if(type == 2) then errors << "#{start}: empty action" end end end rawSubstring = "" if(!lastEscapedChar.nil?) then rawSubstring = escapedSubstring + "\\" + rule[(lastEscapedChar+1)...finish] else rawSubstring = rule[start...finish] end results[:sections] << { type: type, raw: rawSubstring } end
parse(rule)
click to toggle source
# File lib/tracery.rb, line 83 def parse(rule) depth = 0 inTag = false results = {errors: [], sections: []} escaped = false errors = [] start = 0 escapedSubstring = "" lastEscapedChar = nil if(rule.nil?) then sections = {errors: errors, sections: []} return sections end rule.each_char.with_index do |c, i| if(!escaped) then case(c) when '[' then # Enter a deeper bracketed section if(depth == 0 && !inTag) then if(start < i) then createSection(start, i, 0, results, lastEscapedChar, escapedSubstring, rule, errors) lastEscapedChar = nil escapedSubstring = "" end start = i + 1 end depth += 1 when ']' then depth -= 1 # End a bracketed section if(depth == 0 && !inTag) then createSection(start, i, 2, results, lastEscapedChar, escapedSubstring, rule, errors) lastEscapedChar = nil escapedSubstring = "" start = i + 1 end when '#' then # Hashtag # ignore if not at depth 0, that means we are in a bracket if(depth == 0) then if(inTag) then createSection(start, i, 1, results, lastEscapedChar, escapedSubstring, rule, errors) lastEscapedChar = nil escapedSubstring = "" start = i + 1 else if(start < i) then createSection(start, i, 0, results, lastEscapedChar, escapedSubstring, rule, errors) lastEscapedChar = nil escapedSubstring = "" end start = i + 1 end inTag = !inTag end when '\\' then escaped = true; escapedSubstring = escapedSubstring + rule[start...i]; start = i + 1; lastEscapedChar = i; end else escaped = false end end #each character in rule if(start < rule.length) then createSection(start, rule.length, 0, results, lastEscapedChar, escapedSubstring, rule, errors) lastEscapedChar = nil escapedSubstring = "" end errors << ("Unclosed tag") if inTag errors << ("Too many [") if depth > 0 errors << ("Too many ]") if depth < 0 # Strip out empty plaintext sections results[:sections].select! {|section| if(section[:type] == 0 && section[:raw].empty?) then false else true end } results[:errors] = errors; return results end
parseTag(tagContents)
click to toggle source
# File lib/tracery.rb, line 25 def parseTag(tagContents) parsed = { symbol: nil, preactions: [], postactions: [], modifiers: [] } sections = parse(tagContents)[:sections] symbolSection = nil; sections.each do |section| if(section[:type] == 0) then if(symbolSection.nil?) then symbolSection = section[:raw] else raise "multiple main sections in #{tagContents}" end else parsed[:preactions].push(section) end end if(symbolSection.nil?) then # raise "no main section in #{tagContents}" else components = symbolSection.split("."); parsed[:symbol] = components.first parsed[:modifiers] = components.drop(1) end return parsed end