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 411
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 418
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 136
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 147
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 157
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 167
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 454
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 75
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 396
def rule_htmlBlob
  repeatable
  pattern(%w( $HTMLBLOB ), lambda {
    @val[0]
  })
end
rule_inlineFunction() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 435
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 339
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 174
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 188
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 202
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 216
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 226
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 372
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 387
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 90
def rule_pre
  repeatable
  pattern(%w( $PRE ), lambda {
    @val[0]
  })
end
rule_refToken() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 347
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 34
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 50
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 40
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 403
def rule_space
  optional
  repeatable
  pattern(%w( $SPACE ), lambda {
    true
  })
end
rule_text() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 232
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 239
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 97
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 107
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 117
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 127
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 354
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