From 109e7023a321c68cb96ee402a8abaa16d79c0a80 Mon Sep 17 00:00:00 2001
From: Nicolas Marsic <nicolas.marsic@gmail.com>
Date: Thu, 17 Apr 2014 14:19:16 +0000
Subject: [PATCH] PermutationTree::toLatex \o/

---
 FunctionSpace/PermutationTree.cpp | 110 +++++++++++++++++++++++++++++-
 FunctionSpace/PermutationTree.h   |   9 +++
 2 files changed, 118 insertions(+), 1 deletion(-)

diff --git a/FunctionSpace/PermutationTree.cpp b/FunctionSpace/PermutationTree.cpp
index fb18a60d05..255a5a47bd 100644
--- a/FunctionSpace/PermutationTree.cpp
+++ b/FunctionSpace/PermutationTree.cpp
@@ -1,6 +1,5 @@
 #include <map>
 #include <fstream>
-#include <sstream>
 #include <cstring>
 
 #include "Exception.h"
@@ -368,6 +367,115 @@ string PermutationTree::toString(void) const{
   return stream.str();
 }
 
+string PermutationTree::toLatex(void) const{
+  stringstream stream;
+
+  // Small FEM //
+  stream << "%%% Automaticaly generated by SmallFem" << endl;
+
+  // Header //
+  stream << "\\documentclass[11pt]{article}" << endl << endl
+
+         << "\\usepackage{tikz}" << endl
+         << endl
+         << "\\usetikzlibrary{arrows}" << endl
+         << "\\tikzstyle{vertex} = [circle, fill = black!25, inner sep = 2pt]"
+         << endl
+         << "\\tikzstyle{line}   = [thick, black]" << endl
+         << "\\tikzstyle{arrow}  = [-stealth']" << endl << endl
+         << "\\begin{document}" << endl
+         << "\\begin{tikzpicture}";
+
+  // Options //
+  stream << "["
+         << "grow = right,"
+         << "edge from parent/.style={draw, line},"
+         << "level 1/.style={sibling distance=12em},"
+         << "level 2/.style={sibling distance=4em},"
+         << "level 3/.style={sibling distance=2em},"
+         << "level 5/.style={level distance=5em},"
+         << "]" << endl;
+
+  // Tree //
+  // Root
+  stream << "\\node[vertex]{\\phantom{$0$}}" << endl;
+
+  // Travel from root in deepFirst and add childs to stream
+  deepFirstStream(root, stream);
+
+  // Final ;
+  stream << ";" << endl << endl;
+
+  // Leaf Ids //
+  for(size_t i = 0; i < leaf.size(); i++)
+    stream << "\\node[xshift=8, yshift=10] "
+           << "at(l" << leaf[i]->leafId << ") "
+           << "{\\scriptsize $" << leaf[i]->leafId << "$};"
+           << endl;
+
+  // Footer //
+  stream << "\\end{tikzpicture}" << endl
+         << "\\end{document}"    << endl;
+
+  return stream.str();
+
+}
+
+void PermutationTree::deepFirstStream(node_t* node, stringstream& stream) const{
+  vector<size_t> permutation(getSequenceSize());
+
+  // If node is root, don't add to stream: just loop on its childs
+  if(node->myChoice == (size_t)(-1))
+    for(size_t i = 0; i < node->son.size(); i++)
+      deepFirstStream(node->son[i], stream);
+
+  // Else, insert node in stream as child //
+  else{
+    stream << "child{node[vertex]";
+
+    // If node, name it
+    if(node->son.size() == 0)
+      stream << "(l" << node->leafId << ")";
+
+    stream << "{" << node->myChoice << "}" << endl;
+
+    for(size_t i = 0; i < node->son.size(); i++)
+      deepFirstStream(node->son[i], stream);
+
+    // If leaf, child is tag and permutation //
+    if(node->son.size() == 0){
+      // Permutation
+      fillWithPermutation(node->leafId, permutation);
+
+      stream << "child{node{$[";
+
+      for(size_t j = 0; j < permutation.size() - 1; j++)
+        stream << permutation[j] << ", ";
+
+      stream << permutation[permutation.size() - 1] << "]$}"
+             << " edge from parent[arrow]" << endl;
+
+      // Tag
+      stream << "child{node[anchor=west]{" << node->tag;
+
+      // Is true orientation ?
+      if(node->tag == node->leafId)
+        stream << " (\\emph{True Orientation})";
+
+      stream << "} edge from parent[arrow]" << endl;
+
+      // Done
+      stream << "}}";
+    }
+
+    stream << "}" << endl;
+  }
+
+  // If leaf, return //
+  if(node->son.size() == 0)
+    return;
+}
+
 std::pair<size_t, char*> PermutationTree::serialize(void) const{
   // Enumerate Nodes //
   list<node_t*> node;
diff --git a/FunctionSpace/PermutationTree.h b/FunctionSpace/PermutationTree.h
index b40a488c2c..44b3c70b92 100644
--- a/FunctionSpace/PermutationTree.h
+++ b/FunctionSpace/PermutationTree.h
@@ -5,6 +5,7 @@
 #include <vector>
 #include <list>
 #include <string>
+#include <sstream>
 
 /**
    @class PermutationTree
@@ -84,6 +85,8 @@ class PermutationTree{
   std::vector<std::pair<size_t, size_t> > getAllTagsCount(void) const;
 
   std::string toString(void) const;
+  std::string toLatex(void) const;
+
   std::pair<size_t, char*> serialize(void) const;
   void                     serialize(const std::string& path) const;
 
@@ -100,6 +103,8 @@ class PermutationTree{
                          const std::vector<size_t>& sequence,
                          size_t offset);
 
+  void deepFirstStream(node_t* node, std::stringstream& stream) const;
+
   static void enumerate(node_t* node, std::list<node_t*>& listOfNode);
   static void unlink(node_t* node, unlink_t* unlink, size_t maxSize);
          void serialize(char* stream, unlink_t* unlink) const;
@@ -194,6 +199,10 @@ class PermutationTree{
    @return Returns a string describing this PermutationTree
    **
 
+   @fn PermutationTree::toLatex
+   @return Returns a string (of a Latex file) describing this PermutationTree
+   **
+
    @fn PermutationTree::serialize(void) const
 
    Serialize this PermutationTree into a byte stream
-- 
GitLab