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 409
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 416
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 134
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 145
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 155
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 165
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 452
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 73
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 394
def rule_htmlBlob
  repeatable
  pattern(%w( $HTMLBLOB ), lambda {
    @val[0]
  })
end
rule_inlineFunction() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 433
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 337
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 172
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 186
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 200
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 214
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 224
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 370
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 385
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 88
def rule_pre
  repeatable
  pattern(%w( $PRE ), lambda {
    @val[0]
  })
end
rule_refToken() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 345
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 32
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 48
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 38
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 401
def rule_space
  optional
  repeatable
  pattern(%w( $SPACE ), lambda {
    true
  })
end
rule_text() click to toggle source
# File lib/taskjuggler/RichText/SyntaxRules.rb, line 230
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 237
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 95
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 105
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 115
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 125
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 352
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