31<svg id="main" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve">
35<svg id="main" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve">
39<style type="text/css"><![CDATA[
40.node, .edge {opacity: 0.7;}
41.node.selected, .edge.selected {opacity: 1;}
42.edge:hover path { stroke: red; }
43.edge:hover polygon { stroke: red; fill: red; }
50 <circle id="rim" cx="0" cy="0" r="7"/>
51 <circle id="rim2" cx="0" cy="0" r="3.5"/>
53 <use xlink:href="#rim" fill="#404040"><set attributeName="fill" to="#808080" begin="zoomplus.mouseover" end="zoomplus.mouseout"/></use>
54 <path d="M-4,0h8M0,-4v8" fill="none" stroke="white" stroke-width="1.5" pointer-events="none"/>
57 <use xlink:href="#rim" fill="#404040"><set attributeName="fill" to="#808080" begin="zoomminus.mouseover" end="zoomminus.mouseout"/></use>
58 <path d="M-4,0h8" fill="none" stroke="white" stroke-width="1.5" pointer-events="none"/>
60 <g id="arrowUp" transform="translate(30 24)">
61 <use xlink:href="#rim"/>
62 <path pointer-events="none" fill="none" stroke="white" stroke-width="1.5" d="M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5"/>
64 <g id="arrowRight" transform="rotate(90) translate(36 -43)">
65 <use xlink:href="#rim"/>
66 <path pointer-events="none" fill="none" stroke="white" stroke-width="1.5" d="M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5"/>
68 <g id="arrowDown" transform="rotate(180) translate(-30 -48)">
69 <use xlink:href="#rim"/>
70 <path pointer-events="none" fill="none" stroke="white" stroke-width="1.5" d="M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5"/>
72 <g id="arrowLeft" transform="rotate(270) translate(-36 17)">
73 <use xlink:href="#rim"/>
74 <path pointer-events="none" fill="none" stroke="white" stroke-width="1.5" d="M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5"/>
77 <use xlink:href="#rim2" fill="#404040"><set attributeName="fill" to="#808080" begin="reset.mouseover" end="reset.mouseout"/></use>
84<g id="navigator" transform="translate(0 0)" fill="#404254">
85 <rect fill="#f2f5e9" fill-opacity="0.5" stroke="#606060" stroke-width=".5" x="0" y="0" width="60" height="60"/>
86 <use id="zoomplus" xlink:href="#zoomPlus" x="17" y="9" data-zoom="in"/>
87 <use id="zoomminus" xlink:href="#zoomMin" x="42" y="9" data-zoom="out"/>
88 <use id="reset" xlink:href="#resetDef" x="30" y="36" data-reset="true"/>
89 <use id="arrowup" xlink:href="#arrowUp" x="0" y="0" data-pan-x="0" data-pan-y="-1"/>
90 <use id="arrowright" xlink:href="#arrowRight" x="0" y="0" data-pan-x="1" data-pan-y="0"/>
91 <use id="arrowdown" xlink:href="#arrowDown" x="0" y="0" data-pan-x="0" data-pan-y="1"/>
92 <use id="arrowleft" xlink:href="#arrowLeft" x="0" y="0" data-pan-x="-1" data-pan-y="0"/>
94<svg viewBox="0 0 15 15" width="100%" height="30px" preserveAspectRatio="xMaxYMin meet">
95 <g id="arrow_out" transform="scale(0.3 0.3)">
96 <a xlink:href="$orgname" target="_base">
97 <rect id="button" ry="5" rx="5" y="6" x="6" height="38" width="38"
98 fill="#f2f5e9" fill-opacity="0.5" stroke="#606060" stroke-width="1.0"/>
100 d="M 11.500037,31.436501 C 11.940474,20.09759 22.043105,11.32322 32.158766,21.979434 L 37.068811,17.246167 C 37.068811,17.246167 37.088388,32 37.088388,32 L 22.160133,31.978069 C 22.160133,31.978069 26.997745,27.140456 26.997745,27.140456 C 18.528582,18.264221 13.291696,25.230495 11.500037,31.436501 z"
101 style="fill:#404040;"/>
109<style type='text/css'>
111[data-mouse-over-selected='false'] { opacity: 0.7; }
112[data-mouse-over-selected='true'] { opacity: 1.0; }
125 size_t indexS = buf.
find(
"href=\""), indexE = 0;
136 DString link = buf.
mid(indexS+len,indexE-indexS-len);
145 auto dfAst {
createRef( *parser.get(), link.
mid(5), context ) };
146 auto dfAstImpl =
dynamic_cast<const DocNodeAST*
>(dfAst.get());
147 const DocRef *df = std::get_if<DocRef>(&dfAstImpl->root);
157 result +=
"#" + df->
anchor();
163 result = href+
"=\"" + link +
"\"";
168 size_t marker = link.
find(
'$');
176 if (!result.
empty())targetAlreadySet=
true;
184 result = href+
"=\"" + link +
"\"";
187 if (!target.empty() && !targetAlreadySet)
189 result+=
" target=\""+target+
"\"";
195 return leftPart + result + rightPart;
215 const DString &relPath,
bool urlOnly,
221 err(
"problems opening map file {} for inclusion in the docs!\n"
222 "If you installed Graphviz/dot after a previous failing run, \n"
223 "try deleting the output directory and rerun doxygen.\n",mapName);
227 while (getline(f,line))
237 replBuf = replBuf.
left(5) +
" alt=\"\"" + replBuf.
mid(5);
241 if (
size_t indexS = replBuf.
find(
"id=\""), indexE = 0;
244 t << replBuf.
left(indexS-1) << replBuf.
mid(indexE+1);
268 size_t id =
m_maps.size();
269 m_maps.emplace_back(mapFile,relPath,urlOnly,context,label);
270 return static_cast<int>(id);
274 const DString &figureName,
bool heightCheck)
276 size_t id =
m_maps.size();
277 m_maps.emplace_back(figureName,
"",heightCheck,
"",baseName);
278 return static_cast<int>(id);
282 const DString &context,
bool zoomable,
285 size_t id =
m_maps.size();
286 m_maps.emplace_back(
"",relPath,urlOnly,context,
"",zoomable,graphId);
287 return static_cast<int>(id);
294 size_t id =
m_maps.size();
295 m_maps.emplace_back(absImgName,relPath,
false,
"",baseName);
296 return static_cast<int>(id);
309 interactiveSVG = interactiveSVG && map.
zoomable;
326 err(
"problem opening file {} for patching!\n",tmpName);
337 int width=0,height=0;
338 bool insideHeader=
false;
339 bool replacedHeader=
false;
340 bool useNagivation=
false;
342 static const reg::Ex reSVG(R
"([\[<]!-- SVG [0-9]+)");
343 static const reg::Ex reMAP(R
"(<!-- MAP [0-9]+)");
344 static const reg::Ex reFIG(R
"(% FIG [0-9]+)");
346 while (getline(fi,lineStr))
350 auto pos = lineStr.find(
"id=\"page0,1_graph0\"");
351 if (pos != std::string::npos)
352 lineStr.replace(pos, 19,
"id=\"graph0\"");
363 int count = sscanf(line.
data(),
"<svg width=\"%dpt\" height=\"%dpt\"",&width,&height);
364 if (count != 2) count = sscanf(line.
data(),
"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"%d\" height=\"%d\"",&width,&height);
366 useNagivation = count==2 && (width>500 || height>450);
367 insideHeader = count==2;
369 else if (insideHeader && !replacedHeader && line.
find(
"<g id=\"graph")!=
DString::npos)
374 t <<
"<!--zoomable " << height <<
" -->\n";
386 t <<
"<script type=\"application/ecmascript\" xlink:href=\"" << relPath <<
"svg.min.js\"/>\n";
387 t <<
"<svg id=\"graph\" class=\"graph\"";
390 t <<
" data-view-width=\"" << width <<
"\" data-view-height=\"" << height <<
"\"";
393 t <<
" data-section-id=\"dynsection-" << graphId <<
"\"";
400 t <<
"<g id=\"viewport\">\n";
411 if (!insideHeader || !useNagivation)
424 int n = sscanf(line.
data()+i+1,
"!-- SVG %d",&mapId);
425 if (n==1 && mapId>=0 && mapId<
static_cast<int>(
m_maps.size()))
427 size_t e0 = line.
find(
"--]");
428 size_t e1 = line.
find(
"-->");
436 err(
"Problem extracting size from SVG file {}\n",map.
mapFile);
450 int n = sscanf(line.
data()+i,
"<!-- MAP %d",&mapId);
451 if (n==1 && mapId>=0 && mapId<
static_cast<int>(
m_maps.size()))
474 int n = sscanf(line.
data()+i+2,
"FIG %d",&mapId);
476 if (n==1 && mapId>=0 && mapId<
static_cast<int>(
m_maps.size()))
483 err(
"problem writing FIG {} figure!\n",mapId);
489 err(
"Found invalid bounding FIG {} in file {}!\n",mapId,
m_patchFile);
498 if (
isSVGFile && interactiveSVG && !useNagivation) t <<
"</svg>\n";
501 if (
isSVGFile && interactiveSVG && replacedHeader)
517 err(
"problem opening file {} for reading!\n",tmpName);
522 err(
"problem opening file {} for writing!\n",orgName);
526 while (getline(fi,lineStr))
554 while (getline(f,line) && !found)
560 sscanf(line.c_str(),
"<!--zoomable %d",height);
563 else if (sscanf(line.c_str(),
"<svg width=\"%dpt\" height=\"%dpt\"",width,height)==2)
567 else if (sscanf(line.c_str(),
"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"%d\" height=\"%d\"",width,height)==2)
577 out <<
"<p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p>";
585 int width=600,height=600;
592 if (height<=60) height=300;
else height+=300;
593 if (height>600) height=600;
594 out <<
"<div class=\"zoom\">";
597 out <<
"<iframe scrolling=\"no\" loading=\"lazy\" frameborder=\"0\" src=\""
598 << relPath << baseName <<
".svg\" width=\"100%\" height=\"" << height <<
"\">";
604 out <<
"<iframe scrolling=\"no\" loading=\"lazy\" frameborder=\"0\" src=\""
605 << relPath << baseName <<
".svg\" width=\""
606 << ((width*96+48)/72) <<
"\" height=\""
607 << ((height*96+48)/72) <<
"\">";
624 int width=400,height=550;
644 out <<
"\\nopagebreak\n"
645 "\\begin{figure}[H]\n"
648 if (width>maxWidth || height>maxHeight)
651 if (width*maxHeight>height*maxWidth)
653 out <<
"\\includegraphics[width=" << maxWidth <<
"pt]";
657 out <<
"\\includegraphics[height=" << maxHeight <<
"pt]";
662 out <<
"\\includegraphics[width=" << width <<
"pt]";
665 out <<
"{" << baseName <<
"}\n"
A String class for use with Doxygen wrapping std::string and adding some additional functionality off...
DString mid(size_t index, size_t len=npos) const
bool empty() const
Returns true iff the string is empty (std::string compatible alias for isEmpty()).
static constexpr size_t npos
value used to indicate 'not found' or 'to the end of the string', matching std::string::npos
DString & prepend(const char *s)
size_t find(char c, size_t pos=0) const
DString left(size_t len) const
const std::string & str() const
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
bool startsWith(const char *s) const
bool endsWith(const char *s) const
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Class representing a directory in the file system.
bool remove(const std::string &path, bool acceptsAbsPath=true) const
bool rename(const std::string &orgName, const std::string &newName, bool acceptsAbsPath=true) const
Class representing the abstract syntax tree of a documentation block.
Node representing a reference to some item.
int addMap(const DString &mapFile, const DString &relPath, bool urlOnly, const DString &context, const DString &label)
static DString mapLabelToId(const DString &mapLabel)
std::vector< Map > m_maps
DotFilePatcher(const DString &patchFile)
static bool writeVecGfxFigure(TextStream &out, const DString &baseName, const DString &figureName)
int addSVGConversion(const DString &relPath, bool urlOnly, const DString &context, bool zoomable, int graphId)
static bool writeSVGFigureLink(TextStream &out, const DString &relPath, const DString &baseName, const DString &absImgName)
Check if a reference to a SVG figure can be written and do so if possible.
static bool convertMapFile(TextStream &t, const DString &mapName, const DString &relPath, bool urlOnly=false, const DString &context=DString())
int addSVGObject(const DString &baseName, const DString &figureName, const DString &relPath)
int addFigure(const DString &baseName, const DString &figureName, bool heightCheck)
static bool readBoundingBox(const DString &fileName, int *width, int *height, bool isEps)
Text streaming class that buffers data.
bool empty() const
Returns true iff the buffer is empty.
void setStream(std::ostream *s)
Sets or changes the std::ostream to write to.
void flush()
Flushes the buffer.
std::string str() const
Return the contents of the buffer as a std::string object.
Class representing a regular expression.
#define Config_getBool(name)
IDocParserPtr createDocParser()
factory function to create a parser
IDocNodeASTPtr createRef(IDocParser &parserIntf, const DString &target, const DString &context, const DString &srcFile, int srcLine)
static void writeSVGNotSupported(TextStream &out)
static const char svgZoomHeader1[]
static const char svgZoomHeader2[]
static DString replaceRef(const DString &buf, const DString &relPath, bool urlOnly, const DString &context, const DString &target=DString())
static const char svgZoomHeader0_noinit[]
static const char svgZoomFooter2[]
static bool readSVGSize(const DString &fileName, int *width, int *height)
static const char svgZoomHeader0[]
static const char svgZoomFooter1[]
DString substitute(const DString &s, const DString &src, const DString &dst)
substitute all occurrences of src in s by dst
std::ifstream openInputStream(const DString &name, bool binary=false, bool openAtEnd=false)
std::ofstream openOutputStream(const DString &name, bool append=false)
Portable versions of functions that are platform dependent.
Some helper functions for std::string.
size_t findIndex(const StringVector &sv, const std::string &s)
find the index of a string in a vector of strings, returns std::string::npos if the string could not ...
bool literal_at(const char *data, const char(&str)[N])
returns true iff data points to a substring that matches string literal str
DString externalLinkTarget(const bool parent)
DString externalRef(const DString &relPath, const DString &ref, bool href)
void addHtmlExtensionIfMissing(DString &fName)
DString stripPath(const DString &s)
A bunch of utility functions.