From afa248d63e73886a6f0dc0cdb285d18959a0a963 Mon Sep 17 00:00:00 2001 From: albert-github Date: Sun, 4 Apr 2021 18:55:21 +0200 Subject: Extending startuml with extra figure types Not all diagrams can be created with the PlantUML `@startuml` command but need another PlantUML `@start...` command. This wil look like `@start` where currently supported are the following ``'s: `uml`, `bpm`, `wire`, `dot`, `ditaa`, `salt`, `math`, `latex`, `gantt`, `mindmap`, `wbs`, `yaml`, `creole`, `json` and `flow`. By default the `` is `uml`. The `` can be specified as an option. Explicitly the option variant has been chosen so we won't get an explosion of extra commands. --- doc/commands.doc | 22 +++++++++++++---- src/docbookvisitor.cpp | 2 +- src/docparser.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++++++++- src/docparser.h | 3 +++ src/doctokenizer.l | 4 +-- src/htmldocvisitor.cpp | 2 +- src/latexdocvisitor.cpp | 2 +- src/plantuml.cpp | 6 ++--- src/plantuml.h | 3 ++- src/rtfdocvisitor.cpp | 2 +- src/vhdldocgen.cpp | 2 +- 11 files changed, 95 insertions(+), 18 deletions(-) diff --git a/doc/commands.doc b/doc/commands.doc index 1465a1e..afbc786 100644 --- a/doc/commands.doc +++ b/doc/commands.doc @@ -2907,19 +2907,31 @@ class Receiver \sa section \ref cmdmscfile "\\mscfile".
-\section cmdstartuml \\startuml [{file}] ["caption"] [=] +\section cmdstartuml \\startuml ['{'option[,option]'}'] ["caption"] [=] \addindex \\startuml + Starts a text fragment which should contain a valid description of a PlantUML diagram. See https://plantuml.com/ for examples. The text fragment ends with \ref cmdenduml "\\enduml". \note You need to install Java and the PlantUML's jar file, - if you want to use this command. The location of the jar file should be specified - using \ref cfg_plantuml_jar_path "PLANTUML_JAR_PATH". + if you want to use this command. When using PlantUML in \LaTeX you have to download + some more `jar` files, for details see the PlantUML documentation. + The location of the jar file should be specified using + \ref cfg_plantuml_jar_path "PLANTUML_JAR_PATH". + + Not all diagrams can be created with the PlantUML `@startuml` command but need another + PlantUML `@start...` command. This wil look like `@start` where currently supported are + the following ``'s: `uml`, `bpm`, `wire`, `dot`, `ditaa`, `salt`, `math`, `latex`, + `gantt`, `mindmap`, `wbs`, `yaml`, `creole`, `json` and `flow`. By default the `` is + `uml`. The `` can be specified as an option. + Also the file to write the resulting image to can be specified by means of an option, see the + description of the first (optional) argument for details. + Of course only one `` can be specified and also the filename can only be specified once. The first argument is optional and is for compatibility with running PlantUML as a preprocessing - step before running doxygen, you can also add the name of the image file after \c \\startuml - and inside curly brackets, i.e. + step before running doxygen, you can also add the name of the image file after `\startuml` + and inside curly brackets as option, i.e. \verbatim @startuml{myimage.png} "Image Caption" width=5cm Alice -> Bob : Hello diff --git a/src/docbookvisitor.cpp b/src/docbookvisitor.cpp index ce43aec..5f1424c 100644 --- a/src/docbookvisitor.cpp +++ b/src/docbookvisitor.cpp @@ -395,7 +395,7 @@ DB_VIS_C case DocVerbatim::PlantUML: { static QCString docbookOutput = Config_getString(DOCBOOK_OUTPUT); - QCString baseName = PlantumlManager::instance().writePlantUMLSource(docbookOutput,s->exampleFile(),s->text(),PlantumlManager::PUML_BITMAP); + QCString baseName = PlantumlManager::instance().writePlantUMLSource(docbookOutput,s->exampleFile(),s->text(),PlantumlManager::PUML_BITMAP,s->engine()); QCString shortName = baseName; int i; if ((i=shortName.findRev('/'))!=-1) diff --git a/src/docparser.cpp b/src/docparser.cpp index a1f982c..1489ef5 100644 --- a/src/docparser.cpp +++ b/src/docparser.cpp @@ -79,6 +79,9 @@ static const char *sectionLevelToName[] = "subparagraph" }; +static const char *plantumlStart[] = {"uml", "bpm", "wire", "dot", "ditaa", + "salt", "math", "latex", "gantt", "mindmap", + "wbs", "yaml", "creole", "json", "flow" }; //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- @@ -5535,8 +5538,68 @@ int DocPara::handleCommand(const QCString &cmdName, const int tok) static QCString jarPath = Config_getString(PLANTUML_JAR_PATH); doctokenizerYYsetStatePlantUMLOpt(); retval = doctokenizerYYlex(); - QCString plantFile(g_token->sectionId); + + QCString fullMatch = g_token->sectionId; + QCString sectionId = ""; + int idx = fullMatch.find('{'); + int idxEnd = fullMatch.find("}",idx+1); + QCString cmdName; + StringVector optList; + QCString engine; + if (idx != -1) // options present + { + QCString optStr = fullMatch.mid(idx+1,idxEnd-idx-1).stripWhiteSpace(); + optList = split(optStr.str(),","); + for (const auto &opt : optList) + { + if (opt.empty()) continue; + bool found = false; + QCString locOpt = opt; + locOpt = locOpt.lower(); + for (int i = 0; i < sizeof(plantumlStart) / sizeof(*plantumlStart); i++) + { + if (locOpt == plantumlStart[i]) + { + if (!engine.isEmpty()) + { + warn(g_fileName,getDoctokinizerLineNr(), "Multiple definition of engine for '\\startuml'"); + } + engine = plantumlStart[i]; + found = true; + break; + } + } + if (!found) + { + if (sectionId.isEmpty()) + { + sectionId = opt; + } + else + { + warn(g_fileName,getDoctokinizerLineNr(),"Multiple use of of filename for '\\startuml'"); + } + } + } + } + else + { + sectionId = g_token->sectionId; + } + if (engine.isEmpty()) engine = "uml"; + + if (sectionId.isEmpty()) + { + doctokenizerYYsetStatePlantUMLOpt(); + retval = doctokenizerYYlex(); + + sectionId = g_token->sectionId; + sectionId = sectionId.stripWhiteSpace(); + } + + QCString plantFile(sectionId); DocVerbatim *dv = new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::PlantUML,FALSE,plantFile); + dv->setEngine(engine); doctokenizerYYsetStatePara(); QCString width,height; defaultHandleTitleAndSize(CMD_STARTUML,dv,dv->children(),width,height); diff --git a/src/docparser.h b/src/docparser.h index a510b32..e57a2e0 100644 --- a/src/docparser.h +++ b/src/docparser.h @@ -507,11 +507,13 @@ class DocVerbatim : public DocNode bool hasCaption() const { return !m_children.empty(); } QCString width() const { return m_width; } QCString height() const { return m_height; } + QCString engine() const { return m_engine; } const DocNodeList &children() const { return m_children; } DocNodeList &children() { return m_children; } void setText(const QCString &t) { m_text=t; } void setWidth(const QCString &w) { m_width=w; } void setHeight(const QCString &h) { m_height=h; } + void setEngine(const QCString &e) { m_engine=e; } private: QCString m_context; @@ -524,6 +526,7 @@ class DocVerbatim : public DocNode bool m_isBlock = false; QCString m_width; QCString m_height; + QCString m_engine; DocNodeList m_children; }; diff --git a/src/doctokenizer.l b/src/doctokenizer.l index c380cd2..6cb196c 100644 --- a/src/doctokenizer.l +++ b/src/doctokenizer.l @@ -964,10 +964,8 @@ RCSID "$"("Author"|"Date"|"Header"|"Id"|"Locker"|"Log"|"Name"|"RCSfile"|"Revisio lineCount(yytext,yyleng); g_token->verb+=yytext; } -{BLANK}*"{"[^}]*"}" { // case 1: file name is specified as {filename} +{BLANK}*"{"[a-zA-Z_,:0-9\. ]*"}" { // case 1: options present g_token->sectionId = QCString(yytext).stripWhiteSpace(); - // skip curly brackets around the optional image name - g_token->sectionId = g_token->sectionId.mid(1,g_token->sectionId.length()-2).stripWhiteSpace(); return RetVal_OK; } {BLANK}*{FILEMASK}{BLANK}+/{ID}"=" { // case 2: plain file name specified followed by an attribute diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp index 545b96e..e402e66 100644 --- a/src/htmldocvisitor.cpp +++ b/src/htmldocvisitor.cpp @@ -628,7 +628,7 @@ void HtmlDocVisitor::visit(DocVerbatim *s) { format = PlantumlManager::PUML_SVG; } - QCString baseName = PlantumlManager::instance().writePlantUMLSource(htmlOutput,s->exampleFile(),s->text(),format); + QCString baseName = PlantumlManager::instance().writePlantUMLSource(htmlOutput,s->exampleFile(),s->text(),format,s->engine()); m_t << "
\n"; writePlantUMLFile(baseName,s->relPath(),s->context()); visitPreCaption(m_t, s); diff --git a/src/latexdocvisitor.cpp b/src/latexdocvisitor.cpp index 68c050f..4bccb21 100644 --- a/src/latexdocvisitor.cpp +++ b/src/latexdocvisitor.cpp @@ -432,7 +432,7 @@ void LatexDocVisitor::visit(DocVerbatim *s) case DocVerbatim::PlantUML: { QCString latexOutput = Config_getString(LATEX_OUTPUT); - QCString baseName = PlantumlManager::instance().writePlantUMLSource(latexOutput,s->exampleFile(),s->text(),PlantumlManager::PUML_EPS); + QCString baseName = PlantumlManager::instance().writePlantUMLSource(latexOutput,s->exampleFile(),s->text(),PlantumlManager::PUML_EPS,s->engine()); writePlantUMLFile(baseName, s); } diff --git a/src/plantuml.cpp b/src/plantuml.cpp index da26ba7..5fbc1fe 100644 --- a/src/plantuml.cpp +++ b/src/plantuml.cpp @@ -22,7 +22,7 @@ #include "debug.h" #include "fileinfo.h" -QCString PlantumlManager::writePlantUMLSource(const QCString &outDirArg,const QCString &fileName,const QCString &content,OutputFormat format) +QCString PlantumlManager::writePlantUMLSource(const QCString &outDirArg,const QCString &fileName,const QCString &content,OutputFormat format, const QCString &engine) { QCString baseName; QCString puName; @@ -71,9 +71,9 @@ QCString PlantumlManager::writePlantUMLSource(const QCString &outDirArg,const QC Debug::print(Debug::Plantuml,0,"*** %s puName: %s\n","writePlantUMLSource",qPrint(puName)); Debug::print(Debug::Plantuml,0,"*** %s imgName: %s\n","writePlantUMLSource",qPrint(imgName)); - QCString text = "@startuml "+imgName+"\n"; + QCString text = "@start"+engine+" "+imgName+"\n"; text+=content; - text+="\n@enduml\n"; + text+="\n@end"+engine+"\n"; QCString qcOutDir(outDir); uint pos = qcOutDir.findRev("/"); diff --git a/src/plantuml.h b/src/plantuml.h index b92cd0c..b639675 100644 --- a/src/plantuml.h +++ b/src/plantuml.h @@ -58,12 +58,13 @@ class PlantumlManager * @param[in] format the image format to generate. * @returns The name of the generated file. */ - QCString writePlantUMLSource(const QCString &outDir,const QCString &fileName,const QCString &content, OutputFormat format); + QCString writePlantUMLSource(const QCString &outDir,const QCString &fileName,const QCString &content, OutputFormat format, const QCString &engine); /** Convert a PlantUML file to an image. * @param[in] baseName the name of the generated file (as returned by writePlantUMLSource()) * @param[in] outDir the directory to write the resulting image into. * @param[in] format the image format to generate. + * @param[in] engine the plantuml engine to be used so the start command will be `@start` */ void generatePlantUMLOutput(const char *baseName,const char *outDir,OutputFormat format); diff --git a/src/rtfdocvisitor.cpp b/src/rtfdocvisitor.cpp index d0d4e06..e895ddf 100644 --- a/src/rtfdocvisitor.cpp +++ b/src/rtfdocvisitor.cpp @@ -383,7 +383,7 @@ void RTFDocVisitor::visit(DocVerbatim *s) case DocVerbatim::PlantUML: { static QCString rtfOutput = Config_getString(RTF_OUTPUT); - QCString baseName = PlantumlManager::instance().writePlantUMLSource(rtfOutput,s->exampleFile(),s->text(),PlantumlManager::PUML_BITMAP); + QCString baseName = PlantumlManager::instance().writePlantUMLSource(rtfOutput,s->exampleFile(),s->text(),PlantumlManager::PUML_BITMAP,s->engine()); writePlantUMLFile(baseName, s->hasCaption()); visitCaption(this, s->children()); diff --git a/src/vhdldocgen.cpp b/src/vhdldocgen.cpp index 78fef92..8f43286 100644 --- a/src/vhdldocgen.cpp +++ b/src/vhdldocgen.cpp @@ -3344,7 +3344,7 @@ void FlowChart::printUmlTree() QCString htmlOutDir = Config_getString(HTML_OUTPUT); QCString n=convertNameToFileName(); - n=PlantumlManager::instance().writePlantUMLSource(htmlOutDir,n,qcs,PlantumlManager::PUML_SVG); + n=PlantumlManager::instance().writePlantUMLSource(htmlOutDir,n,qcs,PlantumlManager::PUML_SVG,"uml"); PlantumlManager::instance().generatePlantUMLOutput(n,htmlOutDir,PlantumlManager::PUML_SVG); } -- cgit v0.12