source: branches/HeuristicLab.ReingoldTilfordTreeLayout/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Formatters/SymbolicExpressionTreeLatexFormatter.cs @ 9970

Last change on this file since 9970 was 9970, checked in by bburlacu, 6 years ago

#2076: Refactored layout engine to be more generic. Svn-copied folders from trunk and readded layout files.

File size: 4.1 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Globalization;
25using System.Linq;
26using System.Text;
27using HeuristicLab.Common;
28using HeuristicLab.Core;
29
30namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
31  [Item("LaTeX/PDF Formatter", "Formatter for symbolic expression trees for use with latex.")]
32  public class SymbolicExpressionTreeLatexFormatter : NamedItem, ISymbolicExpressionTreeStringFormatter {
33    private readonly static Dictionary<string, string> symbolNameMap = new Dictionary<string, string>
34    {
35      {"ProgramRootSymbol", "Prog"},
36      {"StartSymbol","RPB"}
37    };
38    private readonly ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode> layoutEngine = new ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode>();
39    private readonly SymbolicExpressionTreeLayoutAdapter layoutAdapter = new SymbolicExpressionTreeLayoutAdapter();
40
41    public SymbolicExpressionTreeLatexFormatter() {
42      layoutEngine = new ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode>();
43    }
44
45    protected SymbolicExpressionTreeLatexFormatter(SymbolicExpressionTreeLatexFormatter original, Cloner cloner)
46      : base(original, cloner) {
47    }
48
49    public override IDeepCloneable Clone(Cloner cloner) {
50      return new SymbolicExpressionTreeLatexFormatter(this, cloner);
51    }
52
53    public string Format(ISymbolicExpressionTree symbolicExpressionTree) {
54      var layoutNodes = layoutAdapter.Convert(symbolicExpressionTree).ToList();
55      layoutEngine.Root = layoutNodes[0];
56      foreach (var ln in layoutNodes)
57        layoutEngine.AddNode(ln.Content, ln);
58      layoutEngine.CalculateLayout();
59      var nodeCoordinates = layoutEngine.GetNodeCoordinates();
60      var sb = new StringBuilder();
61      var nl = Environment.NewLine;
62      double ws = 1;
63      double hs = 0.7;
64
65      sb.Append("\\documentclass[class=minimal,border=0pt]{standalone}" + nl +
66                "\\usepackage{tikz}" + nl +
67                "\\begin{document}" + nl +
68                "\\begin{tikzpicture}" + nl +
69                "\\def\\ws{1}" + nl +
70                "\\def\\hs{0.7}" + nl);
71
72      var nodeIndices = new Dictionary<ISymbolicExpressionTreeNode, int>();
73      var nodes = symbolicExpressionTree.IterateNodesBreadth().ToList();
74      for (int i = 0; i < nodes.Count; ++i) {
75        var node = nodes[i];
76        nodeIndices.Add(node, i);
77        var coord = nodeCoordinates[node];
78        var nodeName = symbolNameMap.ContainsKey(node.Symbol.Name) ? symbolNameMap[node.Symbol.Name] : node.ToString();
79        sb.AppendLine(string.Format(CultureInfo.InvariantCulture, "\\node ({0}) at (\\ws*{1},\\hs*{2}) {{{3}}};", i, ws * coord.X, -hs * coord.Y, EscapeLatexString(nodeName)));
80      }
81
82      for (int i = 0; i < nodes.Count; ++i) {
83        foreach (var s in nodes[i].Subtrees) {
84          sb.AppendLine(string.Format(CultureInfo.InvariantCulture, "\\draw ({0}) -- ({1});", i, nodeIndices[s]));
85        }
86      }
87
88      sb.Append("\\end{tikzpicture}" + nl +
89                "\\end{document}" + nl);
90      return sb.ToString();
91    }
92
93    private static string EscapeLatexString(string s) {
94      return s.Replace("\\", "\\\\").Replace("{", "\\{").Replace("}", "\\}").Replace("_", "\\_");
95    }
96  }
97}
Note: See TracBrowser for help on using the repository browser.