# html.rb: html output for internal documentation # copyright (c) 2009 by Vincent Fourmond # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details (in the COPYING file). require 'ctioga2/utils' require 'ctioga2/commands/commands' module CTioga2 module Commands module Documentation # Generation of XHTML snippets (not full pages) that document # the commands/groups and types known to CTioga2. class HTML # The Doc object the HTML class should document attr_accessor :doc # The base URL for the file where the types are documented. attr_accessor :types_url # The base URL for the file where the backends are documented. # # \todo maybe this should be turned into a directory, and each # file would document a backend on its own ? That would make # sense, but that would be rather difficult, I have to admit. attr_accessor :backends_url # The base URL for file where commands and groups are # documented. attr_accessor :commands_url def initialize(doc) @doc = doc @types_url = "types.html" @commands_url = "commands.html" @backends_url = "backends.html" @functions_url = "functions.html" end def write_page_menu(opts, out) if !opts['page-menu'] or opts['page-menu'] =~ /menu|full/i yield out end end def write_page(opts, out) if !opts['page-menu'] or opts['page-menu'] =~ /page|full/i yield out end end def write_functions(opts, out = STDOUT) funcs = @doc.functions names = funcs.keys.sort write_page_menu(opts, out) do |out| out.puts "
" out.puts "

Quick jump

" out.puts "\n" out.puts "
" end write_page(opts, out) do |out| for n in names f = funcs[n] out.puts out.puts "

#{n} - #{f.short_description}

" out.puts markup_to_html(f.description) end end end # Ouputs HTML code to document all groups and commands def write_commands(opts, out = STDOUT) cmds, groups = @doc.documented_commands if opts['snippets'] require 'yaml' snippets = begin YAML.load(IO.readlines(opts['snippets']).join()) rescue Exception => e Log::error { "Failed to load snippets file '#{opts['snippets']}'\n => #{e.inspect}" } {} end end write_page_menu(opts, out) do |out| out.puts "
" out.puts "

Quick jump

" out.puts "\n" out.puts "
" end write_page(opts, out) do |out| for g in groups out.puts out.puts "

#{g.name}

" out.puts markup_to_html(g.description) commands = cmds[g].sort {|a,b| a.name <=> b.name } out.puts "

" out.puts "Available commands:\n" out.puts commands.map {|c| "#{c.name}" }.join(' ') out.puts "

" for cmd in commands out.puts out.puts command_documentation(cmd) if snippets snpts = snippets[cmd.name] if snpts str = "" for k in snpts.keys.sort s = snpts[k] ln = s[:line].chomp # if ln[-1] == '\\' # ln = ln[0..-2] # end # Strip links from the line ln.gsub!(/]+>(.*?)<\/a>/) { || $1 } str += "
#{ln}
\n" end out.puts "
Examples...
\n
#{str}
" end end end end end end # Write a HTML table documenting all command-line options. def write_command_line_options(opts, out = STDOUT) cmds, groups = @doc.documented_commands out.puts "" for g in groups out.puts "" commands = cmds[g].sort {|a,b| a.long_option <=> b.long_option } for cmd in commands opts = cmd.option_strings link = "" out.puts "" out.puts "" out.puts "" end end out.puts "
#{g.name}
#{link}#{opts[0]}#{link}#{opts[1]}#{opts[2]}
" end # Ouputs HTML code to document all types def write_types(opts, out = STDOUT) types = @doc.types.sort.map { |d| d[1]} write_page_menu(opts, out) do |out| out.puts "
" out.puts "

Quick jump

" out.puts "
\n" out.puts "
" end write_page(opts, out) do |out| for t in types out.puts out.puts "

#{t.name}

\n" out.puts markup_to_html(t.description) out.puts # There is no need to wrap the markup # in a paragraph. end end end # Ouputs HTML code to all backends def write_backends(opts, out = STDOUT) backends = @doc.backends.sort.map { |d| d[1]} write_page_menu(opts, out) do |out| out.puts "
" out.puts "

Quick jump

" out.puts "\n" out.puts "
" end write_page(opts, out) do |out| for b in backends out.puts out.puts "

#{b.name}: #{b.long_name}

\n" out.puts markup_to_html(b.description) out.puts for param in b.param_list out.puts "

Parameter: #{param.name}

" out.puts "

/#{param.name}=#{param.type.name}

" out.puts markup_to_html(param.description) end end end end # Write a summary list of all style items def write_styles(opts, out = STDOUT) styles = Graphics::Elements::TiogaElement::styled_classes names = styles.keys.sort write_page_menu(opts, out) do |out| out.puts "
" out.puts "

Quick jump

" out.puts "\n" out.puts "
" end write_page(opts, out) do |out| for n in names out.puts "

#{n}

\n" cls = styles[n].style_class if cls aliases = cls.defined_aliases out.puts "\n" else out.puts "No specific style information" end end end end protected # The string that represents a full command def command_documentation(cmd) str = "

Command: #{cmd.name}

\n" str << "

\nSynopsis (file)\n" str << "

\n
"
          str << "#{cmd.name} "
          str << cmd.arguments.map { |arg|
            "#{arg.displayed_name}"
          }.join(' ')
          if cmd.has_options?
            if(cmd.arguments.size > 0)
              str << " "
            end
            str << "/option=..."
          end
          str << "\n"
          str << "
\n" # Command-line file synopsis str << "

\nSynopsis (command-line)\n" args = cmd.arguments.map { |arg| "#{arg.displayed_name}" }.join(' ') if cmd.has_options? args << " /option=..." end str << "

\n
"
          if cmd.short_option
            str << "-#{cmd.short_option} "
            str << args
            str << "\n"
          end
          str << "--#{cmd.long_option} "
          str << args
          str << "\n"
          str << "
" if cmd.has_options? str << "

Available options:\n" opts = cmd.optional_arguments.sort.map do |k,arg| "#{cmd.normalize_option_name(k)}\n" end str << opts.join(' ') str << "

" end # Now, the description: str << markup_to_html(cmd.long_description) return str end # Takes up an array of MarkupItem objects and returns its # equivalent in HTML format. Alternativelely, it can take a # String and feed it to MarkedUpText. # # \todo escape correctly the produced HTML code... def markup_to_html(items) if items.is_a? String mup = MarkedUpText.new(@doc, items) return markup_to_html(mup.elements) end str = "" for it in items case it when MarkedUpText::MarkupText el = nil case it.kind when :code el = "code" end if el prefix = "<#{el}>" suffix = "" else prefix = "" suffix = "" end str << "#{prefix}#{it.to_s}#{suffix}" when MarkedUpText::MarkupLink case it.target when Command link = "#{@commands_url}#command-#{it.target.name}" when Function link = "#{@functions_url}#func-#{it.target.name}" when CommandGroup link = "#{@commands_url}#group-#{it.target.id}" when CommandType link = "#{@types_url}#type-#{it.target.name}" when Data::Backends::BackendDescription link = "#{@backends_url}#backend-#{it.target.name}" when String # plain URL target link = "#{it.target}" else raise "The link target should be either a group, a command or a type, but is a #{it.target.class} (#{it.dbg.inspect})" end str << "#{it.to_s}" when MarkedUpText::MarkupItemize str << "\n" when MarkedUpText::MarkupParagraph str << "

\n#{markup_to_html(it.elements)}\n

\n" when MarkedUpText::MarkupVerbatim str << "
#{it.text}
\n" else raise "Markup #{it.class} isn't implemented yet for HTML" end end return str end end end end end