changeset 454:dbdc9fa5d479

depgraph fixes, better design for multiple doctargets.
author Jari-Matti M?kel? <jmjm@iki.fi>
date Fri, 26 Oct 2007 01:04:09 +0200
parents 4e5b35df3060
children f92505ad18ab
files trunk/src/docgen/docgen.d trunk/src/docgen/document/writer.d trunk/src/docgen/document/writers.d trunk/src/docgen/graphutils/dotwriter.d trunk/src/docgen/graphutils/modulenamewriter.d trunk/src/docgen/graphutils/modulepathwriter.d trunk/src/docgen/graphutils/writer.d trunk/src/docgen/graphutils/writers.d trunk/src/docgen/misc/misc.d trunk/src/docgen/misc/parser.d trunk/src/docgen/sourcelisting/writer.d trunk/src/docgen/sourcelisting/writers.d trunk/src/docgen/templates/default/latex/firstpage.tpl trunk/src/docgen/templates/default/latex/graphics.tpl trunk/src/docgen/templates/default/latex/makefile.tpl trunk/src/docgen/tests/doctemplate.d trunk/src/docgen/tests/graphs.d trunk/src/docgen/tests/listing.d
diffstat 18 files changed, 106 insertions(+), 125 deletions(-) [+]
line wrap: on
line diff
--- a/trunk/src/docgen/docgen.d	Thu Oct 25 01:08:38 2007 +0300
+++ b/trunk/src/docgen/docgen.d	Fri Oct 26 01:04:09 2007 +0200
@@ -40,8 +40,11 @@
     int id = 1;
 
     Parser.loadModules(
-      options.parser.rootPaths, options.parser.importPaths,
-      null, true, -1,
+      options.parser.rootPaths,
+      options.parser.importPaths,
+      options.parser.strRegexps,
+      options.graph.includeUnlocatableModules,
+      options.graph.depth,
       (char[] fqn, char[] path, Module m) {
         if (m is null) {
           if (fqn in vertices) {
@@ -70,9 +73,9 @@
   void createDepGraph(char[] depGraphFile) {
     auto imgFile = new FileOutput(outPath(depGraphFile));
 
-    auto writer = graphFactory.createGraphWriter( docWriter );
+    auto writer = graphFactory.createGraphWriter( docWriter, GraphFormat.Dot );
 
-    writer.generateGraph(vertices.values, edges, imgFile);
+    writer.generateDepGraph(vertices.values, edges, imgFile);
 
     imgFile.close();
   }
@@ -98,7 +101,7 @@
     auto ddf = new DefaultDocumentWriterFactory(this);
 
     auto docFile = new FileOutput(outPath(docFileName));
-    docWriter = ddf.createDocumentWriter( [ docFile ] );
+    docWriter = ddf.createDocumentWriter( [ docFile ], DocFormat.LaTeX );
 
     docWriter.generateFirstPage();
     docWriter.generateTOC(modules);
@@ -150,7 +153,7 @@
     auto dlwf = new DefaultListingWriterFactory(this);
     auto docFile = new FileOutput(outPath(listingsFile));
     docWriter.setOutput([docFile]);
-    auto writer = dlwf.createListingWriter(docWriter);
+    auto writer = dlwf.createListingWriter(docWriter, DocFormat.LaTeX);
 
     /*modules.sort(
       (Module a, Module b){ return icompare(a.moduleFQN, b.moduleFQN); }
@@ -207,17 +210,16 @@
 void main(char[][] args) {
   DocGeneratorOptions options;
 
-  options.graph.graphFormat = GraphFormat.Dot;
-  options.graph.imageFormat = ImageFormat.PS;
-  options.graph.depth = 0;
+  options.graph.imageFormat = ImageFormat.PDF;
+  options.graph.depth = -1;
   options.graph.nodeColor = "tomato";
   options.graph.cyclicNodeColor = "red";
   options.graph.unlocatableNodeColor = "gray";
   options.graph.clusterColor = "blue";
-  options.graph.includeUnlocatableModules = true;
+  options.graph.includeUnlocatableModules = false;
   options.graph.highlightCyclicEdges = true;
   options.graph.highlightCyclicVertices = true;
-  options.graph.groupByPackageNames = false;
+  options.graph.groupByPackageNames = true;
   options.graph.groupByFullPackageName = false;
   
   options.listings.literateStyle = true;
@@ -234,8 +236,8 @@
   options.parser.rootPaths = [ args[1] ];
   options.parser.strRegexps = null;
 
-  options.docFormat = DocFormat.LaTeX;
-  options.commentFormat = CommentFormat.Doxygen;
+  options.outputFormats = [ DocFormat.LaTeX ];
+  options.parser.commentFormat = CommentFormat.Doxygen;
   options.outputDir = args[3];
   
 
--- a/trunk/src/docgen/document/writer.d	Thu Oct 25 01:08:38 2007 +0300
+++ b/trunk/src/docgen/document/writer.d	Fri Oct 26 01:04:09 2007 +0200
@@ -84,7 +84,7 @@
 }
 
 interface DocumentWriterFactory : WriterFactory {
-  DocumentWriter createDocumentWriter(OutputStream[] outputs);
+  DocumentWriter createDocumentWriter(OutputStream[] outputs, DocFormat outputFormat);
 }
 
 template AbstractDocumentWriter(int n, char[] format) {
--- a/trunk/src/docgen/document/writers.d	Thu Oct 25 01:08:38 2007 +0300
+++ b/trunk/src/docgen/document/writers.d	Fri Oct 26 01:04:09 2007 +0200
@@ -15,8 +15,8 @@
     super(generator);
   }
 
-  DocumentWriter createDocumentWriter(OutputStream[] outputs) {
-    switch (options.docFormat) {
+  DocumentWriter createDocumentWriter(OutputStream[] outputs, DocFormat outputFormat) {
+    switch (outputFormat) {
       case DocFormat.LaTeX:
         return new LaTeXWriter(this, outputs);
       case DocFormat.XML:
@@ -29,4 +29,4 @@
         throw new Exception("Document writer type does not exist!");
     }
   }
-}
\ No newline at end of file
+}
--- a/trunk/src/docgen/graphutils/dotwriter.d	Thu Oct 25 01:08:38 2007 +0300
+++ b/trunk/src/docgen/graphutils/dotwriter.d	Fri Oct 26 01:04:09 2007 +0200
@@ -8,6 +8,7 @@
 import tango.io.Print: Print;
 import tango.text.convert.Layout : Layout;
 import tango.io.FilePath;
+import tango.text.Util;
 
 /**
  * Creates a graph rule file for the dot utility.
@@ -17,13 +18,21 @@
     super(factory, writer);
   }
 
-  void generateGraph(Vertex[] vertices, Edge[] edges, OutputStream imageFile) {
+  void generateDepGraph(Vertex[] vertices, Edge[] edges, OutputStream imageFile) {
     auto image = new Print!(char)(new Layout!(char), imageFile);
 
     Vertex[][char[]] verticesByPckgName;
-    if (factory.options.graph.groupByFullPackageName)
-      foreach (module_; vertices)
-        verticesByPckgName[module_.name] ~= module_; // FIXME: is it name or loc?
+    if (factory.options.graph.groupByFullPackageName ||
+        factory.options.graph.groupByPackageNames) {
+      foreach (mod; vertices) {
+        auto parts = mod.name.delimit(".");
+
+        if (parts.length>1) {
+          auto pkg = parts[0..$-1].join(".");
+          verticesByPckgName[pkg] ~= mod;
+        }
+      }
+    }
 
     if (factory.options.graph.highlightCyclicVertices ||
         factory.options.graph.highlightCyclicEdges)
@@ -33,17 +42,22 @@
     char[] fn = (cast(Object)imageFile.conduit).toUtf8();
     fn = FilePath(fn).file;
 
-    fn = fn[0..$-4];
+    fn = fn[0..$-3] ~ imageFormatExts[factory.options.graph.imageFormat];
     
     writer.addGraphics(fn);
     
     image("Digraph ModuleDependencies {\n");
 
-    foreach (module_; vertices)
+    foreach (module_; vertices) {
+      auto nodeName = 
+        factory.options.graph.groupByPackageNames ?
+        module_.name.split(".")[$-1] :
+        module_.name;
+
       image.format(
         `  n{0} [label="{1}"{2}];`\n,
         module_.id,
-        module_.name,
+        nodeName,
         (module_.isCyclic && factory.options.graph.highlightCyclicVertices ?
           ",style=filled,fillcolor=" ~ factory.options.graph.nodeColor :
           (module_.type == VertexType.UnlocatableModule ?
@@ -52,6 +66,7 @@
           )
         )
       );
+    }
 
     foreach (edge; edges)
       image.format(
@@ -61,11 +76,32 @@
         (edge.isCyclic ? "[color=" ~ factory.options.graph.cyclicNodeColor ~ "]" : "")
       );
 
-    if (factory.options.graph.groupByFullPackageName)
+    if (factory.options.graph.groupByPackageNames)
+
+      if (!factory.options.graph.groupByFullPackageName) {
+        foreach (packageName, vertices; verticesByPckgName) {
+          auto name = packageName.split(".");
+
+          if (name.length > 1) {
+            char[] pkg;
+            foreach(part; name) {
+              pkg ~= part ~ ".";
+              image.format(
+                `subgraph "cluster_{0}" {{`\n`  label="{0}"`\n,
+                pkg[0..$-1],
+                pkg[0..$-1]
+              );
+            }
+            for (int i=0; i< name.length; i++) {
+              image("}\n");
+            }
+          }
+        }
+      }
       foreach (packageName, vertices; verticesByPckgName) {
         image.format(
-          `  subgraph "cluster_{0}" {{`\n`    label="{0}";color=`
-          ~ factory.options.graph.clusterColor ~ `;`\n`    `,
+          `  subgraph "cluster_{0}" {{`\n`  label="{0}";color=`
+          ~ factory.options.graph.clusterColor ~ `;`\n`  `,
           packageName,
           packageName
         );
--- a/trunk/src/docgen/graphutils/modulenamewriter.d	Thu Oct 25 01:08:38 2007 +0300
+++ b/trunk/src/docgen/graphutils/modulenamewriter.d	Fri Oct 26 01:04:09 2007 +0200
@@ -13,7 +13,7 @@
     super(factory, writer);
   }
 
-  void generateGraph(Vertex[] vertices, Edge[] edges, OutputStream imageFile) {
+  void generateDepGraph(Vertex[] vertices, Edge[] edges, OutputStream imageFile) {
 
     void doList(Vertex[] v, uint level, char[] indent = "") {
       if (!level) return;
--- a/trunk/src/docgen/graphutils/modulepathwriter.d	Thu Oct 25 01:08:38 2007 +0300
+++ b/trunk/src/docgen/graphutils/modulepathwriter.d	Fri Oct 26 01:04:09 2007 +0200
@@ -13,7 +13,7 @@
     super(factory, writer);
   }
 
-  void generateGraph(Vertex[] vertices, Edge[] edges, OutputStream imageFile) {
+  void generateDepGraph(Vertex[] vertices, Edge[] edges, OutputStream imageFile) {
 
     void doPaths(Vertex[] v, uint level, char[] indent = "") {
       if (!level) return;
--- a/trunk/src/docgen/graphutils/writer.d	Thu Oct 25 01:08:38 2007 +0300
+++ b/trunk/src/docgen/graphutils/writer.d	Fri Oct 26 01:04:09 2007 +0200
@@ -10,7 +10,7 @@
 debug import tango.io.Stdout;
 
 interface GraphWriter {
-  void generateGraph(Vertex[] vertices, Edge[] edges, OutputStream imageFile);
+  void generateDepGraph(Vertex[] vertices, Edge[] edges, OutputStream imageFile);
 }
 
 /**
@@ -60,72 +60,8 @@
       }
 }
 
-    /+
-    void analyzeGraph(Vertex[] vertices, Edge[] edges)
-    {
-    void recursive(Vertex[] modules)
-    {
-      foreach (idx, vertex; vertices)
-      {
-        uint outgoing, incoming;
-        foreach (j, edge; edges)
-        {
-          if (edge.outgoing is vertex)
-            outgoing++;
-          if (edge.incoming is vertex)
-            incoming++;
-        }
-
-        if (outgoing == 0)
-        {
-          if (incoming != 0)
-          {
-            // Vertex is a sink.
-            alias outgoing i; // Reuse
-            alias incoming j; // Reuse
-            // Remove edges.
-            for (i=j=0; i < edges.length; i++)
-              if (edges[i].incoming !is vertex)
-                edges[j++] = edges[i];
-            edges.length = j;
-            vertices = vertices[0..idx] ~ vertices[idx+1..$];
-            return recursive(modules);
-          }
-          else
-            assert(0, "orphaned module: "~vertex.getFQN()~" (has no edges in graph)"); // orphaned vertex (module) in graph
-        }
-        else if (incoming == 0)
-        {
-          // Vertex is a source
-          alias outgoing i; // Reuse
-          alias incoming j; // Reuse
-          // Remove edges.
-          for (i=j=0; i < edges.length; i++)
-            if (edges[i].outgoing !is vertex)
-              edges[j++] = edges[i];
-          edges.length = j;
-          vertices = vertices[0..idx] ~ vertices[idx+1..$];
-          return recursive(modules);
-        }
-//         else
-//         {
-//           // source && sink
-//         }
-      }
-
-      // When reaching this point it means only cylic edges and vertices are left.
-      foreach (vertex; vertices)
-        vertex.isCyclic = true;
-      foreach (edge; edges)
-        if (edge)
-          edge.isCyclic = true;
-    }
-    recursive(vertices);
-    }
-    +/
-
 interface GraphWriterFactory : WriterFactory {
-  GraphWriter createGraphWriter(DocumentWriter writer);
+  GraphWriter createGraphWriter(DocumentWriter writer, GraphFormat outputFormat);
 }
 
 abstract class AbstractGraphWriter : AbstractWriter!(GraphWriterFactory), GraphWriter {
@@ -135,4 +71,4 @@
     super(factory);
     this.writer = writer;
   }
-}
\ No newline at end of file
+}
--- a/trunk/src/docgen/graphutils/writers.d	Thu Oct 25 01:08:38 2007 +0300
+++ b/trunk/src/docgen/graphutils/writers.d	Fri Oct 26 01:04:09 2007 +0200
@@ -14,8 +14,8 @@
     super(generator);
   }
 
-  GraphWriter createGraphWriter(DocumentWriter writer) {
-    switch (options.graph.graphFormat) {
+  GraphWriter createGraphWriter(DocumentWriter writer, GraphFormat outputFormat) {
+    switch (outputFormat) {
       case GraphFormat.Dot:
         return new DotWriter(this, writer);
       case GraphFormat.ModuleNames:
@@ -26,4 +26,4 @@
         throw new Exception("Graph writer type does not exist!");
     }
   }
-}
\ No newline at end of file
+}
--- a/trunk/src/docgen/misc/misc.d	Thu Oct 25 01:08:38 2007 +0300
+++ b/trunk/src/docgen/misc/misc.d	Fri Oct 26 01:04:09 2007 +0200
@@ -31,11 +31,11 @@
   PNG,
   SVG,
   GIF,
-  PS
+  PDF
 }
 
 /** Image format extensions. */
-const imageFormatExts = [ "png", "svg", "gif", "ps" ];
+const imageFormatExts = [ "png", "svg", "gif", "pdf" ];
 
 /** Supported graph writers. */
 enum GraphFormat {
@@ -45,7 +45,6 @@
 }
 
 struct GraphOptions {
-  GraphFormat graphFormat;
   ImageFormat imageFormat;
   uint depth;
   char[] nodeColor = "tomato";
@@ -88,14 +87,15 @@
   char[][] rootPaths;
   /// regexps for excluding modules
   char[][] strRegexps;
+  /// comment format [comment parser]
+  CommentFormat commentFormat;
 }
 
 struct DocGeneratorOptions {
   /// location for the generated output
   char[] outputDir;
 
-  DocFormat docFormat;
-  CommentFormat commentFormat;
+  DocFormat[] outputFormats;
   
   GraphOptions graph;
   ListingOptions listings;
--- a/trunk/src/docgen/misc/parser.d	Thu Oct 25 01:08:38 2007 +0300
+++ b/trunk/src/docgen/misc/parser.d	Fri Oct 26 01:04:09 2007 +0200
@@ -145,7 +145,7 @@
 
           if (loaded_mod !is null) {
             idg(loaded_mod, mod);
-          } else {
+          } else if (IncludeUnlocatableModules) {
             auto tmp = new Module(null, true);
             tmp.moduleFQN = replace(moduleFQN_.dup, dirSep, '.');
             idg(tmp, mod);
--- a/trunk/src/docgen/sourcelisting/writer.d	Thu Oct 25 01:08:38 2007 +0300
+++ b/trunk/src/docgen/sourcelisting/writer.d	Fri Oct 26 01:04:09 2007 +0200
@@ -15,5 +15,5 @@
 }
 
 interface ListingWriterFactory : WriterFactory {
-  ListingWriter createListingWriter(DocumentWriter writer);
+  ListingWriter createListingWriter(DocumentWriter writer, DocFormat outputFormat);
 }
--- a/trunk/src/docgen/sourcelisting/writers.d	Thu Oct 25 01:08:38 2007 +0300
+++ b/trunk/src/docgen/sourcelisting/writers.d	Fri Oct 26 01:04:09 2007 +0200
@@ -15,8 +15,8 @@
     super(generator);
   }
 
-  ListingWriter createListingWriter(DocumentWriter writer) {
-    switch (options.docFormat) {
+  ListingWriter createListingWriter(DocumentWriter writer, DocFormat outputFormat) {
+    switch (outputFormat) {
       case DocFormat.LaTeX:
         return new LaTeXWriter(this, writer);
       case DocFormat.XML:
@@ -29,4 +29,4 @@
         throw new Exception("Listing writer type does not exist!");
     }
   }
-}
\ No newline at end of file
+}
--- a/trunk/src/docgen/templates/default/latex/firstpage.tpl	Thu Oct 25 01:08:38 2007 +0300
+++ b/trunk/src/docgen/templates/default/latex/firstpage.tpl	Fri Oct 26 01:04:09 2007 +0200
@@ -3,6 +3,7 @@
 \usepackage{{makeidx}
 \usepackage{{fancyhdr}
 \usepackage{{graphicx}
+\usepackage{{hyperref}
 \usepackage{{multicol}
 \usepackage{{float}
 \usepackage{{textcomp}
@@ -25,6 +26,7 @@
   columns=fixed,
   basicstyle=\small
 }
+\hypersetup{{backref,colorlinks=true}
 \makeindex
 \setcounter{{tocdepth}{{1}
 \newcommand{{\clearemptydoublepage}{{\newpage{{\pagestyle{{empty}\cleardoublepage}}
--- a/trunk/src/docgen/templates/default/latex/graphics.tpl	Thu Oct 25 01:08:38 2007 +0300
+++ b/trunk/src/docgen/templates/default/latex/graphics.tpl	Fri Oct 26 01:04:09 2007 +0200
@@ -1,1 +1,1 @@
-\includegraphics{{{0}}
\ No newline at end of file
+\includegraphics[width=1\textwidth,height=1\textheight,keepaspectratio]{{{0}}
--- a/trunk/src/docgen/templates/default/latex/makefile.tpl	Thu Oct 25 01:08:38 2007 +0300
+++ b/trunk/src/docgen/templates/default/latex/makefile.tpl	Fri Oct 26 01:04:09 2007 +0200
@@ -1,10 +1,10 @@
 #!/bin/sh
 
 for i in *.dot; do
-  F=`echo $i|sed 's/dot/ps/'`
-  dot $i -Tps2 -o$F
-  ps2pdf $F
+  F=`echo $i|sed 's/dot/pdf/'`
+  dot $i -Tpdf -o$F
 done
 
 pdflatex document.tex
+makeindex document
 pdflatex document.tex
--- a/trunk/src/docgen/tests/doctemplate.d	Thu Oct 25 01:08:38 2007 +0300
+++ b/trunk/src/docgen/tests/doctemplate.d	Fri Oct 26 01:04:09 2007 +0200
@@ -12,12 +12,12 @@
 //@unittest
 void doctemplate1() {
   auto gen = new TestDocGenerator;
-  gen.options.docFormat = DocFormat.LaTeX;
+  gen.options.outputFormats = [ DocFormat.LaTeX ];
   auto fname = "doctemplate.tex";
   
   auto gwf = new DefaultDocumentWriterFactory(gen);
   auto file = new FileConduit("docgen/teststuff/" ~ fname, FileConduit.WriteCreate);
-  auto writer = gwf.createDocumentWriter( [ file ] );
+  auto writer = gwf.createDocumentWriter( [ file ], DocFormat.LaTeX );
   
   writer.generateFirstPage();
   writer.generateTOC(null);
--- a/trunk/src/docgen/tests/graphs.d	Thu Oct 25 01:08:38 2007 +0300
+++ b/trunk/src/docgen/tests/graphs.d	Fri Oct 26 01:04:09 2007 +0200
@@ -15,7 +15,6 @@
   auto gen = new TestDocGenerator;
   gen.options.graph.highlightCyclicVertices = true;
   gen.options.graph.imageFormat = ImageFormat.SVG;
-  gen.options.graph.graphFormat = GraphFormat.Dot;
   //gen.options.graph.graphFormat = GraphFormat.ModuleNames;
   //gen.options.graph.graphFormat = GraphFormat.ModulePaths;
   gen.options.graph.depth = 5;
@@ -23,9 +22,12 @@
   auto gwf = new DefaultGraphWriterFactory(gen);
   auto file = new FileConduit("docgen/teststuff/" ~ fname, FileConduit.WriteCreate);
   auto file2 = new FileConduit("docgen/teststuff/" ~ fname ~ "-2", FileConduit.WriteCreate);
-  auto writer = gwf.createGraphWriter( ddf.createDocumentWriter( [ file2 ] ) );
+  auto writer = gwf.createGraphWriter(
+    ddf.createDocumentWriter( [ file2 ], DocFormat.LaTeX),
+    GraphFormat.Dot
+  );
   
-  writer.generateGraph(vertices, edges, file);
+  writer.generateDepGraph(vertices, edges, file);
   
   file.close();
   file2.close();
@@ -107,9 +109,8 @@
 void graph5() {
   auto gen = new TestDocGenerator;
   gen.options.graph.highlightCyclicVertices = true;
-  gen.options.graph.graphFormat = GraphFormat.Dot;
-  gen.options.graph.imageFormat = ImageFormat.SVG;
-  gen.options.docFormat = DocFormat.LaTeX;
+  gen.options.graph.imageFormat = ImageFormat.PDF;
+  gen.options.outputFormats = [ DocFormat.LaTeX ];
   auto fname = "dependencies.tex";
   auto imgFname = "depgraph.dot";
   
@@ -135,9 +136,12 @@
     modules
   );
 
-  auto writer = gwf.createGraphWriter( ddf.createDocumentWriter( [ file ] ) );
+  auto writer = gwf.createGraphWriter(
+    ddf.createDocumentWriter( [ file ], DocFormat.LaTeX ),
+    GraphFormat.Dot
+  );
   
-  writer.generateGraph(vertices.values, edges, imgFile);
+  writer.generateDepGraph(vertices.values, edges, imgFile);
   
   file.close();
   imgFile.close();
--- a/trunk/src/docgen/tests/listing.d	Thu Oct 25 01:08:38 2007 +0300
+++ b/trunk/src/docgen/tests/listing.d	Fri Oct 26 01:04:09 2007 +0200
@@ -15,7 +15,7 @@
 //@unittest
 void listing1() {
   auto gen = new TestDocGenerator;
-  gen.options.docFormat = DocFormat.LaTeX;
+  gen.options.outputFormats = [ DocFormat.LaTeX ];
   auto fname = "files.tex";
   
   auto ddf = new DefaultDocumentWriterFactory(gen);
@@ -38,7 +38,8 @@
     
     auto srcFile = new FileConduit(mod.filePath);
     auto dstFile = new FileConduit("docgen/teststuff/_" ~ dstFname ~ ".d", FileConduit.WriteCreate);
-    auto writer = dlwf.createListingWriter( ddf.createDocumentWriter( [ file ] ) );
+    auto writer = dlwf.createListingWriter( ddf.createDocumentWriter( [ file ],
+          DocFormat.LaTeX ), DocFormat.LaTeX );
     
     writer.generateListing(srcFile, dstFile, mod.moduleFQN);