Commit 7506404e authored by Dimitri van Heesch's avatar Dimitri van Heesch

Bug 731947 - Support for PlantUML

parent 97d12d05
# Doxyfile 1.8.3.1
# Doxyfile 1.8.7
#---------------------------------------------------------------------------
# Project related configuration options
......@@ -10,6 +10,7 @@ PROJECT_BRIEF =
PROJECT_LOGO =
OUTPUT_DIRECTORY = doxygen_docs
CREATE_SUBDIRS = YES
ALLOW_UNICODE_NAMES = NO
OUTPUT_LANGUAGE = English
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
......@@ -63,6 +64,7 @@ INTERNAL_DOCS = NO
CASE_SENSE_NAMES = NO
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = YES
SHOW_GROUPED_MEMB_INC = NO
FORCE_LOCAL_INCLUDES = NO
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
......@@ -84,7 +86,7 @@ FILE_VERSION_FILTER =
LAYOUT_FILE =
CITE_BIB_FILES =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
# Configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = NO
WARNINGS = YES
......@@ -94,9 +96,10 @@ WARN_NO_PARAMDOC = NO
WARN_FORMAT = "$file:$line: $text "
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
# Configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = src
INPUT = src \
vhdlparser
INPUT_ENCODING = UTF-8
FILE_PATTERNS = *.h \
*.cpp \
......@@ -105,6 +108,7 @@ RECURSIVE = NO
EXCLUDE = src/logos.cpp \
src/lodepng.cpp
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXCLUDE_SYMBOLS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS =
......@@ -116,7 +120,7 @@ FILTER_SOURCE_FILES = NO
FILTER_SOURCE_PATTERNS =
USE_MDFILE_AS_MAINPAGE =
#---------------------------------------------------------------------------
# configuration options related to source browsing
# Configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = YES
INLINE_SOURCES = NO
......@@ -124,18 +128,17 @@ STRIP_CODE_COMMENTS = YES
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION = YES
REFERENCES_LINK_SOURCE = YES
SOURCE_TOOLTIPS = YES
USE_HTAGS = NO
VERBATIM_HEADERS = YES
CLANG_ASSISTED_PARSING = YES
CLANG_OPTIONS =
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
# Configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = YES
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
# Configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT =
......@@ -184,6 +187,7 @@ USE_MATHJAX = NO
MATHJAX_FORMAT = HTML-CSS
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
MATHJAX_EXTENSIONS =
MATHJAX_CODEFILE =
SEARCHENGINE = YES
SERVER_BASED_SEARCH = YES
EXTERNAL_SEARCH = NO
......@@ -192,7 +196,7 @@ SEARCHDATA_FILE = searchdata.xml
EXTERNAL_SEARCH_ID =
EXTRA_SEARCH_MAPPINGS =
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
# Configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
LATEX_OUTPUT =
......@@ -211,7 +215,7 @@ LATEX_HIDE_INDICES = NO
LATEX_SOURCE_CODE = NO
LATEX_BIB_STYLE = plain
#---------------------------------------------------------------------------
# configuration options related to the RTF output
# Configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT =
......@@ -220,31 +224,31 @@ RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
# Configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT =
MAN_EXTENSION = .3
MAN_SUBDIR =
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
# Configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options related to the DOCBOOK output
# Configuration options related to the DOCBOOK output
#---------------------------------------------------------------------------
GENERATE_DOCBOOK = NO
DOCBOOK_OUTPUT = docbook
DOCBOOK_PROGRAMLISTING = NO
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
# Configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
# Configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
......@@ -257,13 +261,14 @@ ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
SEARCH_INCLUDES = YES
INCLUDE_PATH = qtools libmd5
INCLUDE_PATH = qtools \
libmd5
INCLUDE_FILE_PATTERNS =
PREDEFINED =
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
# Configuration options related to external references
#---------------------------------------------------------------------------
TAGFILES = qtools_docs/qtools.tag=../../qtools_docs/html
GENERATE_TAGFILE = doxygen.tag
......@@ -276,6 +281,7 @@ PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = NO
MSCGEN_PATH =
DIA_PATH =
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = YES
DOT_NUM_THREADS = 0
......@@ -299,6 +305,8 @@ INTERACTIVE_SVG = YES
DOT_PATH =
DOTFILE_DIRS =
MSCFILE_DIRS =
DIAFILE_DIRS =
PLANTUML_JAR_PATH =
DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 0
DOT_TRANSPARENT = NO
......
......@@ -90,6 +90,7 @@ documentation:
\refitem cmdendrtfonly \\endrtfonly
\refitem cmdendsecreflist \\endsecreflist
\refitem cmdendverbatim \\endverbatim
\refitem cmdenduml \\enduml
\refitem cmdendxmlonly \\endxmlonly
\refitem cmdenum \\enum
\refitem cmdexample \\example
......@@ -174,6 +175,7 @@ documentation:
\refitem cmdskip \\skip
\refitem cmdskipline \\skipline
\refitem cmdsnippet \\snippet
\refitem cmdstartuml \\startuml
\refitem cmdstruct \\struct
\refitem cmdsubpage \\subpage
\refitem cmdsubsection \\subsection
......@@ -2530,6 +2532,59 @@ class Receiver
\sa section \ref cmdmscfile "\\mscfile".
<hr>
\section cmdstartuml \\startuml
\addindex \\startuml
Starts a text fragment which should contain a valid description of a
PlantUML diagram. See http://plantuml.sourceforge.net/ 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".
Here is an example of the use of the \c \\startuml command.
\code
/** Sender class. Can be used to send a command to the server.
* The receiver will acknowledge the command by calling Ack().
* \startuml
* Sender->Receiver : Command()
* Sender<--Receiver : Ack()
* \enduml
*/
class Sender
{
public:
/** Acknowledgment from server */
void Ack(bool ok);
};
/** Receiver class. Can be used to receive and execute commands.
* After execution of a command, the receiver will send an acknowledgment
* \startuml
* Receiver<-Sender : Command()
* Receiver-->Sender : Ack()
* \enduml
*/
class Receiver
{
public:
/** Executable a command on the server */
void Command(int commandId);
};
\endcode
\note 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.
\verbatim
@startuml{myimage.png}
Alice -> Bob : Hello
@enduml
\endverbatim
When the name of the image is specified, doxygen will generate an image with that name.
Without the name doxygen will choose a name automatically.
<hr>
\section cmddotfile \\dotfile <file> ["caption"]
......@@ -2650,6 +2705,12 @@ class Receiver
\addindex \\endmsc
Ends a block that was started with \ref cmdmsc "\\msc".
<hr>
\section cmdenduml \\enduml
\addindex \\enduml
Ends a block that was started with \ref cmdstartuml "\\startuml".
<hr>
\section cmdendhtmlonly \\endhtmlonly
......
......@@ -120,8 +120,10 @@ CommandMap cmdMap[] =
{ "_internalref", CMD_INTERNALREF },
{ "dot", CMD_DOT },
{ "msc", CMD_MSC },
{ "startuml", CMD_STARTUML },
{ "enddot", CMD_ENDDOT },
{ "endmsc", CMD_ENDMSC },
{ "enduml", CMD_ENDUML },
{ "manonly", CMD_MANONLY },
{ "endmanonly", CMD_ENDMANONLY },
{ "includelineno", CMD_INCWITHLINES },
......
......@@ -127,7 +127,9 @@ enum CommandType
CMD_DIAFILE = 97,
CMD_LATEXINCLUDE = 98,
CMD_NDASH = 99,
CMD_MDASH = 100
CMD_MDASH = 100,
CMD_STARTUML = 101,
CMD_ENDUML = 102
};
enum HtmlTagType
......
......@@ -446,7 +446,7 @@ void replaceComment(int offset);
g_blockName=&yytext[1];
BEGIN(VerbatimCode);
}
<CComment,ReadLine>[\\@]("dot"|"code"|"msc")/[^a-z_A-Z0-9] { /* start of a verbatim block */
<CComment,ReadLine>[\\@]("dot"|"code"|"msc"|"startuml")/[^a-z_A-Z0-9] { /* start of a verbatim block */
copyToOutput(yytext,(int)yyleng);
g_lastCommentContext = YY_START;
g_javaBlock=0;
......@@ -517,7 +517,7 @@ void replaceComment(int offset);
}
}
}
<VerbatimCode>[\\@]("enddot"|"endcode"|"endmsc") { /* end of verbatim block */
<VerbatimCode>[\\@]("enddot"|"endcode"|"endmsc"|"enduml") { /* end of verbatim block */
copyToOutput(yytext,(int)yyleng);
if (&yytext[4]==g_blockName)
{
......@@ -554,7 +554,7 @@ void replaceComment(int offset);
copyToOutput(yytext,(int)yyleng);
}
<Verbatim>^[ \t]*"///" {
if (g_blockName=="dot" || g_blockName=="msc" || g_blockName.at(0)=='f')
if (g_blockName=="dot" || g_blockName=="msc" || g_blockName=="startuml" || g_blockName.at(0)=='f')
{
// see bug 487871, strip /// from dot images and formulas.
int l=0;
......
......@@ -191,6 +191,7 @@ static DocCmdMap docCmdMap[] =
{ "manonly", &handleFormatBlock, FALSE },
{ "dot", &handleFormatBlock, TRUE },
{ "msc", &handleFormatBlock, TRUE },
{ "startuml", &handleFormatBlock, TRUE },
{ "code", &handleFormatBlock, TRUE },
{ "addindex", &handleAddIndex, FALSE },
{ "if", &handleIf, FALSE },
......@@ -877,7 +878,7 @@ static int yyread(char *buf,int max_size)
/* start command character */
CMD ("\\"|"@")
DCMD1 ("arg"|"attention"|"author"|"cite"|"code")
DCMD2 ("date"|"dot"|"msc"|"dotfile"|"example")
DCMD2 ("date"|"dot"|"msc"|"dotfile"|"example"|"startuml")
DCMD3 ("htmlinclude"|"htmlonly"|"image"|"include")
DCMD4 ("includelineno"|"internal"|"invariant")
DCMD5 ("latexinclude"|"latexonly"|"li"|"line"|"manonly"|"name")
......@@ -1785,6 +1786,13 @@ RCSTAG "$"{ID}":"[^\n$]+"$"
BEGIN(Comment);
}
}
<FormatBlock>{CMD}"enduml" {
addOutput(yytext);
if (blockName=="startuml") // found end of the block
{
BEGIN(Comment);
}
}
<FormatBlock>[^ \@\*\/\\\n]* { // some word
addOutput(yytext);
}
......@@ -1809,9 +1817,11 @@ RCSTAG "$"{ID}":"[^\n$]+"$"
addOutput(*yytext);
}
<FormatBlock><<EOF>> {
QCString endTag = "@end"+blockName;
if (blockName=="startuml") endTag="enduml";
warn(yyFileName,yyLineNr,
"reached end of comment while inside a @%s block; check for missing @end%s tag!",
blockName.data(),blockName.data()
"reached end of comment while inside a @%s block; check for missing @%s tag!",
blockName.data(),endTag.data()
);
yyterminate();
}
......
......@@ -386,7 +386,7 @@
<xsd:element name="rtfonly" type="xsd:string" />
<xsd:element name="latexonly" type="xsd:string" />
<xsd:element name="dot" type="xsd:string" />
<xsd:element name="msc" type="xsd:string" />
<xsd:element name="plantuml" type="xsd:string" />
<xsd:element name="anchor" type="docAnchorType" />
<xsd:element name="formula" type="docFormulaType" />
<xsd:element name="ref" type="docRefTextType" />
......
......@@ -1329,6 +1329,37 @@ void Config::check()
mscgenPath="";
}
// check plantuml path
QCString &plantumlJarPath = Config_getString("PLANTUML_JAR_PATH");
if (!plantumlJarPath.isEmpty())
{
QFileInfo pu(plantumlJarPath);
if (pu.exists() && pu.isDir()) // PLANTUML_JAR_PATH is directory
{
QFileInfo jar(plantumlJarPath+portable_pathSeparator()+"plantuml.jar");
if (jar.exists() && jar.isFile())
{
plantumlJarPath = jar.dirPath(TRUE).utf8()+portable_pathSeparator();
}
else
{
config_err("Jar file plantuml.jar not found at location "
"specified via PLANTUML_JAR_PATH: '%s'\n",plantumlJarPath.data());
plantumlJarPath="";
}
}
else if (pu.exists() && pu.isFile() && plantumlJarPath.right(4)==".jar") // PLANTUML_JAR_PATH is file
{
plantumlJarPath = pu.dirPath(TRUE).utf8()+portable_pathSeparator();
}
else
{
config_err("path specified via PLANTUML_JAR_PATH does not exist or not a directory: %s\n",
plantumlJarPath.data());
plantumlJarPath="";
}
}
// check dia path
QCString &diaPath = Config_getString("DIA_PATH");
if (!diaPath.isEmpty())
......
......@@ -3292,6 +3292,16 @@ to be found in the default search path.
The \c DIAFILE_DIRS tag can be used to specify one or more directories that
contain dia files that are included in the documentation (see the
\ref cmdmscfile "\\diafile" command).
]]>
</docs>
</option>
<option type='string' id='PLANTUML_JAR_PATH' format='dir' defval='' depends='HAVE_DOT'>
<docs>
<![CDATA[
When using plantuml, the \c PLANTUML_JAR_PATH tag should be used to specify the path where
java can find the \c plantuml.jar file. If left blank, it is assumed PlantUML is not used or
called during a preprocessing step. Doxygen will generate a warning when it encounters a
\ref cmdstartuml "\\startuml" command in this case and will not generate output for the diagram.
]]>
</docs>
</option>
......
......@@ -34,6 +34,7 @@
#include "msc.h"
#include "dia.h"
#include "htmlentity.h"
#include "plantuml.h"
DocbookDocVisitor::DocbookDocVisitor(FTextStream &t,CodeOutputInterface &ci)
: DocVisitor(DocVisitor_Docbook), m_t(t), m_ci(ci), m_insidePre(FALSE), m_hide(FALSE)
......@@ -216,35 +217,58 @@ void DocbookDocVisitor::visit(DocVerbatim *s)
}
break;
case DocVerbatim::Msc:
static int mscindex = 1;
QCString baseName(4096);
QCString name;
QCString stext = s->text();
m_t << "<para>" << endl;
name.sprintf("%s%d", "msc_inline_mscgraph_", mscindex);
baseName.sprintf("%s%d",
(Config_getString("DOCBOOK_OUTPUT")+"/inline_mscgraph_").data(),
mscindex++
);
QFile file(baseName+".msc");
if (!file.open(IO_WriteOnly))
{
err("Could not open file %s.msc for writing\n",baseName.data());
static int mscindex = 1;
QCString baseName(4096);
QCString name;
QCString stext = s->text();
m_t << "<para>" << endl;
name.sprintf("%s%d", "msc_inline_mscgraph_", mscindex);
baseName.sprintf("%s%d",
(Config_getString("DOCBOOK_OUTPUT")+"/inline_mscgraph_").data(),
mscindex++
);
QFile file(baseName+".msc");
if (!file.open(IO_WriteOnly))
{
err("Could not open file %s.msc for writing\n",baseName.data());
}
QCString text = "msc {";
text+=stext;
text+="}";
file.writeBlock( text, text.length() );
file.close();
m_t << " <figure>" << endl;
m_t << " <title>" << name << "</title>" << endl;
m_t << " <mediaobject>" << endl;
m_t << " <imageobject>" << endl;
writeMscFile(baseName);
m_t << " </imageobject>" << endl;
m_t << " </mediaobject>" << endl;
m_t << " </figure>" << endl;
m_t << "</para>" << endl;
}
break;
case DocVerbatim::PlantUML:
{
static QCString docbookOutput = Config_getString("DOCBOOK_OUTPUT");
QCString baseName = writePlantUMLSource(docbookOutput,s->exampleFile(),s->text());
QCString shortName = baseName;
int i;
if ((i=shortName.findRev('/'))!=-1)
{
shortName=shortName.right(shortName.length()-i-1);
}
m_t << " <figure>" << endl;
m_t << " <title>" << shortName << "</title>" << endl;
m_t << " <mediaobject>" << endl;
m_t << " <imageobject>" << endl;
writePlantUMLFile(baseName);
m_t << " </imageobject>" << endl;
m_t << " </mediaobject>" << endl;
m_t << " </figure>" << endl;
m_t << "</para>" << endl;
}
QCString text = "msc {";
text+=stext;
text+="}";
file.writeBlock( text, text.length() );
file.close();
m_t << " <figure>" << endl;
m_t << " <title>" << name << "</title>" << endl;
m_t << " <mediaobject>" << endl;
m_t << " <imageobject>" << endl;
writeMscFile(baseName);
m_t << " </imageobject>" << endl;
m_t << " </mediaobject>" << endl;
m_t << " </figure>" << endl;
m_t << "</para>" << endl;
break;
}
}
......@@ -1195,6 +1219,22 @@ void DocbookDocVisitor::writeMscFile(const QCString &baseName)
m_t << "</imagedata>" << endl;
}
void DocbookDocVisitor::writePlantUMLFile(const QCString &baseName)
{
QCString shortName = baseName;
int i;
if ((i=shortName.findRev('/'))!=-1)
{
shortName=shortName.right(shortName.length()-i-1);
}
QCString outDir = Config_getString("DOCBOOK_OUTPUT");
generatePlantUMLOutput(baseName,outDir,PUML_BITMAP);
m_t << " <imagedata";
m_t << " width=\"50%\"";
m_t << " align=\"center\" valign=\"middle\" scalefit=\"1\" fileref=\"" << shortName << ".png" << "\">";
m_t << "</imagedata>" << endl;
}
void DocbookDocVisitor::startMscFile(const QCString &fileName,
const QCString &width,
const QCString &height,
......
......@@ -156,6 +156,7 @@ class DocbookDocVisitor : public DocVisitor
const QCString &height, bool hasCaption);
void endDotFile(bool hasCaption);
void writeDotFile(const QCString &fileName);
void writePlantUMLFile(const QCString &fileName);
//--------------------------------------
// state variables
//--------------------------------------
......
......@@ -5569,6 +5569,23 @@ int DocPara::handleCommand(const QCString &cmdName)
doctokenizerYYsetStatePara();
}
break;
case CMD_STARTUML:
{
static QCString jarPath = Config_getString("PLANTUML_JAR_PATH");
doctokenizerYYsetStatePlantUML();
retval = doctokenizerYYlex();
if (jarPath.isEmpty())
{
warn_doc_error(g_fileName,doctokenizerYYlineno,"ignoring startuml command because PLANTUML_JAR_PATH is not set");
}
else
{
m_children.append(new DocVerbatim(this,g_context,g_token->verb,DocVerbatim::PlantUML,FALSE,g_token->sectionId));
}
if (retval==0) warn_doc_error(g_fileName,doctokenizerYYlineno,"startuml section ended without end marker");
doctokenizerYYsetStatePara();
}
break;
case CMD_ENDPARBLOCK:
retval=RetVal_EndParBlock;
break;
......@@ -5583,6 +5600,7 @@ int DocPara::handleCommand(const QCString &cmdName)
case CMD_ENDVERBATIM:
case CMD_ENDDOT:
case CMD_ENDMSC:
case CMD_ENDUML:
warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected command %s",qPrint(g_token->name));
break;
case CMD_PARAM:
......
......@@ -433,7 +433,7 @@ class DocWhiteSpace : public DocNode
class DocVerbatim : public DocNode
{
public:
enum Type { Code, HtmlOnly, ManOnly, LatexOnly, RtfOnly, XmlOnly, Verbatim, Dot, Msc, DocbookOnly };
enum Type { Code, HtmlOnly, ManOnly, LatexOnly, RtfOnly, XmlOnly, Verbatim, Dot, Msc, DocbookOnly, PlantUML };
DocVerbatim(DocNode *parent,const QCString &context,
const QCString &text, Type t,bool isExample,
const QCString &exampleFile,bool isBlock=FALSE,const QCString &lang=QCString());
......
......@@ -160,5 +160,6 @@ void doctokenizerYYpushBackHtmlTag(const char *tag);
void doctokenizerYYsetStateSnippet();
void doctokenizerYYstartAutoList();
void doctokenizerYYendAutoList();
void doctokenizerYYsetStatePlantUML();
#endif
......@@ -417,6 +417,8 @@ REFWORD {LABELID}|{REFWORD2}|{REFWORD3}|{LNKWORD2}
%x St_Verbatim
%x St_Dot
%x St_Msc
%x St_PlantUMLOpt
%x St_PlantUML
%x St_Param
%x St_XRefItem
%x St_XRefItem2
......@@ -843,7 +845,7 @@ REFWORD {LABELID}|{REFWORD2}|{REFWORD3}|{LNKWORD2}
<St_Dot>. { /* dot text */
g_token->verb+=yytext;
}
<St_Msc>{CMD}("endmsc"|"endvhdlflow") {
<St_Msc>{CMD}("endmsc") {
return RetVal_OK;
}
<St_Msc>[^\\@\n]+ |
......@@ -851,6 +853,23 @@ REFWORD {LABELID}|{REFWORD2}|{REFWORD3}|{LNKWORD2}
<St_Msc>. { /* msc text */
g_token->verb+=yytext;
}
<St_PlantUMLOpt>\n {
g_token->sectionId=g_token->sectionId.stripWhiteSpace();
BEGIN(St_PlantUML);
}
<St_PlantUMLOpt>["{}] { // skip curly brackets or quotes around the optional image name
}
<St_PlantUMLOpt>. {
g_token->sectionId += yytext;
}
<St_PlantUML>{CMD}"enduml" {
return RetVal_OK;
}
<St_PlantUML>[^\\@\n]+ |
<St_PlantUML>\n |
<St_PlantUML>. { /* plantuml text */
g_token->verb+=yytext;
}
<St_Title>"\"" { // quoted title
BEGIN(St_TitleQ);
}
......@@ -1121,6 +1140,10 @@ REFWORD {LABELID}|{REFWORD2}|{REFWORD3}|{LNKWORD2}
g_endMarker="endmsc";
BEGIN(St_SecSkip);
}
<St_Sections>{CMD}"startuml"/[^a-z_A-Z0-9] {
g_endMarker="enduml";
BEGIN(St_SecSkip);
}
<St_Sections>{CMD}"htmlonly"/[^a-z_A-Z0-9] {
g_endMarker="endhtmlonly";
BEGIN(St_SecSkip);
......@@ -1318,6 +1341,13 @@ void doctokenizerYYsetStateMsc()
BEGIN(St_Msc);
}
void doctokenizerYYsetStatePlantUML()
{
g_token->verb="";
g_token->sectionId="";
BEGIN(St_PlantUMLOpt);
}
void doctokenizerYYsetStateParam()
{
BEGIN(St_Param);
......
......@@ -34,6 +34,7 @@
#include "filedef.h"
#include "memberdef.h"
#include "htmlentity.h"
#include "plantuml.h"
static const int NUM_HTML_LIST_TYPES = 4;
static const char types[][NUM_HTML_LIST_TYPES] = {"1", "a", "i", "A"};
......@@ -429,9 +430,21 @@ void HtmlDocVisitor::visit(DocVerbatim *s)
m_t << "<div align=\"center\">" << endl;
writeMscFile(baseName+".msc",s->relPath(),s->context());
if (Config_getBool("DOT_CLEANUP")) file.remove();
m_t << "</div>" << endl;
forceStartParagraph(s);
}
break;
case DocVerbatim::PlantUML:
{
forceEndParagraph(s);
static QCString htmlOutput = Config_getString("HTML_OUTPUT");
QCString baseName = writePlantUMLSource(htmlOutput,s->exampleFile(),s->text());
m_t << "<div align=\"center\">" << endl;
writePlantUMLFile(baseName,s->relPath(),s->context());
m_t << "</div>" << endl;
forceStartParagraph(s);
}
m_t << "</div>" << endl;
forceStartParagraph(s);
break;
}
}
......@@ -1976,6 +1989,37 @@ void HtmlDocVisitor::writeDiaFile(const QCString &fileName,
m_t << "<img src=\"" << relPath << baseName << ".png" << "\" />" << endl;
}
void HtmlDocVisitor::writePlantUMLFile(const QCString &fileName,
const QCString &relPath,
const QCString &)
{
QCString baseName=fileName;
int i;
if ((i=baseName.findRev('/'))!=-1) // strip path
{
baseName=baseName.right(baseName.length()-i-1);
}
if ((i=baseName.findRev('.'))!=-1) // strip extension
{
baseName=baseName.left(i);
}
static QCString outDir = Config_getString("HTML_OUTPUT");
static QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT");
if (imgExt=="svg")
{
generatePlantUMLOutput(fileName,outDir,PUML_SVG);
//m_t << "<iframe scrolling=\"no\" frameborder=\"0\" src=\"" << relPath << baseName << ".svg" << "\" />" << endl;
//m_t << "<p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p>";
//m_t << "</iframe>" << endl;
m_t << "<object type=\"image/svg+xml\" data=\"" << relPath << baseName << ".svg\"></object>" << endl;
}
else
{
generatePlantUMLOutput(fileName,outDir,PUML_BITMAP);
m_t << "<img src=\"" << relPath << baseName << ".png" << "\" />" << endl;
}
}
/** Used for items found inside a paragraph, which due to XHTML restrictions
* have to be outside of the paragraph. This method will forcefully end
* the current paragraph and forceStartParagraph() will restart it.
......
......@@ -153,6 +153,7 @@ class HtmlDocVisitor : public DocVisitor
void writeDotFile(const QCString &fileName,const QCString &relPath,const QCString &context);
void writeMscFile(const QCString &fileName,const QCString &relPath,const QCString &context);
void writeDiaFile(const QCString &fileName,const QCString &relPath,const QCString &context);
void writePlantUMLFile(const QCString &fileName,const QCString &relPath,const QCString &context);
void pushEnabled();
void popEnabled();
......
......@@ -462,7 +462,7 @@ const DocSymbol::PerlSymb *HtmlEntityMapper::perl(DocSymbol::SymType symb) const
/*!
* @brief Give code of the requested HTML entity name
* @param symName HTML entity name without \c & and \c;
* @param symName HTML entity name without \c & and \c ;
* @return the code for the requested HTML entity name,
* in case the requested HTML item does not exist `DocSymbol::Sym_unknown` is returned.
*/
......
......@@ -32,6 +32,7 @@
#include "filedef.h"
#include "config.h"
#include "htmlentity.h"
#include "plantuml.h"
static QCString escapeLabelName(const char *s)
{
......@@ -321,6 +322,16 @@ void LatexDocVisitor::visit(DocVerbatim *s)
if (Config_getBool("DOT_CLEANUP")) file.remove();
}
break;
case DocVerbatim::PlantUML:
{
QCString latexOutput = Config_getString("LATEX_OUTPUT");
QCString baseName = writePlantUMLSource(latexOutput,s->exampleFile(),s->text());
m_t << "\\begin{center}\n";
writePlantUMLFile(baseName);
m_t << "\\end{center}\n";
}
break;
}
}
......@@ -1743,6 +1754,7 @@ void LatexDocVisitor::writeMscFile(const QCString &baseName)
m_t << "\\end{DoxyImageNoCaption}\n";
}
void LatexDocVisitor::startDiaFile(const QCString &fileName,
const QCString &width,
const QCString &height,
......@@ -1834,3 +1846,20 @@ void LatexDocVisitor::writeDiaFile(const QCString &baseName)
m_t << "\\end{DoxyImageNoCaption}\n";
}
void LatexDocVisitor::writePlantUMLFile(const QCString &baseName)
{
QCString shortName = baseName;
int i;
if ((i=shortName.findRev('/'))!=-1)
{
shortName=shortName.right(shortName.length()-i-1);
}
QCString outDir = Config_getString("LATEX_OUTPUT");
generatePlantUMLOutput(baseName,outDir,PUML_EPS);
m_t << "\n\\begin{DoxyImageNoCaption}"
" \\mbox{\\includegraphics";
m_t << "{" << shortName << "}";
m_t << "}\n"; // end mbox
m_t << "\\end{DoxyImageNoCaption}\n";
}
......@@ -176,6 +176,7 @@ class LatexDocVisitor : public DocVisitor
const QCString &height, bool hasCaption);
void endDiaFile(bool hasCaption);
void writeDiaFile(const QCString &fileName);
void writePlantUMLFile(const QCString &fileName);
void pushEnabled();
void popEnabled();
......
......@@ -87,6 +87,7 @@ HEADERS = arguments.h \
pagedef.h \
perlmodgen.h \
lodepng.h \
plantuml.h \
pre.h \
printdocvisitor.h \
pycode.h \
......@@ -165,6 +166,7 @@ SOURCES = arguments.cpp \
layout.cpp \
lodepng.cpp \
logos.cpp \
plantuml.cpp \
mandocvisitor.cpp \
mangen.cpp \
sqlite3gen.cpp \
......
......@@ -208,6 +208,7 @@ void ManDocVisitor::visit(DocVerbatim *s)
case DocVerbatim::DocbookOnly:
case DocVerbatim::Dot:
case DocVerbatim::Msc:
case DocVerbatim::PlantUML:
/* nothing */
break;
}
......
......@@ -208,6 +208,10 @@ static QCString isBlockCommand(const char *data,int offset,int size)
{
return "end"+blockName;
}
else if (blockName=="startuml")
{
return "enduml";
}
else if (blockName=="f" && end<size)
{
if (data[end]=='$')
......
......@@ -662,8 +662,9 @@ void PerlModDocVisitor::visit(DocVerbatim *s)
case DocVerbatim::LatexOnly: type = "latexonly"; break;
case DocVerbatim::XmlOnly: type = "xmlonly"; break;
case DocVerbatim::DocbookOnly: type = "docbookonly"; break;
case DocVerbatim::Dot: type = "dot"; break;
case DocVerbatim::Dot: type = "dot"; break;
case DocVerbatim::Msc: type = "msc"; break;
case DocVerbatim::PlantUML: type = "plantuml"; break;
}
openItem(type);
m_output.addFieldQuotedString("content", s->text());
......
/******************************************************************************
*
* Copyright (C) 1997-2014 by Dimitri van Heesch.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation under the terms of the GNU General Public License is hereby
* granted. No representations are made about the suitability of this software
* for any purpose. It is provided "as is" without express or implied warranty.
* See the GNU General Public License for more details.
*
* Documents produced by Doxygen are derivative works derived from the
* input used in their production; they are not affected by this license.
*
*/
#include "plantuml.h"
#include "portable.h"
#include "config.h"
#include "message.h"
#include <qdir.h>
//static const int maxCmdLine = 40960;
QCString writePlantUMLSource(const QCString &outDir,const QCString &fileName,const QCString &content)
{
QCString baseName(4096);
static int umlindex=1;
if (fileName.isEmpty()) // generate name
{
baseName = outDir+"/inline_umlgraph_"+QCString().setNum(umlindex++);
}
else // user specified name
{
baseName = fileName;
int i=baseName.findRev('.');
if (i!=-1) baseName = baseName.left(i);
baseName.prepend(outDir+"/");
}
QFile file(baseName+".pu");
if (!file.open(IO_WriteOnly))
{
err("Could not open file %s for writing\n",baseName.data());
}
QCString text = "@startuml\n";
text+=content;
text+="@enduml\n";
file.writeBlock( text, text.length() );
file.close();
return baseName;
}
void generatePlantUMLOutput(const char *baseName,const char *outDir,PlantUMLOutputFormat format)
{
static QCString plantumlJarPath = Config_getString("PLANTUML_JAR_PATH");
QCString pumlExe = "java";
QCString pumlArgs = "-Djava.awt.headless=true -jar \""+plantumlJarPath+"plantuml.jar\" ";
pumlArgs+="-o \"";
pumlArgs+=outDir;
pumlArgs+="\" ";
QCString extension;
switch (format)
{
case PUML_BITMAP:
pumlArgs+="-tpng";
extension=".png";
break;
case PUML_EPS:
pumlArgs+="-teps";
extension=".eps";
break;
case PUML_SVG:
pumlArgs+="-tsvg";
extension=".svg";
break;
}
pumlArgs+=" \"";
pumlArgs+=baseName;
pumlArgs+=".pu\" ";
int exitCode;
//printf("*** running: %s %s outDir:%s %s\n",pumlExe.data(),pumlArgs.data(),outDir,outFile);
msg("Running PlantUML on generated file %s.pu\n",baseName);
portable_sysTimerStart();
if ((exitCode=portable_system(pumlExe,pumlArgs,FALSE))!=0)
{
err("Problems running PlantUML. Verify that the command 'java -jar \"%splantuml.jar\" -h' works from the command line\n",
plantumlJarPath.data());
}
else if (Config_getBool("DOT_CLEANUP"))
{
QFile(QCString(baseName)+".pu").remove();
}
portable_sysTimerStop();
}
/******************************************************************************
*
* Copyright (C) 1997-2014 by Dimitri van Heesch.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation under the terms of the GNU General Public License is hereby
* granted. No representations are made about the suitability of this software
* for any purpose. It is provided "as is" without express or implied warranty.
* See the GNU General Public License for more details.
*
* Documents produced by Doxygen are derivative works derived from the
* input used in their production; they are not affected by this license.
*
*/
#ifndef PLANTUML_H
#define PLANTUML_H
class QCString;
/** Plant UML output image formats */
enum PlantUMLOutputFormat { PUML_BITMAP, PUML_EPS, PUML_SVG };
/** Write a PlantUML compatible file.
* @param[in] outDir the output directory to write the file to.
* @param[in] fileName the name of the file. If empty a name will be chosen automatically.
* @param[in] content the contents of the PlantUML file.
* @returns The name of the generated file.
*/
QCString writePlantUMLSource(const QCString &outDir,const QCString &fileName,const QCString &content);
/** 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.
*/
void generatePlantUMLOutput(const char *baseName,const char *outDir,PlantUMLOutputFormat format);
#endif
......@@ -134,6 +134,7 @@ class PrintDocVisitor : public DocVisitor
case DocVerbatim::DocbookOnly: printf("<docbookonly>"); break;
case DocVerbatim::Dot: printf("<dot>"); break;
case DocVerbatim::Msc: printf("<msc>"); break;
case DocVerbatim::PlantUML: printf("<plantuml>"); break;
}
printf("%s",s->text().data());
switch(s->type())
......@@ -148,6 +149,7 @@ class PrintDocVisitor : public DocVisitor
case DocVerbatim::DocbookOnly: printf("</docbookonly>"); break;
case DocVerbatim::Dot: printf("</dot>"); break;
case DocVerbatim::Msc: printf("</msc>"); break;
case DocVerbatim::PlantUML: printf("</plantuml>"); break;
}
}
void visit(DocAnchor *a)
......
......@@ -16,6 +16,8 @@
*
*/
#include <qfileinfo.h>
#include "rtfdocvisitor.h"
#include "docparser.h"
#include "language.h"
......@@ -26,13 +28,13 @@
#include "util.h"
#include "rtfstyle.h"
#include "message.h"
#include <qfileinfo.h>
#include "parserintf.h"
#include "msc.h"
#include "dia.h"
#include "filedef.h"
#include "config.h"
#include "htmlentity.h"
#include "plantuml.h"
//#define DBG_RTF(x) m_t << x
#define DBG_RTF(x) do {} while(0)
......@@ -317,6 +319,16 @@ void RTFDocVisitor::visit(DocVerbatim *s)
if (Config_getBool("DOT_CLEANUP")) file.remove();
}
break;
case DocVerbatim::PlantUML:
{
static QCString rtfOutput = Config_getString("RTF_OUTPUT");
QCString baseName = writePlantUMLSource(rtfOutput,s->exampleFile(),s->text());
m_t << "\\par{\\qc "; // center picture
writePlantUMLFile(baseName);
m_t << "} ";
}
break;
}
m_lastIsPara=FALSE;
}
......@@ -1704,3 +1716,23 @@ void RTFDocVisitor::writeDiaFile(const QCString &fileName)
m_lastIsPara=TRUE;
}
void RTFDocVisitor::writePlantUMLFile(const QCString &fileName)
{
QCString baseName=fileName;
int i;
if ((i=baseName.findRev('/'))!=-1)
{
baseName=baseName.right(baseName.length()-i-1);
}
QCString outDir = Config_getString("RTF_OUTPUT");
generatePlantUMLOutput(fileName,outDir,PUML_BITMAP);
if (!m_lastIsPara) m_t << "\\par" << endl;
m_t << "{" << endl;
m_t << rtf_Style_Reset;
m_t << "\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
m_t << baseName << ".png";
m_t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
m_t << "}" << endl;
m_lastIsPara=TRUE;
}
......@@ -155,6 +155,7 @@ class RTFDocVisitor : public DocVisitor
void writeDotFile(const QCString &fileName);
void writeMscFile(const QCString &fileName);
void writeDiaFile(const QCString &fileName);
void writePlantUMLFile(const QCString &fileName);
//--------------------------------------
// state variables
......
......@@ -209,6 +209,11 @@ void XmlDocVisitor::visit(DocVerbatim *s)
filter(s->text());
m_t << "</msc>";
break;
case DocVerbatim::PlantUML:
m_t << "<plantuml>";
filter(s->text());
m_t << "</plantuml>";
break;
}
}
......
......@@ -842,6 +842,10 @@
RelativePath="..\src\perlmodgen.cpp"
>
</File>
<File
RelativePath="..\src\plantuml.cpp"
>
</File>
<File
RelativePath="..\src\portable.cpp"
>
......@@ -2614,6 +2618,10 @@
RelativePath="..\src\perlmodgen.h"
>
</File>
<File
RelativePath="..\src\plantuml.h"
>
</File>
<File
RelativePath="..\src\portable.h"
>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment