mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
LivePreview: smart live preview for sequence diagram
This commit is contained in:
parent
bf51b7b117
commit
2bf36319d1
@ -1421,6 +1421,8 @@ var setPreviewEnabled = function(enabled) {
|
|||||||
previewDiv.style.display = 'none';
|
previewDiv.style.display = 'none';
|
||||||
previewDiv.innerHTML = '';
|
previewDiv.innerHTML = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clearMarkRectDivs();
|
||||||
};
|
};
|
||||||
|
|
||||||
var previewCodeBlock = function(id, lang, text, isLivePreview) {
|
var previewCodeBlock = function(id, lang, text, isLivePreview) {
|
||||||
@ -1737,17 +1739,12 @@ var findNodeWithText = function(node, text, isMatched) {
|
|||||||
|
|
||||||
// Draw a rectangle to mark @rect.
|
// Draw a rectangle to mark @rect.
|
||||||
var markNode = function(rect) {
|
var markNode = function(rect) {
|
||||||
|
clearMarkRectDivs();
|
||||||
|
|
||||||
if (!rect) {
|
if (!rect) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var nodes = document.getElementsByClassName(VMarkRectDivClass);
|
|
||||||
while (nodes.length > 0) {
|
|
||||||
var n = nodes[0];
|
|
||||||
n.outerHTML = '';
|
|
||||||
delete n;
|
|
||||||
}
|
|
||||||
|
|
||||||
var div = document.createElement('div');
|
var div = document.createElement('div');
|
||||||
div.id = 'markrect_' + Date.now();
|
div.id = 'markrect_' + Date.now();
|
||||||
div.classList.add(VMarkRectDivClass);
|
div.classList.add(VMarkRectDivClass);
|
||||||
@ -1765,3 +1762,12 @@ var markNode = function(rect) {
|
|||||||
+ 'if (node) { node.outerHTML = ""; delete node; }',
|
+ 'if (node) { node.outerHTML = ""; delete node; }',
|
||||||
3000);
|
3000);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var clearMarkRectDivs = function() {
|
||||||
|
var nodes = document.getElementsByClassName(VMarkRectDivClass);
|
||||||
|
while (nodes.length > 0) {
|
||||||
|
var n = nodes[0];
|
||||||
|
n.outerHTML = '';
|
||||||
|
delete n;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@ -193,21 +193,21 @@ static bool tryClassDiagram(QString &p_keyword, QString &p_hints, bool &p_isRege
|
|||||||
{
|
{
|
||||||
Q_UNUSED(p_isRegex);
|
Q_UNUSED(p_isRegex);
|
||||||
|
|
||||||
// class ABC #Pink {
|
// class ABC #Pink
|
||||||
static QRegExp classDef1("^\\s*(?:class|(?:abstract(?:\\s+class)?)|interface|annotation|enum)\\s*"
|
static QRegExp classDef1("^\\s*(?:class|(?:abstract(?:\\s+class)?)|interface|annotation|enum)\\s+"
|
||||||
"(?!class)(\\w+)\\s*.*");
|
"(?!class)(\\w+)");
|
||||||
if (classDef1.indexIn(p_keyword) >= 0) {
|
if (classDef1.indexIn(p_keyword) >= 0) {
|
||||||
p_keyword = classDef1.cap(1);
|
p_keyword = classDef1.cap(1);
|
||||||
p_hints = "id";
|
p_hints = "id";
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// class "ABC DEF" as AD #Pink {
|
// class "ABC DEF" as AD #Pink
|
||||||
static QRegExp classDef2("^\\s*(?:class|(?:abstract(?:\\s+class)?)|interface|annotation|enum)\\s*"
|
static QRegExp classDef2("^\\s*(?:class|(?:abstract(?:\\s+class)?)|interface|annotation|enum)\\s+"
|
||||||
"\"([^\"]+)\"\\s*(?:\\bas (\\w+))?.*");
|
"\"([^\"]+)\"\\s*(?:\\bas\\s+(\\w+))?");
|
||||||
if (classDef2.indexIn(p_keyword) >= 0) {
|
if (classDef2.indexIn(p_keyword) >= 0) {
|
||||||
if (classDef2.cap(2).isEmpty()) {
|
if (classDef2.cap(2).isEmpty()) {
|
||||||
p_keyword = classDef2.cap(1);
|
p_keyword = classDef2.cap(1).trimmed();
|
||||||
} else {
|
} else {
|
||||||
p_keyword = classDef2.cap(2);
|
p_keyword = classDef2.cap(2);
|
||||||
}
|
}
|
||||||
@ -216,24 +216,23 @@ static bool tryClassDiagram(QString &p_keyword, QString &p_hints, bool &p_isRege
|
|||||||
}
|
}
|
||||||
|
|
||||||
// class01 "1" *-- "many" class02 : contains 4 >
|
// class01 "1" *-- "many" class02 : contains 4 >
|
||||||
static QRegExp relation("^\\s*(?:(\\w+)|\"([^\"]+)\")\\s+"
|
static QRegExp relation("^\\s*(?:(\\w+)|\"([^\"]+)\")\\s*"
|
||||||
"(?:\"[^\"]+\"\\s+)?"
|
"(?:\"[^\"]+\"\\s*)?"
|
||||||
"(?:<\\||[*o<#x}+^])?" "(?:-+|\\.+)" "(?:\\|>|[*o>#x{+^])?\\s+"
|
"(?:<\\||[*o<#x}+^])?" "(?:-+|\\.+)" "(?:\\|>|[*o>#x{+^])?\\s*"
|
||||||
"(?:\"[^\"]+\"\\s+)?"
|
"(?:\"[^\"]+\"\\s*)?"
|
||||||
"(?:(\\w+)|\"([^\"]+)\")\\s*"
|
"(?:(\\w+)|\"([^\"]+)\")\\s*"
|
||||||
"(?::(.+))?");
|
"(?::(.+))?");
|
||||||
if (relation.indexIn(p_keyword) >= 0) {
|
if (relation.indexIn(p_keyword) >= 0) {
|
||||||
QString note(relation.cap(5));
|
if (relation.cap(5).isEmpty()) {
|
||||||
if (note.isEmpty()) {
|
|
||||||
QString class2 = relation.cap(3);
|
QString class2 = relation.cap(3);
|
||||||
if (class2.isEmpty()) {
|
if (class2.isEmpty()) {
|
||||||
class2 = relation.cap(4);
|
class2 = relation.cap(4).trimmed();
|
||||||
}
|
}
|
||||||
|
|
||||||
p_keyword = class2;
|
p_keyword = class2;
|
||||||
p_hints = "id";
|
p_hints = "id";
|
||||||
} else {
|
} else {
|
||||||
p_keyword = note.trimmed();
|
p_keyword = relation.cap(5).trimmed();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -257,7 +256,7 @@ static bool tryClassDiagram(QString &p_keyword, QString &p_hints, bool &p_isRege
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// note left on link: message
|
// note left on link #Pink : message
|
||||||
// note left on link
|
// note left on link
|
||||||
// node on link: message
|
// node on link: message
|
||||||
// MUST before next rule "note".
|
// MUST before next rule "note".
|
||||||
@ -270,11 +269,13 @@ static bool tryClassDiagram(QString &p_keyword, QString &p_hints, bool &p_isRege
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// note top of Object: message
|
// note top of Object #Pink : message
|
||||||
// note top of Object
|
// note top of Object
|
||||||
// note top: message
|
// note top: message
|
||||||
static QRegExp note("^\\s*note\\s+(?:left|top|right|bottom)"
|
// hnote and rnote for sequence diagram.
|
||||||
"(?:\\s+of\\s+(\\w+))?\\s*"
|
static QRegExp note("^\\s*[hr]?note\\s+(?:left|top|right|bottom)"
|
||||||
|
"(?:\\s+of\\s+(\\w+))?"
|
||||||
|
"[^:]*"
|
||||||
"(?::(.*))?");
|
"(?::(.*))?");
|
||||||
if (note.indexIn(p_keyword) >= 0) {
|
if (note.indexIn(p_keyword) >= 0) {
|
||||||
p_keyword = note.cap(2).trimmed();
|
p_keyword = note.cap(2).trimmed();
|
||||||
@ -288,16 +289,16 @@ static bool tryClassDiagram(QString &p_keyword, QString &p_hints, bool &p_isRege
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// note "a floating note" as N1
|
// note "a floating note" as N1 #Pink
|
||||||
// note as N1
|
// note as N1
|
||||||
static QRegExp note2("^\\s*note\\s+(?:\"([^\"]*)\"\\s+)?as\\s+\\w+\\s*");
|
static QRegExp note2("^\\s*note\\s+(?:\"([^\"]*)\"\\s+)?as\\s+\\w+");
|
||||||
if (note2.indexIn(p_keyword) >= 0) {
|
if (note2.indexIn(p_keyword) >= 0) {
|
||||||
p_keyword = note2.cap(1);
|
p_keyword = note2.cap(1).trimmed();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// end note
|
// end note
|
||||||
static QRegExp note3("^\\s*end note\\s*$");
|
static QRegExp note3("^\\s*end ?note\\s*$");
|
||||||
if (note3.indexIn(p_keyword) >= 0) {
|
if (note3.indexIn(p_keyword) >= 0) {
|
||||||
p_keyword.clear();
|
p_keyword.clear();
|
||||||
return true;
|
return true;
|
||||||
@ -355,17 +356,26 @@ static bool tryActivityDiagram(QString &p_keyword, QString &p_hints, bool &p_isR
|
|||||||
|
|
||||||
// Activity.
|
// Activity.
|
||||||
// multiple lines;
|
// multiple lines;
|
||||||
static QRegExp activity2("^\\s*(.+)[;|<>/\\]}]\\s*$");
|
static QRegExp activity2("^\\s*(.+)([;|<>/\\]}])\\s*$");
|
||||||
if (activity2.indexIn(p_keyword) >= 0) {
|
if (activity2.indexIn(p_keyword) >= 0) {
|
||||||
p_keyword = activity2.cap(1).trimmed();
|
QString word = activity2.cap(1);
|
||||||
|
QChar end = activity2.cap(2)[0];
|
||||||
|
if (end != ';' && !word.isEmpty()) {
|
||||||
|
// || << >> // ]] }} are not legal.
|
||||||
|
if (word[word.size() - 1] == end) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p_keyword = word.trimmed();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// start, stop, end, endif, repeat, fork, fork again, end fork, },
|
// start, stop, end, endif, repeat, fork, fork again, end fork, },
|
||||||
// detach
|
// detach
|
||||||
static QRegExp start("^\\s*(?:start|stop|end|endif|repeat|"
|
static QRegExp keywords("^\\s*(?:start|stop|end|endif|repeat|"
|
||||||
"fork(?:\\s+again)?|end\\s+fork|\\}|detach)\\s*$");
|
"fork(?:\\s+again)?|end\\s+fork|\\}|detach)\\s*$");
|
||||||
if (start.indexIn(p_keyword) >= 0) {
|
if (keywords.indexIn(p_keyword) >= 0) {
|
||||||
p_keyword.clear();
|
p_keyword.clear();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -426,6 +436,143 @@ static bool tryActivityDiagram(QString &p_keyword, QString &p_hints, bool &p_isR
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool trySequenceDiagram(QString &p_keyword, QString &p_hints, bool &p_isRegex)
|
||||||
|
{
|
||||||
|
Q_UNUSED(p_isRegex);
|
||||||
|
Q_UNUSED(p_hints);
|
||||||
|
|
||||||
|
// participant ABC #Pink
|
||||||
|
// participant "ABC DEF" as AD #Pink
|
||||||
|
static QRegExp participant1("^\\s*(?:participant|actor|boundary|control|entity|database)\\s+"
|
||||||
|
"(?:(\\w+)|\"([^\"]+)\"\\s*(?:\\bas\\s+\\w+)?)");
|
||||||
|
if (participant1.indexIn(p_keyword) >= 0) {
|
||||||
|
p_keyword = participant1.cap(1);
|
||||||
|
if (p_keyword.isEmpty()) {
|
||||||
|
p_keyword = participant1.cap(2).trimmed();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// "abc" ->> "def" : Authentication
|
||||||
|
static QRegExp message("^\\s*(?:\\w+|\"[^\"]+\")\\s*"
|
||||||
|
"[-<>x\\\\/o]+\\s*"
|
||||||
|
"(?:\\w+|\"[^\"]+\")\\s*"
|
||||||
|
":\\s*(.+)");
|
||||||
|
if (message.indexIn(p_keyword) >= 0) {
|
||||||
|
p_keyword = message.cap(1).trimmed();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// autonumber
|
||||||
|
static QRegExp autonum("^\\s*autonumber\\s+");
|
||||||
|
if (autonum.indexIn(p_keyword) >= 0) {
|
||||||
|
p_keyword.clear();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// newpage
|
||||||
|
static QRegExp newpage("^\\s*newpage\\s+(.+)");
|
||||||
|
if (newpage.indexIn(p_keyword) >= 0) {
|
||||||
|
p_keyword = newpage.cap(1).trimmed();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// alt, else, group, loop ABCDEFG
|
||||||
|
static QRegExp group1("^\\s*(?:alt|else|group|loop)\\s+(.*)");
|
||||||
|
if (group1.indexIn(p_keyword) >= 0) {
|
||||||
|
p_keyword = group1.cap(1).trimmed();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// note over bob, alice #Pink:
|
||||||
|
// ret over bob, alice : init
|
||||||
|
static QRegExp noteon("^\\s*(?:[hr]?note|ref)\\s+over\\s+"
|
||||||
|
"(\\w+)[^:]*"
|
||||||
|
"(?::(.+))?");
|
||||||
|
if (noteon.indexIn(p_keyword) >= 0) {
|
||||||
|
p_keyword = noteon.cap(2).trimmed();
|
||||||
|
if (p_keyword.isEmpty()) {
|
||||||
|
p_keyword = noteon.cap(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Divider.
|
||||||
|
// == Initialization ==
|
||||||
|
static QRegExp divider("^\\s*==\\s*([^=]*)==\\s*$");
|
||||||
|
if (divider.indexIn(p_keyword) >= 0) {
|
||||||
|
p_keyword = divider.cap(1).trimmed();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delay.
|
||||||
|
// ... 5 minutes latter ...
|
||||||
|
static QRegExp delay("^\\s*\\.\\.\\.(?:(.+)\\.\\.\\.)?\\s*$");
|
||||||
|
if (delay.indexIn(p_keyword) >= 0) {
|
||||||
|
p_keyword = delay.cap(1).trimmed();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// activate A
|
||||||
|
static QRegExp activate("^\\s*(?:(?:de)?activate|destroy)\\s+"
|
||||||
|
"(?:(\\w+)|\"([^\"]+)\")");
|
||||||
|
if (activate.indexIn(p_keyword) >= 0) {
|
||||||
|
p_keyword = activate.cap(1);
|
||||||
|
if (p_keyword.isEmpty()) {
|
||||||
|
p_keyword = activate.cap(2).trimmed();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create control ABC
|
||||||
|
static QRegExp create("^\\s*create\\s+(?:\\w+\\s+)?"
|
||||||
|
"(?:(\\w+)|\"([^\"]+)\")");
|
||||||
|
if (create.indexIn(p_keyword) >= 0) {
|
||||||
|
p_keyword = create.cap(1);
|
||||||
|
if (p_keyword.isEmpty()) {
|
||||||
|
p_keyword = create.cap(2).trimmed();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Incoming and outgoing message.
|
||||||
|
static QRegExp incoming("^\\s*\\[[-<>ox]+\\s*"
|
||||||
|
"(?:\\w+|\"[^\"]+\")\\s*"
|
||||||
|
":\\s*(.+)");
|
||||||
|
if (incoming.indexIn(p_keyword) >= 0) {
|
||||||
|
p_keyword = incoming.cap(1).trimmed();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QRegExp outgoing("^\\s*(?:\\w+|\"[^\"]+\")\\s*"
|
||||||
|
"[-<>ox]+\\]\\s*"
|
||||||
|
":\\s*(.+)");
|
||||||
|
if (outgoing.indexIn(p_keyword) >= 0) {
|
||||||
|
p_keyword = outgoing.cap(1).trimmed();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// box "Internal Service" #Pink
|
||||||
|
static QRegExp box("^\\s*box(?:\\s+\"([^\"]+)\")?\\s*");
|
||||||
|
if (box.indexIn(p_keyword) >= 0) {
|
||||||
|
p_keyword = box.cap(1).trimmed();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// end box
|
||||||
|
static QRegExp endbox("^\\s*end ?box\\s*$");
|
||||||
|
if (endbox.indexIn(p_keyword) >= 0) {
|
||||||
|
p_keyword.clear();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
QString VPlantUMLHelper::keywordForSmartLivePreview(const QString &p_text,
|
QString VPlantUMLHelper::keywordForSmartLivePreview(const QString &p_text,
|
||||||
QString &p_hints,
|
QString &p_hints,
|
||||||
bool &p_isRegex)
|
bool &p_isRegex)
|
||||||
@ -449,6 +596,12 @@ QString VPlantUMLHelper::keywordForSmartLivePreview(const QString &p_text,
|
|||||||
return kw;
|
return kw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qDebug() << "trySequenceDiagram" << kw;
|
||||||
|
|
||||||
|
if (trySequenceDiagram(kw, p_hints, p_isRegex)) {
|
||||||
|
return kw;
|
||||||
|
}
|
||||||
|
|
||||||
qDebug() << "tryCommonElements" << kw;
|
qDebug() << "tryCommonElements" << kw;
|
||||||
|
|
||||||
if (tryCommonElements(kw, p_hints, p_isRegex)) {
|
if (tryCommonElements(kw, p_hints, p_isRegex)) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user