summaryrefslogtreecommitdiff
path: root/tikzit
diff options
context:
space:
mode:
authorAleks Kissinger <aleks0@gmail.com>2017-01-22 17:05:37 +0100
committerAleks Kissinger <aleks0@gmail.com>2017-01-22 17:05:37 +0100
commitbd6c301c136ca7dd8f0bc89a90ad85e0f01be01b (patch)
tree28fc690abdd3a3994387d878d0de59d16bf353e8 /tikzit
parentdf9f92b955ceb18a89b68dacdc3a2ab820a36123 (diff)
tikz output
Diffstat (limited to 'tikzit')
-rw-r--r--tikzit/src/data/edge.h3
-rw-r--r--tikzit/src/data/graph.cpp110
-rw-r--r--tikzit/src/data/graph.h9
-rw-r--r--tikzit/src/data/graphelementdata.cpp20
-rw-r--r--tikzit/src/data/graphelementdata.h2
-rw-r--r--tikzit/src/data/graphelementproperty.cpp14
-rw-r--r--tikzit/src/data/graphelementproperty.h2
-rw-r--r--tikzit/src/data/node.h2
-rw-r--r--tikzit/src/data/tikzparser.y5
-rw-r--r--tikzit/src/data/tikzparserdefs.h1
-rw-r--r--tikzit/src/test/testmain.cpp5
-rw-r--r--tikzit/src/test/testparser.cpp71
-rw-r--r--tikzit/src/test/testparser.h4
-rw-r--r--tikzit/src/test/testtikzoutput.cpp40
-rw-r--r--tikzit/src/test/testtikzoutput.h14
-rw-r--r--tikzit/tikzit.pro6
16 files changed, 291 insertions, 17 deletions
diff --git a/tikzit/src/data/edge.h b/tikzit/src/data/edge.h
index 90e624e..fba30a3 100644
--- a/tikzit/src/data/edge.h
+++ b/tikzit/src/data/edge.h
@@ -2,11 +2,10 @@
#define EDGE_H
#include "graphelementdata.h"
+#include "node.h"
#include <QObject>
-class Node;
-
class Edge : public QObject
{
Q_OBJECT
diff --git a/tikzit/src/data/graph.cpp b/tikzit/src/data/graph.cpp
index 9307d62..2480507 100644
--- a/tikzit/src/data/graph.cpp
+++ b/tikzit/src/data/graph.cpp
@@ -1,8 +1,11 @@
#include "graph.h"
+#include <QTextStream>
+
Graph::Graph(QObject *parent) : QObject(parent)
{
_data = new GraphElementData();
+ _bbox = QRectF(0,0,0,0);
}
Graph::~Graph()
@@ -53,6 +56,113 @@ const QVector<Edge*> &Graph::edges()
return _edges;
}
+QRectF Graph::bbox() const
+{
+ return _bbox;
+}
+
+bool Graph::hasBbox() {
+ return !(_bbox == QRectF(0,0,0,0));
+}
+
+void Graph::clearBbox() {
+ _bbox = QRectF(0,0,0,0);
+}
+
+QString Graph::tikz()
+{
+ QString str;
+ QTextStream code(&str);
+// [NSMutableString
+// stringWithFormat:@"\\begin{tikzpicture}%@\n",
+// [[self data] tikzList]];
+
+// if ([self hasBoundingBox]) {
+// [code appendFormat:@"\t\\path [use as bounding box] (%@,%@) rectangle (%@,%@);\n",
+// [NSNumber numberWithFloat:boundingBox.origin.x],
+// [NSNumber numberWithFloat:boundingBox.origin.y],
+// [NSNumber numberWithFloat:boundingBox.origin.x + boundingBox.size.width],
+// [NSNumber numberWithFloat:boundingBox.origin.y + boundingBox.size.height]];
+// }
+
+// // NSArray *sortedNodeList = [[nodes allObjects]
+// // sortedArrayUsingSelector:@selector(compareTo:)];
+// //NSMutableDictionary *nodeNames = [NSMutableDictionary dictionary];
+
+// if ([nodes count] > 0) [code appendFormat:@"\t\\begin{pgfonlayer}{nodelayer}\n"];
+
+// int i = 0;
+// for (Node *n in nodes) {
+// [n updateData];
+// [n setName:[NSString stringWithFormat:@"%d", i]];
+// [code appendFormat:@"\t\t\\node %@ (%d) at (%@, %@) {%@};\n",
+// [[n data] tikzList],
+// i,
+// formatFloat([n point].x, 4),
+// formatFloat([n point].y, 4),
+// [n label]
+// ];
+// i++;
+// }
+
+// if ([nodes count] > 0) [code appendFormat:@"\t\\end{pgfonlayer}\n"];
+// if ([edges count] > 0) [code appendFormat:@"\t\\begin{pgfonlayer}{edgelayer}\n"];
+
+// NSString *nodeStr;
+// for (Edge *e in edges) {
+// [e updateData];
+
+// if ([e hasEdgeNode]) {
+// nodeStr = [NSString stringWithFormat:@"node%@{%@} ",
+// [[[e edgeNode] data] tikzList],
+// [[e edgeNode] label]
+// ];
+// } else {
+// nodeStr = @"";
+// }
+
+// NSString *edata = [[e data] tikzList];
+
+// NSString *srcAnchor;
+// NSString *tgtAnchor;
+
+// if ([[e sourceAnchor] isEqual:@""]) {
+// srcAnchor = @"";
+// } else {
+// srcAnchor = [NSString stringWithFormat:@".%@", [e sourceAnchor]];
+// }
+
+// if ([[e targetAnchor] isEqual:@""]) {
+// tgtAnchor = @"";
+// } else {
+// tgtAnchor = [NSString stringWithFormat:@".%@", [e targetAnchor]];
+// }
+
+// [code appendFormat:@"\t\t\\draw%@ (%@%@) to %@(%@%@);\n",
+// ([edata isEqual:@""]) ? @"" : [NSString stringWithFormat:@" %@", edata],
+// [[e source] name],
+// srcAnchor,
+// nodeStr,
+// ([e source] == [e target]) ? @"" : [[e target] name],
+// tgtAnchor
+// ];
+// }
+
+// if ([edges count] > 0) [code appendFormat:@"\t\\end{pgfonlayer}\n"];
+
+// [code appendString:@"\\end{tikzpicture}"];
+
+// [graphLock unlock];
+
+// return code;
+ return str;
+}
+
+void Graph::setBbox(const QRectF &bbox)
+{
+ _bbox = bbox;
+}
+
Node *Graph::addNode() {
Node *n = new Node(this);
_nodes << n;
diff --git a/tikzit/src/data/graph.h b/tikzit/src/data/graph.h
index 8f466a2..37bbff9 100644
--- a/tikzit/src/data/graph.h
+++ b/tikzit/src/data/graph.h
@@ -8,6 +8,8 @@
#include <QObject>
#include <QVector>
#include <QMultiHash>
+#include <QRectF>
+#include <QString>
class Graph : public QObject
{
@@ -26,6 +28,12 @@ public:
const QVector<Node *> &nodes();
const QVector<Edge*> &edges();
+ QRectF bbox() const;
+ void setBbox(const QRectF &bbox);
+ bool hasBbox();
+ void clearBbox();
+
+ QString tikz();
signals:
public slots:
@@ -36,6 +44,7 @@ private:
QMultiHash<Node*,Edge*> inEdges;
QMultiHash<Node*,Edge*> outEdges;
GraphElementData *_data;
+ QRectF _bbox;
};
#endif // GRAPH_H
diff --git a/tikzit/src/data/graphelementdata.cpp b/tikzit/src/data/graphelementdata.cpp
index 8f81e31..ef16be2 100644
--- a/tikzit/src/data/graphelementdata.cpp
+++ b/tikzit/src/data/graphelementdata.cpp
@@ -1,6 +1,7 @@
#include "graphelementdata.h"
#include <QDebug>
+#include <QTextStream>
GraphElementData::GraphElementData(QObject *parent) : QAbstractItemModel(parent)
{
@@ -143,3 +144,22 @@ Qt::ItemFlags GraphElementData::flags(const QModelIndex &index) const
//}
+QString GraphElementData::tikz() {
+ if (_properties.length() == 0) return "";
+ QString str;
+ QTextStream code(&str);
+ code << "[";
+
+ GraphElementProperty p;
+ bool first = true;
+ foreach(p, _properties) {
+ if (!first) code << ", ";
+ code << p.tikz();
+ first = false;
+ }
+
+ code << "]";
+
+ code.flush();
+ return str;
+}
diff --git a/tikzit/src/data/graphelementdata.h b/tikzit/src/data/graphelementdata.h
index 82279cf..42f63ba 100644
--- a/tikzit/src/data/graphelementdata.h
+++ b/tikzit/src/data/graphelementdata.h
@@ -51,6 +51,8 @@ public:
void operator <<(GraphElementProperty p);
void add(GraphElementProperty p);
+
+ QString tikz();
signals:
public slots:
diff --git a/tikzit/src/data/graphelementproperty.cpp b/tikzit/src/data/graphelementproperty.cpp
index 9cc6b00..a50af58 100644
--- a/tikzit/src/data/graphelementproperty.cpp
+++ b/tikzit/src/data/graphelementproperty.cpp
@@ -1,5 +1,7 @@
#include "graphelementproperty.h"
+#include <QRegExp>
+
GraphElementProperty::GraphElementProperty ():
_key(""), _value(""), _atom(false), _keyMatch(false)
{}
@@ -43,3 +45,15 @@ bool GraphElementProperty::operator==(const GraphElementProperty &p)
{
return matches(p);
}
+
+QString GraphElementProperty::tikzEscape(QString str)
+{
+ QRegExp re("[0-9a-zA-Z<> \\-'.]*");
+ if (re.exactMatch(str)) return str;
+ else return "{" + str + "}";
+}
+
+QString GraphElementProperty::tikz() {
+ if (_atom) return tikzEscape(_key);
+ return tikzEscape(_key) + "=" + tikzEscape(_value);
+}
diff --git a/tikzit/src/data/graphelementproperty.h b/tikzit/src/data/graphelementproperty.h
index 4e8bbd1..01b6e5a 100644
--- a/tikzit/src/data/graphelementproperty.h
+++ b/tikzit/src/data/graphelementproperty.h
@@ -24,6 +24,8 @@ public:
bool matches(const GraphElementProperty &p);
bool operator==(const GraphElementProperty &p);
+ static QString tikzEscape(QString str);
+ QString tikz();
signals:
public slots:
diff --git a/tikzit/src/data/node.h b/tikzit/src/data/node.h
index 6205732..e72e9a7 100644
--- a/tikzit/src/data/node.h
+++ b/tikzit/src/data/node.h
@@ -23,8 +23,6 @@ public:
QString label() const;
void setLabel(const QString &label);
-
-
GraphElementData *data() const;
void setData(GraphElementData *data);
diff --git a/tikzit/src/data/tikzparser.y b/tikzit/src/data/tikzparser.y
index 970f5b4..b5bca35 100644
--- a/tikzit/src/data/tikzparser.y
+++ b/tikzit/src/data/tikzparser.y
@@ -246,8 +246,9 @@ optignoreprops: "[" ignoreprops "]";
boundingbox:
"\\path" optignoreprops COORD "rectangle" COORD ";"
{
- // TODO: bounding box
- //[[assembler graph] setBoundingBox:NSRectAroundPoints($3, $5)];
+ assembler->graph()->setBbox(QRectF(*$3, *$5));
+ delete $3;
+ delete $5;
};
/* vi:ft=yacc:noet:ts=4:sts=4:sw=4
diff --git a/tikzit/src/data/tikzparserdefs.h b/tikzit/src/data/tikzparserdefs.h
index b6a904b..9d4bfe8 100644
--- a/tikzit/src/data/tikzparserdefs.h
+++ b/tikzit/src/data/tikzparserdefs.h
@@ -7,6 +7,7 @@
#include "tikzgraphassembler.h"
#include <QString>
+#include <QRectF>
#include <QDebug>
struct noderef {
diff --git a/tikzit/src/test/testmain.cpp b/tikzit/src/test/testmain.cpp
index 613be7a..56491ed 100644
--- a/tikzit/src/test/testmain.cpp
+++ b/tikzit/src/test/testmain.cpp
@@ -1,5 +1,6 @@
#include "testtest.h"
#include "testparser.h"
+#include "testtikzoutput.h"
#include <QTest>
#include <QDebug>
@@ -9,8 +10,10 @@ int main(int argc, char *argv[])
{
TestTest test;
TestParser parser;
+ TestTikzOutput tikzOutput;
int r = QTest::qExec(&test, argc, argv) |
- QTest::qExec(&parser, argc, argv);
+ QTest::qExec(&parser, argc, argv) |
+ QTest::qExec(&tikzOutput, argc, argv);
if (r == 0) std::cout << "***************** All tests passed! *****************\n";
else std::cout << "***************** Some tests failed. *****************\n";
diff --git a/tikzit/src/test/testparser.cpp b/tikzit/src/test/testparser.cpp
index e978892..bbc90cf 100644
--- a/tikzit/src/test/testparser.cpp
+++ b/tikzit/src/test/testparser.cpp
@@ -54,19 +54,78 @@ void TestParser::parseEdgeGraph()
bool res = ga.parse(
"\\begin{tikzpicture}\n"
" \\begin{pgfonlayer}{nodelayer}\n"
- " \\node [style=none] (0) at (-1, -1) {};\n"
- " \\node [style=none] (1) at (0, 1) {};\n"
- " \\node [style=none] (2) at (1, -1) {};\n"
+ " \\node [style=x, {foo++}] (0) at (-1, -1) {};\n"
+ " \\node [style=y] (1) at (0, 1) {};\n"
+ " \\node [style=z] (2) at (1, -1) {};\n"
" \\end{pgfonlayer}\n"
" \\begin{pgfonlayer}{edgelayer}\n"
- " \\draw [style=diredge] (1.center) to (2.center);\n"
- " \\draw [style=diredge] (2.center) to (0.center);\n"
- " \\draw [style=diredge] (0.center) to (1.center);\n"
+ " \\draw [style=a] (1.center) to (2);\n"
+ " \\draw [style=b, foo] (2) to (0.west);\n"
+ " \\draw [style=c] (0) to (1);\n"
" \\end{pgfonlayer}\n"
"\\end{tikzpicture}\n");
QVERIFY(res);
QVERIFY(g->nodes().size() == 3);
QVERIFY(g->edges().size() == 3);
+ QVERIFY(g->nodes()[0]->data()->atom("foo++"));
+ QVERIFY(g->edges()[0]->data()->property("style") == "a");
+ QVERIFY(!g->edges()[0]->data()->atom("foo"));
+ QVERIFY(g->edges()[1]->data()->property("style") == "b");
+ QVERIFY(g->edges()[1]->data()->atom("foo"));
+ QVERIFY(g->edges()[2]->data()->property("style") == "c");
+ Node *en = g->edges()[0]->edgeNode();
+ QVERIFY(en == 0);
+ delete g;
+}
+
+void TestParser::parseEdgeNode()
+{
+ Graph *g = new Graph();
+ TikzGraphAssembler ga(g);
+ bool res = ga.parse(
+ "\\begin{tikzpicture}\n"
+ " \\begin{pgfonlayer}{nodelayer}\n"
+ " \\node [style=none] (0) at (-1, 0) {};\n"
+ " \\node [style=none] (1) at (1, 0) {};\n"
+ " \\end{pgfonlayer}\n"
+ " \\begin{pgfonlayer}{edgelayer}\n"
+ " \\draw [style=diredge] (0.center) to node[foo, bar=baz baz]{test} (1.center);\n"
+ " \\end{pgfonlayer}\n"
+ "\\end{tikzpicture}\n");
+ QVERIFY(res);
+ QVERIFY(g->nodes().size() == 2);
+ QVERIFY(g->edges().size() == 1);
+ Node *en = g->edges()[0]->edgeNode();
+ QVERIFY(en != 0);
+ QVERIFY(en->label() == "test");
+ QVERIFY(en->data()->atom("foo"));
+ QVERIFY(en->data()->property("bar") == "baz baz");
+ delete g;
+}
+
+void TestParser::parseBbox()
+{
+ Graph *g = new Graph();
+ TikzGraphAssembler ga(g);
+ bool res = ga.parse(
+ "\\begin{tikzpicture}\n"
+ " \\path [use as bounding box] (-1.5,-1.5) rectangle (1.5,1.5);\n"
+ " \\begin{pgfonlayer}{nodelayer}\n"
+ " \\node [style=white dot] (0) at (-1, -1) {};\n"
+ " \\node [style=white dot] (1) at (0, 1) {};\n"
+ " \\node [style=white dot] (2) at (1, -1) {};\n"
+ " \\end{pgfonlayer}\n"
+ " \\begin{pgfonlayer}{edgelayer}\n"
+ " \\draw [style=diredge] (1) to (2);\n"
+ " \\draw [style=diredge] (2) to (0);\n"
+ " \\draw [style=diredge] (0) to (1);\n"
+ " \\end{pgfonlayer}\n"
+ "\\end{tikzpicture}\n");
+ QVERIFY(g->nodes().size() == 3);
+ QVERIFY(g->edges().size() == 3);
+ QVERIFY(g->hasBbox());
+ QVERIFY(g->bbox() == QRectF(QPointF(-1.5,-1.5), QPointF(1.5,1.5)));
+
delete g;
}
diff --git a/tikzit/src/test/testparser.h b/tikzit/src/test/testparser.h
index 8e2e589..69dc965 100644
--- a/tikzit/src/test/testparser.h
+++ b/tikzit/src/test/testparser.h
@@ -7,11 +7,11 @@ class TestParser : public QObject
{
Q_OBJECT
private slots:
- //void initTestCase();
void parseEmptyGraph();
void parseNodeGraph();
void parseEdgeGraph();
- //void cleanupTestCase();
+ void parseEdgeNode();
+ void parseBbox();
};
#endif // TESTPARSER_H
diff --git a/tikzit/src/test/testtikzoutput.cpp b/tikzit/src/test/testtikzoutput.cpp
new file mode 100644
index 0000000..8b14bd3
--- /dev/null
+++ b/tikzit/src/test/testtikzoutput.cpp
@@ -0,0 +1,40 @@
+#include "testtikzoutput.h"
+#include "graphelementproperty.h"
+#include "graphelementdata.h"
+
+#include <QTest>
+
+void TestTikzOutput::escape()
+{
+ QVERIFY(GraphElementProperty::tikzEscape("foo") == "foo");
+ QVERIFY(GraphElementProperty::tikzEscape("foo'") == "foo'");
+ QVERIFY(GraphElementProperty::tikzEscape("foo bar") == "foo bar");
+ QVERIFY(GraphElementProperty::tikzEscape("foo.bar") == "foo.bar");
+ QVERIFY(GraphElementProperty::tikzEscape("foo-bar") == "foo-bar");
+ QVERIFY(GraphElementProperty::tikzEscape("foo >") == "foo >");
+ QVERIFY(GraphElementProperty::tikzEscape("foo <") == "foo <");
+ QVERIFY(GraphElementProperty::tikzEscape("foo+") == "{foo+}");
+ QVERIFY(GraphElementProperty::tikzEscape("foo{bar}") == "{foo{bar}}");
+}
+
+void TestTikzOutput::data()
+{
+ GraphElementData d;
+ QVERIFY(d.tikz() == "");
+ d.setAtom("foo");
+ QVERIFY(d.tikz() == "[foo]");
+ d.setAtom("bar");
+ QVERIFY(d.tikz() == "[foo, bar]");
+ d.setProperty("foo","bar");
+ QVERIFY(d.tikz() == "[foo, bar, foo=bar]");
+ d.setAtom("foo+");
+ QVERIFY(d.tikz() == "[foo, bar, foo=bar, {foo+}]");
+ d.unsetAtom("foo");
+ QVERIFY(d.tikz() == "[bar, foo=bar, {foo+}]");
+ d.unsetProperty("foo");
+ QVERIFY(d.tikz() == "[bar, {foo+}]");
+ d.unsetAtom("foo+");
+ QVERIFY(d.tikz() == "[bar]");
+ d.unsetAtom("bar");
+ QVERIFY(d.tikz() == "");
+}
diff --git a/tikzit/src/test/testtikzoutput.h b/tikzit/src/test/testtikzoutput.h
new file mode 100644
index 0000000..24c594e
--- /dev/null
+++ b/tikzit/src/test/testtikzoutput.h
@@ -0,0 +1,14 @@
+#ifndef TESTTIKZOUTPUT_H
+#define TESTTIKZOUTPUT_H
+
+#include <QObject>
+
+class TestTikzOutput : public QObject
+{
+ Q_OBJECT
+private slots:
+ void escape();
+ void data();
+};
+
+#endif // TESTTIKZOUTPUT_H
diff --git a/tikzit/tikzit.pro b/tikzit/tikzit.pro
index 3574bfd..2e7d463 100644
--- a/tikzit/tikzit.pro
+++ b/tikzit/tikzit.pro
@@ -67,10 +67,12 @@ test {
TARGET = UnitTests
SOURCES -= src/main.cpp
HEADERS += src/test/testtest.h \
- src/test/testparser.h
+ src/test/testparser.h \
+ src/test/testtikzoutput.h
SOURCES += src/test/testmain.cpp \
src/test/testtest.cpp \
- src/test/testparser.cpp
+ src/test/testparser.cpp \
+ src/test/testtikzoutput.cpp
} else {
SOURCES += src/main.cpp
}