logo

class

docCompiler::FandocToHtmlGenerator

sys::Obj
  fandoc::HtmlDocWriter
    docCompiler::HtmlGenerator
      docCompiler::FandocToHtmlGenerator
   1  //
   2  // Copyright (c) 2007, Brian Frank and Andy Frank
   3  // Licensed under the Academic Free License version 3.0
   4  //
   5  // History:
   6  //   5 May 07  Brian Frank  Creation
   7  //
   8  
   9  using compiler
  10  using fandoc
  11  
  12  **
  13  ** FandocToHtmlGenerator generates an HTML file for a standalone fandoc file
  14  **
  15  class FandocToHtmlGenerator : HtmlGenerator
  16  {
  17  
  18  //////////////////////////////////////////////////////////////////////////
  19  // Constructor
  20  //////////////////////////////////////////////////////////////////////////
  21  
  22    new make(DocCompiler compiler, Location loc, OutStream out, Doc doc)
  23      : super(compiler, loc, out)
  24    {
  25      this.doc = doc
  26    }
  27  
  28  //////////////////////////////////////////////////////////////////////////
  29  // Generator
  30  //////////////////////////////////////////////////////////////////////////
  31  
  32    override Str title()
  33    {
  34      title := doc.meta["title"]
  35      if (title != null) return title
  36      compiler.err("WARNING: Missing title", loc)
  37      return super.title
  38    }
  39  
  40    override Void header()
  41    {
  42      out.print("<ul>\n")
  43      out.print("  <li><a href='../index.html'>$docHome</a></li>\n")
  44      out.print("  <li><a href='index.html'>$compiler.pod.name</a></li>\n")
  45      out.print("  <li>$title</li>\n")
  46      out.print("</ul>\n")
  47    }
  48  
  49    override Void content()
  50    {
  51      findPrevNext
  52      prevNext
  53      out.print("<h1 class='title'>$title</h1>\n")
  54      doc.children.each |DocNode node| { node.write(this) }
  55      prevNext
  56    }
  57  
  58    override Void sidebar()
  59    {
  60      // make a quick run thru to make sure we even
  61      // have any headers for the content sidebar
  62      temp := doc.children.find |DocNode node->Bool| { return node is Heading }
  63      if (temp == null) return
  64  
  65      // we found some so print them
  66      out.print("<h2>Contents</h2>\n")
  67      out.print("<ul>\n")
  68      curLevel := 1
  69      doc.children.each |DocNode node|
  70      {
  71        heading := node as Heading
  72        if (heading != null)
  73        {
  74          id := heading.anchorId
  75          if (heading.level > curLevel)
  76          {
  77            out.print("<li><ul>\n")
  78            curLevel++
  79          }
  80          else if (heading.level < curLevel)
  81          {
  82            out.print("</ul></li>\n")
  83            curLevel--
  84          }
  85  
  86          out.print("<li>")
  87          if (id != null) out.print("<a href='#$id'>")
  88          heading.children.each |DocNode n| { n.write(this) }
  89          if (id != null) out.print("</a>")
  90          out.print("</li>\n")
  91        }
  92      }
  93      while (curLevel > 1)
  94      {
  95        out.print("</ul></li>\n")
  96        curLevel--
  97      }
  98      out.print("</ul>\n")
  99    }
 100  
 101    Void prevNext()
 102    {
 103      if (prev == null && next == null) return
 104      out.print("<div class='prevNext'>\n")
 105      if (prev != null) out.print("<div class='prev'>&lt; <a href='${prev}.html'>$prev</a></div>\n")
 106      if (next != null) out.print("<div class='next'><a href='${next}.html'>$next</a> &gt;</div>\n")
 107      out.print("</div>\n")
 108    }
 109  
 110    Void findPrevNext()
 111    {
 112      if (compiler.fandocIndex == null) return
 113  
 114      // give something easier to work with
 115      index := [,]
 116      for (i:=0; i<compiler.fandocIndex.size; i++)
 117      {
 118        v := compiler.fandocIndex[i]
 119        if (v is Uri) index.push(v)
 120        else if (v is Obj[]) index.push((v as Obj[])[0] as Uri)
 121      }
 122  
 123      // try to find prev/next
 124      for (i:=0; i<index.size; i++)
 125        if (title == index[i].toStr)
 126        {
 127          if (i > 0) prev = index[i-1]
 128          if (i < index.size-1) next = index[i+1]
 129          break;
 130        }
 131    }
 132  
 133  //////////////////////////////////////////////////////////////////////////
 134  // Fields
 135  //////////////////////////////////////////////////////////////////////////
 136  
 137    Doc doc
 138    Uri prev   // prev link if exists
 139    Uri next   // next link if exists
 140  
 141  }
 142