1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
|
#!/usr/bin/env ruby -w
# encoding: UTF-8
#
# = Parser.rb -- The TaskJuggler III Project Management Software
#
# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014
# by Chris Schlaeger <cs@taskjuggler.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
#
require 'taskjuggler/TextParser'
require 'taskjuggler/RichText/Scanner'
require 'taskjuggler/RichText/SyntaxRules'
require 'taskjuggler/Log'
class TaskJuggler
# This is the parser class used by the RichText class to convert the input
# text into an intermediate representation. Most of the actual work is done
# by the generic TextParser class. The syntax description for the markup
# language is provided by the RichTextSyntaxRules module. To break the input
# String into tokens, the RichTextScanner class is used.
class RichTextParser < TextParser
include RichTextSyntaxRules
# Create the parser and initialize the rule set. _rt_ is the RichText object
# the resulting tree of RichTextElement objects should belong to.
def initialize(rti, sectionCounter = [ 0, 0, 0, 0 ], tokenSet = nil)
super()
@richTextI = rti
# These are the tokens that can be returned by the RichTextScanner.
@variables = [ :LINEBREAK, :SPACE, :WORD,
:BOLD, :ITALIC, :CODE, :BOLDITALIC, :PRE,
:HREF, :HREFEND, :REF, :REFEND, :HLINE,
:HTMLBLOB, :FCOLSTART, :FCOLEND,
:QUERY,
:INLINEFUNCSTART, :INLINEFUNCEND,
:BLOCKFUNCSTART, :BLOCKFUNCEND, :ID, :STRING,
:TITLE1, :TITLE2, :TITLE3, :TITLE4,
:TITLE1END, :TITLE2END, :TITLE3END, :TITLE4END,
:BULLET1, :BULLET2, :BULLET3, :BULLET4,
:NUMBER1, :NUMBER2, :NUMBER3, :NUMBER4
]
limitTokenSet(tokenSet)
# Load the rule set into the parser.
initRules
updateParserTables
# The sections and numbered list can each nest 3 levels deep. We use these
# counter Arrays to generate proper 1.2.3 type labels.
@sectionCounter = sectionCounter
@numberListCounter = [ 0, 0, 0, 0 ]
end
def reuse(rti, sectionCounter = [ 0, 0, 0, 0],
tokenSet = nil)
@blockedVariables = {}
@stack = nil
@richTextI = rti
@sectionCounter = sectionCounter
limitTokenSet(tokenSet)
end
# Construct the parser and get ready to read.
def open(text)
# Make sure that the last line is properly terminated with a newline.
# Multiple newlines at the end are simply ignored.
@scanner = RichTextScanner.new(text + "\n\n", Log)
@scanner.open(true)
end
# Get the next token from the scanner.
def nextToken
@scanner.nextToken
end
# Return the last fetch token again to the scanner.
def returnToken(token)
@scanner.returnToken(token)
end
end
end
|