lib/RichTextElement.rb in taskjuggler-0.0.3 vs lib/RichTextElement.rb in taskjuggler-0.0.4

- old
+ new

@@ -1,11 +1,11 @@ #!/usr/bin/env ruby -w # encoding: UTF-8 # # = RichTextElement.rb -- The TaskJuggler III Project Management Software # -# Copyright (c) 2006, 2007, 2008, 2009 by Chris Schlaeger <cs@kde.org> +# Copyright (c) 2006, 2007, 2008, 2009, 2010 by Chris Schlaeger <cs@kde.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. # @@ -21,11 +21,11 @@ # Array of other RichTextElement nodes, building a tree that represents the # syntactical structure of the parsed RichText. Each node has a certain # category that identifies the content of the node. class RichTextElement - attr_reader :category, :children + attr_reader :richText, :category, :children attr_writer :data attr_accessor :appendSpace # Create a new RichTextElement node. _rt_ is the RichText object this # element belongs to. _category_ is the type of the node. It can be :title, @@ -63,14 +63,20 @@ @children = @children[0].children end self end + # Return true of the node contains an empty RichText tree. + def empty? + @category == :richtext && @children.empty? + end + + # Recursively extract the section headings from the RichTextElement and - # build fill the TableOfContents _toc_ with the gathered sections. - # _fileName_ is the base name (without .html or other suffix) of the file - # the TOCEntries should point to. + # build the TableOfContents _toc_ with the gathered sections. _fileName_ + # is the base name (without .html or other suffix) of the file the + # TOCEntries should point to. def tableOfContents(toc, fileName) number = nil case @category when :title1 number = "#{@data[0]} " @@ -148,11 +154,11 @@ when :bulletitem3 pre = ' * ' post = "\n\n" when :numberlist1 when :numberitem1 - pre = "#{@data[0]} " + pre = "#{@data[0]}. " post = "\n\n" when :numberlist2 when :numberitem2 pre = "#{@data[0]}.#{@data[1]} " post = "\n\n" @@ -161,10 +167,14 @@ pre = "#{@data[0]}.#{@data[1]}.#{@data[2]} " post = "\n\n" when :ref when :href when :blockfunc + when :inlinefunc + noChilds = true + checkHandler + pre = @richText.functionHandler(@data[0]).to_s(@data[1]) when :italic when :bold when :code when :text else @@ -240,20 +250,30 @@ post = "</li>\n" when :ref pre = "<ref data=\"#{@data}\">" post = '</ref>' when :href - pre = "<a href=\"#{@data}\" target=\"_blank\">" + pre = "<a href=\"#{@data}\" #{@richText.linkTarget ? + "target=\"#{@richText.linkTarget}\"" : + ""}>" post = '</a>' when :blockfunc pre = "<blockfunc:#{@data[0]}" if @data[1] @data[1].keys.sort.each do |key| pre += " #{key}=\"#{@data[1][key]}\"" end end post = "/>" + when :inlinefunc + pre = "<inlinefunc:#{@data[0]}" + if @data[1] + @data[1].keys.sort.each do |key| + pre += " #{key}=\"#{@data[1][key]}\"" + end + end + post = "/>" when :italic pre = '<i>' post = '</i>' when :bold pre = '<b>' @@ -281,37 +301,27 @@ end # Convert the intermediate representation into HTML elements. def to_html noChilds = false + attrs = {} + attrs['class'] = @richText.cssClass if @richText.cssClass html = case @category when :richtext - XMLElement.new('div') + XMLElement.new(@richText.blockMode ? 'div' : 'span', attrs) when :title1 - el = XMLElement.new('h1', 'id' => convertToID(children_to_s)) - if @richText.sectionNumbers - el << XMLText.new("#{@data[0]} ") - end - el + htmlTitle(1) when :title2 - el = XMLElement.new('h2', 'id' => convertToID(children_to_s)) - if @richText.sectionNumbers - el << XMLText.new("#{@data[0]}.#{@data[1]} ") - end - el + htmlTitle(2) when :title3 - el = XMLElement.new('h3', 'id' => convertToID(children_to_s)) - if @richText.sectionNumbers - el << XMLText.new("#{@data[0]}.#{@data[1]}.#{@data[2]} ") - end - el + htmlTitle(3) when :hline noChilds = true - XMLElement.new('hr') + XMLElement.new('hr', attrs) when :paragraph - XMLElement.new('p') + XMLElement.new('p', attrs) when :pre noChilds = true pre = XMLElement.new('pre') pre << XMLText.new(@children[0]) when :bulletlist1 @@ -339,20 +349,27 @@ when :numberitem3 XMLElement.new('li') when :ref XMLElement.new('a', 'href' => "#{@data}.html") when :href - XMLElement.new('a', 'href' => @data, 'target' => '_blank') + a = XMLElement.new('a', 'href' => @data.to_s) + a['target'] = @richText.linkTarget if @richText.linkTarget + a when :blockfunc noChilds = true - @richText.protocolHandler(@data[0]).to_html(@data[1]) + checkHandler + @richText.functionHandler(@data[0]).to_html(@data[1]) + when :inlinefunc + noChilds = true + checkHandler + @richText.functionHandler(@data[0]).to_html(@data[1]) when :italic XMLElement.new('i') when :bold XMLElement.new('b') when :code - XMLElement.new('code') + XMLElement.new('code', attrs) when :text noChilds = true XMLText.new(@children[0]) else raise TjException.new, "Unknown RichTextElement category #{@category}" @@ -376,10 +393,19 @@ text << c.to_s + (c.is_a?(RichTextElement) && c.appendSpace ? ' ' : '') end text end + def checkHandler + unless @data[0] && @data[0].is_a?(String) + raise "Bad RichText function '#{@data[0]}' requested" + end + if @richText.functionHandler(@data[0]).nil? + raise "No handler for #{@data[0]} registered" + end + end + # This function converts a String into a new String that only contains # characters that are acceptable for HTML tag IDs. def convertToID(text) out = '' text.each_utf8_char do |c| @@ -387,9 +413,27 @@ (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') out << '_' if c == ' ' end out.chomp('_') + end + + private + + def htmlTitle(level) + attrs = { 'id' => convertToID(children_to_s) } + attrs['class'] = @richText.cssClass if @richText.cssClass + el = XMLElement.new("h#{level}", attrs) + if @richText.sectionNumbers + s = '' + 1.upto(level) do |i| + s += '.' unless s.empty? + s += "#{@data[i - 1]}" + end + s += ' ' + el << XMLText.new(s) + end + el end end end