module TaskJuggler::RichTextSyntaxRules

This modules contains the syntax definition for the RichTextParser. The defined syntax aims to be compatible to the most commonly used markup elements of the MediaWiki system. See en.wikipedia.org/wiki/Wikipedia:Cheatsheet for details.

Linebreaks are treated just like spaces as word separators unless it is followed by another newline or any of the start-of-line special characters. These characters start sequences that mark headlines, bullet items and such. The special meaning only gets activated when used at the start of the line.

The parser traverses the input text and creates a tree of RichTextElement objects. This is the intermediate representation that can be converted to the final output format.

Public Instance Methods

rule_blankLines() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 410
def rule_blankLines
  optional
  repeatable
  pattern(%w( $LINEBREAK ))
  pattern(%w( $SPACE ))
end
rule_blockFunction() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 417
def rule_blockFunction
  pattern(%w( $BLOCKFUNCSTART $ID !functionArguments $BLOCKFUNCEND ),
          lambda {
    args = {}
    @val[2].each { |arg| args[arg[0]] = arg[1] } if @val[2]
    el = RichTextElement.new(@richTextI, :blockfunc)
    # Data is a 2 element Array with the function name and a Hash for the
    # arguments.
    unless @richTextI.richText.functionHandler(@val[1], true)
      error('bad_block_function',
            "Unsupported block function #{@val[1]}")
    end
    el.data = [@val[1], args ]
    el
  })
end
rule_bulletList1() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 135
def rule_bulletList1
  optional
  repeatable
  pattern(%w( $BULLET1 !text ), lambda {
    RichTextElement.new(@richTextI, :bulletitem1, @val[1])
  })
  pattern(%w( !bulletList2 ), lambda {
    RichTextElement.new(@richTextI, :bulletlist2, @val[0])
  })
end
rule_bulletList2() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 146
def rule_bulletList2
  repeatable
  pattern(%w( $BULLET2 !text ), lambda {
    RichTextElement.new(@richTextI, :bulletitem2, @val[1])
  })
  pattern(%w( !bulletList3 ), lambda {
    RichTextElement.new(@richTextI, :bulletlist3, @val[0])
  })
end
rule_bulletList3() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 156
def rule_bulletList3
  repeatable
  pattern(%w( $BULLET3 !text ), lambda {
    RichTextElement.new(@richTextI, :bulletitem3, @val[1])
  })
  pattern(%w( !bulletList4 ), lambda {
    RichTextElement.new(@richTextI, :bulletlist4, @val[0])
  })
end
rule_bulletList4() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 166
def rule_bulletList4
  repeatable
  pattern(%w( $BULLET4 !text ), lambda {
    RichTextElement.new(@richTextI, :bulletitem4, @val[1])
  })
end
rule_functionArguments() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 453
def rule_functionArguments
  optional
  repeatable
  pattern(%w( $ID _= $STRING ), lambda {
    [ @val[0], @val[2] ]
  })
end
rule_headlines() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 74
def rule_headlines
  pattern(%w( !title1 ), lambda {
    @val[0]
  })
  pattern(%w( !title2 ), lambda {
    @val[0]
  })
  pattern(%w( !title3 ), lambda {
    @val[0]
  })
  pattern(%w( !title4 ), lambda {
    @val[0]
  })
end
rule_htmlBlob() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 395
def rule_htmlBlob
  repeatable
  pattern(%w( $HTMLBLOB ), lambda {
    @val[0]
  })
end
rule_inlineFunction() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 434
def rule_inlineFunction
  pattern(%w( $INLINEFUNCSTART $ID !functionArguments $INLINEFUNCEND
              !space ),
          lambda {
    args = {}
    @val[2].each { |arg| args[arg[0]] = arg[1] } if @val[2]
    el = RichTextElement.new(@richTextI, :inlinefunc)
    # Data is a 2 element Array with the function name and a Hash for the
    # arguments.
    unless @richTextI.richText.functionHandler(@val[1], false)
      error('bad_inline_function',
            "Unsupported inline function #{@val[1]}")
    end
    el.data = [@val[1], args ]
    el.appendSpace = !@val[4].nil?
    el
  })
end
rule_moreRefToken() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 338
def rule_moreRefToken
  repeatable
  optional
  pattern(%w( _| !refToken ), lambda {
    @val[1].join
  })
end
rule_numberList1() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 173
def rule_numberList1
  repeatable
  pattern(%w( $NUMBER1 !text !blankLines ), lambda {
    el = RichTextElement.new(@richTextI, :numberitem1, @val[1])
    @numberListCounter[0] += 1
    el.data = @numberListCounter.dup
    el
  })
  pattern(%w( !numberList2 ), lambda {
    @numberListCounter[1, 2] = [ 0, 0 ]
    RichTextElement.new(@richTextI, :numberlist2, @val[0])
  })
end
rule_numberList2() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 187
def rule_numberList2
  repeatable
  pattern(%w( $NUMBER2 !text !blankLines ), lambda {
    el = RichTextElement.new(@richTextI, :numberitem2, @val[1])
    @numberListCounter[1] += 1
    el.data = @numberListCounter.dup
    el
  })
  pattern(%w( !numberList3 ), lambda {
    @numberListCounter[2] = 0
    RichTextElement.new(@richTextI, :numberlist3, @val[0])
  })
end
rule_numberList3() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 201
def rule_numberList3
  repeatable
  pattern(%w( $NUMBER3 !text !blankLines ), lambda {
    el = RichTextElement.new(@richTextI, :numberitem3, @val[1])
    @numberListCounter[2] += 1
    el.data = @numberListCounter.dup
    el
  })
  pattern(%w( !numberList4 ), lambda {
    @numberListCounter[3] = 0
    RichTextElement.new(@richTextI, :numberlist4, @val[0])
  })
end
rule_numberList4() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 215
def rule_numberList4
  repeatable
  pattern(%w( $NUMBER4 !text !blankLines ), lambda {
    el = RichTextElement.new(@richTextI, :numberitem4, @val[1])
    @numberListCounter[3] += 1
    el.data = @numberListCounter.dup
    el
  })
end
rule_paragraph() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 225
def rule_paragraph
  pattern(%w( !text ), lambda {
    RichTextElement.new(@richTextI, :paragraph, @val[0])
  })
end
rule_plainText() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 371
def rule_plainText
  repeatable
  optional
  pattern(%w( !htmlBlob !space ), lambda {
    el = RichTextElement.new(@richTextI, :htmlblob, @val[0].join)
    el.appendSpace = !@val[1].nil?
    el
  })
  pattern(%w( $WORD !space ), lambda {
    el = RichTextElement.new(@richTextI, :text, @val[0])
    el.appendSpace = !@val[1].nil?
    el
  })
end
rule_plainTextWithQueries() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 386
def rule_plainTextWithQueries
  repeatable
  optional
  pattern(%w( !wordWithQueries !space ), lambda {
    @val[0][-1].appendSpace = true if @val[1]
    @val[0]
  })
end
rule_pre() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 89
def rule_pre
  repeatable
  pattern(%w( $PRE ), lambda {
    @val[0]
  })
end
rule_refToken() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 346
def rule_refToken
  repeatable
  pattern(%w( $WORD ), lambda {
    @val[0]
  })
end
rule_richtext() click to toggle source

This is the entry node.

# File lib/taskjuggler/RichText/SyntaxRules.rb, line 33
def rule_richtext
  pattern(%w( !sections . ), lambda {
    RichTextElement.new(@richTextI, :richtext, @val[0])
  })
end
rule_section() click to toggle source

The following syntax elements are all block elements that can span multiple lines.

# File lib/taskjuggler/RichText/SyntaxRules.rb, line 49
def rule_section
  pattern(%w( !headlines ), lambda {
    @val[0]
  })
  pattern(%w( $HLINE ), lambda {
    RichTextElement.new(@richTextI, :hline, @val[0])
  })
  pattern(%w( !paragraph ), lambda {
    @val[0]
  })
  pattern(%w( !pre ), lambda {
    RichTextElement.new(@richTextI, :pre, @val[0].join)
  })
  pattern(%w( !bulletList1 ), lambda {
    RichTextElement.new(@richTextI, :bulletlist1, @val[0])
  })
  pattern(%w( !numberList1 ), lambda {
    @numberListCounter = [ 0, 0, 0, 0 ]
    RichTextElement.new(@richTextI, :numberlist1, @val[0])
  })
  pattern(%w( !blockFunction ), lambda {
    @val[0]
  })
end
rule_sections() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 39
def rule_sections
  optional
  repeatable
  pattern(%w( !section !blankLines ), lambda {
    @val[0]
  })
end
rule_space() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 402
def rule_space
  optional
  repeatable
  pattern(%w( $SPACE ), lambda {
    true
  })
end
rule_text() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 231
def rule_text
  pattern(%w( !textWithSpace ), lambda {
    @val[0].last.appendSpace = false
    @val[0]
  })
end
rule_textWithSpace() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 238
def rule_textWithSpace
  repeatable
  pattern(%w( !plainTextWithLinks ), lambda {
    @val[0]
  })
  pattern(%w( !inlineFunction ), lambda {
    @val[0]
  })
  pattern(%w( $ITALIC !space !plainTextWithLinks $ITALIC !space ), lambda {
    el = RichTextElement.new(@richTextI, :italic, @val[2])
    # Since the italic end marker will disappear we need to make sure
    # there was no space before it.
    @val[2].last.appendSpace = false if @val[2].last
    el.appendSpace = !@val[4].nil?
    el
  })
  pattern(%w( $BOLD !space !plainTextWithLinks $BOLD !space ), lambda {
    el = RichTextElement.new(@richTextI, :bold, @val[2])
    @val[2].last.appendSpace = false if @val[2].last
    el.appendSpace = !@val[4].nil?
    el
  })
  pattern(%w( $CODE !space !plainTextWithLinks $CODE !space ), lambda {
    el = RichTextElement.new(@richTextI, :code, @val[2])
    @val[2].last.appendSpace = false if @val[2].last
    el.appendSpace = !@val[4].nil?
    el
  })
  pattern(%w( $BOLDITALIC !space !plainTextWithLinks $BOLDITALIC !space ),
          lambda {
    el = RichTextElement.new(@richTextI,
                        :bold, RichTextElement.new(@richTextI,
                                                   :italic, @val[2]))
    @val[2].last.appendSpace = false if @val[2].last
    el.appendSpace = !@val[4].nil?
    el
  })
  pattern(%w( $FCOLSTART !space !plainTextWithLinks $FCOLEND !space ),
          lambda {
    el = RichTextElement.new(@richTextI, :fontCol, @val[2])
    el.data = @val[0]
    el.appendSpace = !@val[4].nil?
    el
  })
end
rule_title1() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 96
def rule_title1
  pattern(%w( $TITLE1 !space !text $TITLE1END ), lambda {
    el = RichTextElement.new(@richTextI, :title1, @val[2])
    @sectionCounter[0] += 1
    @sectionCounter[1] = @sectionCounter[2] = 0
    el.data = @sectionCounter.dup
    el
  })
end
rule_title2() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 106
def rule_title2
  pattern(%w( $TITLE2 !space !text $TITLE2END ), lambda {
    el = RichTextElement.new(@richTextI, :title2, @val[2])
    @sectionCounter[1] += 1
    @sectionCounter[2] = 0
    el.data = @sectionCounter.dup
    el
  })
end
rule_title3() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 116
def rule_title3
  pattern(%w( $TITLE3 !space !text $TITLE3END ), lambda {
    el = RichTextElement.new(@richTextI, :title3, @val[2])
    @sectionCounter[2] += 1
    @sectionCounter[3] = 0
    el.data = @sectionCounter.dup
    el
  })
end
rule_title4() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 126
def rule_title4
  pattern(%w( $TITLE4 !space !text $TITLE4END ), lambda {
    el = RichTextElement.new(@richTextI, :title4, @val[2])
    @sectionCounter[3] += 1
    el.data = @sectionCounter.dup
    el
  })
end
rule_wordWithQueries() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 353
def rule_wordWithQueries
  repeatable
  pattern(%w( $WORD ), lambda {
    RichTextElement.new(@richTextI, :text, @val[0])
  })
  pattern(%w( $QUERY ), lambda {
    # The <-attributeID-> syntax is a shortcut for an embedded query
    # inline function. It can only be used within a ReportTableCell
    # context that provides a property and a scope property.
    el = RichTextElement.new(@richTextI, :inlinefunc)
    # Data is a 2 element Array with the function name and a Hash for the
    # arguments.
    el.data = ['query', { 'attribute' => @val[0] } ]
    el
  })

end