Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TDocDirective.cxx
Go to the documentation of this file.
1#include "TDocDirective.h"
2
3#include "TApplication.h"
4#include "TClass.h"
5#include "TDocInfo.h"
6#include "TDocOutput.h"
7#include "TDocParser.h"
8#include "TError.h"
9#include "THtml.h"
10#include "TInterpreter.h"
11#include "TLatex.h"
12#include "TMacro.h"
13#include "TObjString.h"
14#include "TObjArray.h"
15#include "TPRegexp.h"
16#include "TROOT.h"
17#include "TSystem.h"
18#include "TVirtualPad.h"
19#include "TVirtualMutex.h"
20#include "TVirtualX.h"
21#include <typeinfo>
22#include <fstream>
23#include <sstream>
24#include <cstdlib>
25
26//______________________________________________________________________________
27//
28// When THtml parses documentation (through TDocParser), it checks for special
29// words ("begin_something", "end_something", where the begin and end are the
30// significant part). THtml then searches for a TDocDirective which can handle
31// these tags ("whatever" in the example), passes the text enclosed by these
32// tags to the directive, which in turn processes it.
33//
34// That way, HTML, latex, and C++ macros can be processed by THtml, e.g. to
35// generate plain HTML or GIF pictures. The classes reposinsible for parsing
36// that are TDocHtmlDirective, TDocLatexDirective, and TDocMacroDirective,
37// respecively.
38//
39// Directives can have optional parameters; these are passed as paranthesis
40// enclosed, comma delimited name=value pairs; see SetParameters().
41//
42// You can implement your own directive simply by deriving from TDocDirective;
43// the tag corresponds to TDocDirective's name (e.g. "HTML" for "begin_html" /
44// "end_html").
45//______________________________________________________________________________
46
48
49////////////////////////////////////////////////////////////////////////////////
50/// Delete all output generated by the directive beginning
51/// with Name() and ending with ext
52
53void TDocDirective::DeleteOutputFiles(const char* ext) const
54{
55 TString basename;
56 GetName(basename);
57 basename += "_";
58 TString dirname(GetOutputDir());
59 void* hDir = gSystem->OpenDirectory(dirname);
60 const char* entry = 0;
61 while ((entry = gSystem->GetDirEntry(hDir))) {
62 TString sEntry(entry);
63 if (sEntry.BeginsWith(basename) && isdigit(sEntry[basename.Length()]) && (!ext || sEntry.EndsWith(ext)))
64 gSystem->Unlink((dirname + "/" + entry).Data());
65 }
67}
68
69////////////////////////////////////////////////////////////////////////////////
70/// Get the full name, based on fName, fTitle, fDocParser's tag.
71
73{
74 name = fName;
76 name += "_";
77 TString outfilename;
79 outfilename = gSystem->BaseName(outfilename);
80 Ssiz_t posExt = outfilename.Last('.');
81 outfilename.Remove(posExt, outfilename.Length() - posExt);
82 name += outfilename;
83 }
84 if (GetTitle() && strlen(GetTitle())) {
85 name += "_";
86 name += GetTitle();
87 }
88 if (fCounter != -1) {
89 name += "_";
90 name += fCounter;
91 }
92}
93
94////////////////////////////////////////////////////////////////////////////////
95/// Get the directory for documentation output.
96
97const char* TDocDirective::GetOutputDir() const
98{
99 return fHtml ? fHtml->GetOutputDir().Data() : 0;
100}
101
102////////////////////////////////////////////////////////////////////////////////
103/// Given a string containing parameters in params,
104/// we call AddParameter() for each of them.
105/// This function splits the parameter names and
106/// extracts their values if they are given.
107/// Parameters are separated by ",", values are
108/// separated from parameter names by "=".
109/// params being
110/// a = "a, b, c", b='d,e'
111/// will issue two calls to AddParameter(), one for
112/// a with value "a, b, c" and one for b with value
113/// "d,e" (each without the quotation marks).
114
115void TDocDirective::SetParameters(const char* params)
116{
117 fParameters = params;
118
119 if (!fParameters.Length())
120 return;
121
122 TString param;
123 Ssiz_t pos = 0;
124 while (fParameters.Tokenize(param, pos, ",")) {
125 param = param.Strip(TString::kBoth);
126 if (!param.Length())
127 continue;
128
129 Ssiz_t posAssign = param.Index('=');
130 if (posAssign != kNPOS) {
131 TString value(param(posAssign + 1, param.Length()));
132 value = value.Strip(TString::kBoth);
133 if (value[0] == '\'')
134 value = value.Strip(TString::kBoth, '\'');
135 else if (value[0] == '"')
136 value = value.Strip(TString::kBoth, '"');
137 param.Remove(posAssign, param.Length());
138 param = param.Strip(TString::kBoth);
139 AddParameter(param, value);
140 } else {
141 param = param.Strip(TString::kBoth);
142 AddParameter(param, 0);
143 }
144 }
145}
146
147////////////////////////////////////////////////////////////////////////////////
148/// Set the parser, and fDocOutput, fHtml from that
149
151{
152 fDocParser = parser;
153 fDocOutput = parser ? parser->GetDocOutput() : 0;
155}
156
157
158//______________________________________________________________________________
159//
160// Process a "begin_html" / "end_html" block. Stop linking keywords and simply
161// copy the text enclosed by the directive to the output HTML file.
162//______________________________________________________________________________
163
165
166////////////////////////////////////////////////////////////////////////////////
167/// Add a line of HTML
168
170{
171 if (line.Start() == -1) return;
172
173 TPRegexp pretag("</?[pP][rR][eE][ >]");
174 TSubString iLine(line);
175 Ssiz_t posPre = iLine.String().Index(pretag, iLine.Start());
176 if (posPre == kNPOS)
177 fText += line;
178 else {
179 // remove <pre> in fVerbatim environments, and
180 // </pre> in !fVerbatim environments.
181 while (posPre != kNPOS && posPre > 0) {
182 Bool_t isOpen = line[posPre + 1 - line.Start()] != '/';
183 Ssiz_t posClose = iLine.String().Index(">", posPre);
184 if (posClose ==kNPOS) break; // aka oops.
185 Ssiz_t len = posClose - posPre;
186
187 if (fVerbatim) {
188 if (isOpen) {
189 // skip
190 fText += iLine.String()(iLine.Start(), posPre - iLine.Start());
191 } else {
192 // write it out
193 fText += iLine.String()(iLine.Start(), posPre + len - iLine.Start());
195 }
196 } else {
197 if (!isOpen) {
198 // skip
199 fText += iLine.String()(iLine.Start(), posPre - iLine.Start());
200 } else {
201 // write it out
202 fText += iLine.String()(iLine.Start(), posPre + len - iLine.Start());
204 }
205 }
206
207 iLine = iLine.String()(posPre + len, iLine.Length());
208 posPre = iLine.String().Index(pretag, iLine.Start());
209 }
210
211 fText += iLine;
212 }
213 fText += "\n";
214}
215
216////////////////////////////////////////////////////////////////////////////////
217/// Set result to the HTML code that was passed in via AddLine().
218/// Prepend a closing </pre>, append an opening <pre>
219
221{
222 result = "</pre><!-- TDocHtmlDirective start -->";
223 result += fText + "<!-- TDocHtmlDirective end --><pre>";
224 return kTRUE;
225}
226
227
228
229//______________________________________________________________________________
230//
231// Process a "begin_macro" / "end_macro" block. The block can be a file name
232// or a CINT script (i.e. even ".x file.C" is allowed). See AddParameter() for
233// supported options. Example (the quotes prevent THtml from expanding the
234// example):
235//
236// "BEGIN_MACRO"
237// .x $ROOTSYS/tutorials/hsimple.C
238// "END_MACRO"
239//
240// The macro is meant to create an object that can be saved as a GIF file by
241// calling object->SaveAs(outputfile.gif). The macro is expected to return that
242// object as a TObject*; if it does not, gPad is used and saved. The object
243// is deleted by TDocMacroDirective once saved.
244//______________________________________________________________________________
245
247
248////////////////////////////////////////////////////////////////////////////////
249/// Destructor
250
252{
253 delete fMacro;
254}
255
256////////////////////////////////////////////////////////////////////////////////
257
260 Longptr_t ret = gROOT->ProcessLine(TString(".x ") + what, &error);
261 Int_t sleepCycles = 50; // 50 = 5 seconds
262 while (error == TInterpreter::kProcessing && --sleepCycles > 0)
263 gSystem->Sleep(100);
264
265 gSystem->ProcessEvents(); // in case ret needs to handle some events first
266
267 if (error != TInterpreter::kNoError) {
268 ::Error("TDocMacroDirective::HandleDirective_Macro",
269 "Error processing macro for %s!", out.Data());
270 return;
271 }
272 if (!ret) {
273 return;
274 }
275
276 // Something with a vtable
277 const TObject* objRet = (const TObject*)ret;
278 try {
279 typeid(*objRet).name(); // needed to test whether ret is indeed an object with a vtable!
280 objRet = dynamic_cast<const TObject*>(objRet);
281 }
282 catch (...) {
283 objRet = 0;
284 }
285
286 if (!objRet) {
287 return;
288 }
289
290 if (gDebug > 3)
291 ::Info("TDocMacroDirective::HandleDirective_Macro",
292 "Saving returned %s to file %s.",
293 objRet->IsA()->GetName(), out.Data());
294
295 if (!gROOT->IsBatch()) {
296 // to get X11 to sync :-( gVirtualX->Update()/Sync() don't do it
297 gSystem->Sleep(1000);
298 gVirtualX->Update(0);
299 gVirtualX->Update(1);
300 }
301
303 if (!gROOT->IsBatch()) {
304 gVirtualX->Update(0);
305 gVirtualX->Update(1);
306 }
307
308 objRet->SaveAs(out);
309 gSystem->ProcessEvents(); // SaveAs triggers an event
310
311#ifdef R__BEPAEPSTLICHERALSDERPAPST
312 // ensure objRet is not e.g. the TGMainFrame of a new TCanvas: require padSave == gPad
313 if (objRet != gPad && padSave == gPad) {
314 delete objRet;
315 }
316#endif
317}
318
319////////////////////////////////////////////////////////////////////////////////
320/// Add a macro line.
321/// Lines ending on "*HIDE*" will be executed as part of the
322/// macro, but not shown in the source tab if the parameter
323/// source is supplied.
324
326{
327 if (!fMacro) {
329 GetName(name);
330 fMacro = new TMacro(name);
331 }
332
333 // return if no line - or if there was an intentinal line-break,
334 // i.e. an empty line
335 if (line.Start() == -1 && const_cast<TSubString&>(line).String().Length()) return;
336
337 TString sLine(line);
338 fMacro->AddLine(sLine);
339 fIsFilename &= !sLine.Contains('{');
340}
341
342////////////////////////////////////////////////////////////////////////////////
343/// Create the input file for SubProcess().
344
346 if (!fIsFilename) {
347 TString fileSysName;
348 GetName(fileSysName);
349 fileSysName += ".C";
351 fMacro->SaveSource(fileSysName);
352 return fileSysName;
353 }
354
355 // We have a filename; find it and build the invocation.
357 TIter iLine(fMacro->GetListOfLines());
358 while (filename.Length() == 0)
359 filename = ((TObjString*)iLine())->String().Strip(TString::kBoth);
360
361 TString macroPath;
362 TString modulename;
363 if (GetHtml() && GetDocParser()) {
366 else GetDocParser()->GetCurrentModule(modulename);
367 }
368 if (modulename.Length()) {
369 GetHtml()->GetModuleMacroPath(modulename, macroPath);
370 } else macroPath = gSystem->pwd();
371
372 const char* pathDelimiter = ":"; // use ":" even on windows
373 TObjArray* arrDirs(macroPath.Tokenize(pathDelimiter));
374 TIter iDir(arrDirs);
375 TObjString* osDir = nullptr;
376 macroPath = "";
377 TString filenameDirPart = gSystem->GetDirName(filename);
378 filenameDirPart.Prepend('/'); // as dir delimiter, not as root dir
379 while ((osDir = (TObjString*)iDir())) {
380 if (osDir->String().EndsWith("\\"))
381 osDir->String().Remove(osDir->String().Length() - 1);
382 osDir->String() += filenameDirPart;
383 macroPath += osDir->String() + pathDelimiter;
384 }
385
386 TString plusplus;
387 while (filename.EndsWith("+")) {
388 plusplus += '+';
389 filename.Remove(filename.Length() - 1);
390 }
391
392 TString params;
393 if (filename.EndsWith(")")) {
394 Ssiz_t posOpen = filename.Last('(');
395 if (posOpen != kNPOS) {
396 params = filename(posOpen, filename.Length());
397 filename.Remove(posOpen, filename.Length());
398 }
399 }
400
401 TString fileSysName(gSystem->BaseName(filename));
402 if (!gSystem->FindFile(macroPath, fileSysName)) {
403 Error("GetResult", "Cannot find macro '%s' in path '%s'!",
404 gSystem->BaseName(filename), macroPath.Data());
405 return "";
406 }
407 fileSysName += params;
408 fileSysName += plusplus;
409
410
411 if (fShowSource) {
412 // copy macro into fMacro - before running it, in case the macro blocks its file
413 std::ifstream ifMacro(fileSysName);
416 while (ifMacro) {
417 if (!line.ReadLine(ifMacro, kFALSE) || ifMacro.eof())
418 break;
420 }
421 }
422 return fileSysName;
423}
424
425////////////////////////////////////////////////////////////////////////////////
426/// Get the result (i.e. an HTML img tag) for the macro invocation.
427/// If fShowSource is set, a second tab will be created which shows
428/// the source.
429
431{
432 if (!fMacro)
433 return kFALSE;
434
435 if (!fMacro->GetListOfLines()
436 || !fMacro->GetListOfLines()->First()) {
437 Warning("GetResult", "Empty directive found!");
438 return kTRUE;
439 }
440
441 R__LOCKGUARD(GetHtml()->GetMakeClassMutex());
442
443 if (gDebug > 3)
444 Info("HandleDirective_Macro", "executing macro \"%s\" with %d lines.",
446
447 Bool_t wasBatch = gROOT->IsBatch();
448 Bool_t wantBatch = kFALSE;
449 if (!wasBatch && !fNeedGraphics)
450 wantBatch = kTRUE;
451 else if (fNeedGraphics) {
452 if (fHtml->IsBatch()) {
453 Warning("GetResult()", "Will not initialize the graphics system; skipping macro %s!", GetName());
454 result = "";
455 return kFALSE;
456 }
457 }
458
459 TString outFileName;
460 {
461 GetName(outFileName);
462 GetDocOutput()->NameSpace2FileName(outFileName);
463 outFileName += ".gif";
464 outFileName.ReplaceAll(" ", "_");
465 gSystem->PrependPathName(GetOutputDir(), outFileName);
466 }
467
468 TString subProcInputFile = CreateSubprocessInputFile();
469 if (!subProcInputFile.Length()) return kFALSE;
470
471 subProcInputFile.ReplaceAll("\\", "\\\\");
472 subProcInputFile.ReplaceAll("\"", "\\\"");
473 TString invoc("root.exe -l -q ");
474 if (wantBatch) {
475 invoc += "-b ";
476 }
477 invoc += "-e 'TDocMacroDirective::SubProcess(\""
478 + subProcInputFile + "\",\"" + outFileName + "\");'";
479 gSystem->Unlink(outFileName);
480 Int_t exitCode = gSystem->Exec(invoc.Data());
481
482 if (exitCode && gDebug > 0) {
483 Info("GetResult()", "Subprocess exited with status %d\n", exitCode);
484 } else if (!fIsFilename) {
485 // we have created the input file.
486 gSystem->Unlink(subProcInputFile);
487 }
488
489 if (!gSystem->AccessPathName(outFileName)) {
490 // Output file was created
491 result = "<span class=\"macro\"><img class=\"macro\" alt=\"output of ";
492 result += outFileName;
493
494 result += "\" title=\"MACRO\" src=\"";
495 result += gSystem->BaseName(outFileName);
496 result += "\" /></span>";
497 }
498
499 if (fShowSource) {
500 // convert the macro source
501 TIter iLine(fMacro->GetListOfLines());
502 TObjString* osLine = 0;
503 std::stringstream ssRaw;
504 while ((osLine = (TObjString*)iLine()))
505 ssRaw << osLine->String() << std::endl;
506
507 TDocParser *dparser = 0;
508 if (GetDocParser()->GetCurrentClass())
509 dparser = new TDocParser(*(TClassDocOutput*)GetDocOutput(), GetDocParser()->GetCurrentClass());
510 else dparser = new TDocParser(*GetDocOutput());
511 std::stringstream ssConverted;
512 dparser->Convert(ssConverted, ssRaw, "./", kTRUE /*code*/, kFALSE /*process directives*/);
513 delete dparser;
514
517 while (!ssConverted.fail()) {
518 if (!line.ReadLine(ssConverted, kFALSE) || ssConverted.eof())
519 break;
521 }
522
523 TString id(gSystem->BaseName(outFileName));
524 id = id(0, id.Length()-4); // remove ".gif"
525 // TODO: we need an accessible version of the source, i.e. visible w/o javascript
526 TString tags("</pre><div class=\"tabs\">\n"
527 "<a id=\"" + id + "_A0\" class=\"tabsel\" href=\"" + gSystem->BaseName(outFileName) + "\" onclick=\"javascript:return SetDiv('" + id + "',0);\">Picture</a>\n"
528 "<a id=\"" + id + "_A1\" class=\"tab\" href=\"#\" onclick=\"javascript:return SetDiv('" + id + "',1);\">Source</a>\n"
529 "<br /></div><div class=\"tabcontent\">\n"
530 "<div id=\"" + id + "_0\" class=\"tabvisible\">" + result + "</div>\n"
531 "<div id=\"" + id + "_1\" class=\"tabhidden\"><div class=\"listing\"><pre class=\"code\">");
532 iLine.Reset();
533 osLine = 0;
534 while ((osLine = (TObjString*) iLine()))
535 if (!TString(osLine->String().Strip()).EndsWith("*HIDE*"))
536 tags += osLine->String() + "\n";
537 if (tags.EndsWith("\n"))
538 tags.Remove(tags.Length()-1); // trailing line break
539 tags += "</pre></div></div><div class=\"clear\"></div></div><pre>";
540 result = tags;
541 // Protect the nested comments from being stripped by a
542 // TDocParser::ProcessComment() in the call stack.
543 result.ReplaceAll("<span class=\"comment\">", "<span class=\"codecomment\">");
544 }
545
546 return kTRUE;
547}
548
549////////////////////////////////////////////////////////////////////////////////
550/// Setting fNeedGraphics if name is "GUI",
551/// setting fShowSource if name is "SOURCE"
552
553void TDocMacroDirective::AddParameter(const TString& name, const char* /*value=0*/)
554{
555 if (!name.CompareTo("gui", TString::kIgnoreCase))
557 else if (!name.CompareTo("source", TString::kIgnoreCase))
559 else Warning("AddParameter", "Unknown option %s!", name.Data());
560}
561
562
563
564namespace {
565 Float_t gLinePadding = 10.; //px
566 Float_t gColumnPadding = 10.; //px
567
568 class TLatexLine {
569 private:
570 std::vector<Float_t> fWidths;
571 Float_t fHeight;
572 TObjArray* fColumns; // of TObjString*
573
574 public:
575 TLatexLine(TObjArray* columns = 0):
576 fHeight(0.), fColumns(columns) { if (columns) fWidths.resize(Size());}
577
578 Float_t& Width(UInt_t col) {return fWidths[col];}
579 Float_t& Height() {return fHeight;}
580 TString* operator[](Int_t column) {
581 if (fColumns && fColumns->GetEntriesFast() > column)
582 return &(((TObjString*)fColumns->At(column))->String());
583 return 0;
584 }
585 UInt_t Size() const { return fColumns ? fColumns->GetEntries() : 0; }
586 void Delete() { delete fColumns; }
587 };
588}
589
590//______________________________________________________________________________
591//
592// Handle a "Begin_Latex"/"End_Latex" directive.
593// called as
594// "Begin_Latex(fontsize=10, separator='=,', rseparator='=|,', align=lcl)"
595// will create and include a TLatex-processed image, with a given fontsize
596// in pixels (defaults to 16). If (r)separator is given, the formulas on the
597// following lines will be grouped into columns; a new column starts with
598// (regexp) match of the separator; by default there is only one column.
599// separator matches any character, rseparator matches as regexp with one
600// column per pattern match. Only one of separator or rseparator can be given.
601// align defines the alignment for each columns; be default, all columns
602// are right aligned. NOTE that the column separator counts as a column itself!
603//______________________________________________________________________________
604
605
607
608////////////////////////////////////////////////////////////////////////////////
609/// Destructor
610
612{
614 delete fLatex;
615 delete fBBCanvas;
617}
618
619////////////////////////////////////////////////////////////////////////////////
620/// Add a latex line
621
623{
624 if (line.Length() == 0)
625 return;
626
627 if (!fLatex) {
629 GetName(name);
630 fLatex = new TMacro(name);
631 }
632
633 TString sLine(line);
634 GetDocParser()->Strip(sLine);
635 if (sLine.Length() == 0)
636 return;
637
638 fLatex->AddLine(sLine);
639}
640
641////////////////////////////////////////////////////////////////////////////////
642/// Create a gif file named filename from a latex expression in fLatex.
643/// Called when "Begin_Latex"/"End_Latex" is processed.
644
646{
647 if (!fLatex
649 || !fLatex->GetListOfLines()->First())
650 return;
651
652 R__LOCKGUARD(GetHtml()->GetMakeClassMutex());
653
654 TVirtualPad* oldPad = gPad;
655
656 Bool_t wasBatch = gROOT->IsBatch();
657 if (!wasBatch)
658 gROOT->SetBatch();
659
660 const Float_t canvSize = 1200.;
661 if (!fBBCanvas)
662 // add magic batch vs. gui canvas sizes (4, 28)
663 fBBCanvas = (TVirtualPad*)gROOT->ProcessLineFast(
664 Form("new TCanvas(\"R__TDocLatexDirective_BBCanvas\",\"fBBCanvas\",%g,%g);", -(canvSize + 4.), canvSize + 28.));
665 if (!fBBCanvas) {
666 Error("CreateLatex", "Cannot create a TCanvas via the interpreter!");
667 return;
668 }
671
673
674 std::list<TLatexLine> latexLines;
675 std::vector<Float_t> maxWidth(20);
676 UInt_t numColumns = 0;
677 Float_t totalHeight = gLinePadding;
678
679 TLatex latex;
680 latex.SetTextFont(43);
682 latex.SetTextAlign(12);
683
684 // calculate positions
685 TIter iterLine(fLatex->GetListOfLines());
686 TObjString* line = 0;
687 TPRegexp regexp;
688 if (fSeparator.Length()) {
689 if (fSepIsRegexp)
690 regexp = TPRegexp(fSeparator);
691 } else fSepIsRegexp = kFALSE;
692
693 while ((line = (TObjString*) iterLine())) {
694 const TString& str = line->String();
695 TObjArray* split = 0;
696 if (!fSepIsRegexp) {
697 split = new TObjArray();
698 split->SetOwner();
699 }
700 if (!fSeparator.Length()) {
701 if (split)
702 split->Add(new TObjString(str));
703 } else {
704 if (fSepIsRegexp)
705 split = regexp.MatchS(str);
706 else {
707 Ssiz_t prevStart = 0;
708 for (Ssiz_t pos = 0; pos < str.Length(); ++pos) {
709 if (fSeparator.Index(str[pos]) != kNPOS) {
710 split->Add(new TObjString(TString(str(prevStart, pos - prevStart))));
711 split->Add(new TObjString(TString(str(pos, 1))));
712 prevStart = pos + 1;
713 }
714 }
715 split->Add(new TObjString(TString(str(prevStart, str.Length() - prevStart))));
716 }
717 }
718
719 latexLines.push_back(TLatexLine(split));
720 if (numColumns < (UInt_t)split->GetEntries())
721 numColumns = split->GetEntries();
722
723 Float_t heightLine = -1.;
724 for (UInt_t col = 0; col < (UInt_t)split->GetEntries(); ++col) {
725 Float_t widthLatex = 0.;
726 Float_t heightLatex = 0.;
727 TString* strCol = latexLines.back()[col];
728 if (strCol)
729 GetBoundingBox(latex, *strCol, widthLatex, heightLatex);
730 if (heightLine < heightLatex) heightLine = heightLatex;
731 if (maxWidth.size() < col)
732 maxWidth.resize(col * 2);
733 if (maxWidth[col] < widthLatex)
734 maxWidth[col] = widthLatex;
735 latexLines.back().Width(col) = widthLatex;
736 }
737 latexLines.back().Height() = heightLine;
738 totalHeight += heightLine + gLinePadding;
739 } // while next line
740
741 std::vector<Float_t> posX(numColumns + 1);
742 for (UInt_t col = 0; col <= numColumns; ++col) {
743 if (col == 0) posX[col] = gColumnPadding;
744 else posX[col] = posX[col - 1] + maxWidth[col - 1] + gColumnPadding;
745 }
746 Float_t totalWidth = posX[numColumns];
747
748 // draw
749 fBBCanvas->Clear();
750 fBBCanvas->cd();
751 Float_t padSizeX = totalWidth;
752 Float_t padSizeY = totalHeight + 8.;
753 // add magic batch vs. gui canvas sizes (4, 28) + rounding
754 TVirtualPad* padImg = (TVirtualPad*)gROOT->ProcessLineFast(
755 Form("new TCanvas(\"R__TDocLatexDirective_padImg\",\"padImg\",-(Int_t)%g,(Int_t)%g);",
756 padSizeX + 4.5, padSizeY + 28.5));
757 padImg->SetBorderMode(0);
758 padImg->SetFillColor(kWhite);
759 padImg->cd();
760
761 Float_t posY = 0.;
762 for (std::list<TLatexLine>::iterator iLine = latexLines.begin();
763 iLine != latexLines.end(); ++iLine) {
764 posY += iLine->Height()/2. + gLinePadding;
765 for (UInt_t iCol = 0; iCol < iLine->Size(); ++iCol) {
766 TString* str = (*iLine)[iCol];
767 if (!str) continue;
768 char align = 'l';
769 if ((UInt_t)fAlignment.Length() > iCol)
770 align = fAlignment[(Int_t)iCol];
771 Float_t x = posX[iCol];
772 switch (align) {
773 case 'l': break;
774 case 'r': x += maxWidth[iCol] - iLine->Width(iCol); break;
775 case 'c': x += 0.5*(maxWidth[iCol] - iLine->Width(iCol)); break;
776 default:
777 if (iLine == latexLines.begin())
778 Error("CreateLatex", "Invalid alignment character '%c'!", align);
779 }
780 latex.DrawLatex( x / padSizeX, 1. - posY / padSizeY, str->Data());
781 }
782 posY += iLine->Height()/2.;
783 }
784
785 padImg->Print(filename);
786
787 // delete the latex objects
788 for (std::list<TLatexLine>::iterator iLine = latexLines.begin();
789 iLine != latexLines.end(); ++iLine) {
790 iLine->Delete();
791 }
792
793 delete padImg;
794
795 if (!wasBatch)
797
798 gPad = oldPad;
799}
800
801////////////////////////////////////////////////////////////////////////////////
802/// Determines the bounding box for text as height and width.
803/// Assumes that we are in batch mode.
804
806{
807 UInt_t uiWidth = 0;
808 UInt_t uiHeight = 0;
809 fBBCanvas->cd();
810 latex.SetText(0.1, 0.5, text);
811 latex.GetBoundingBox(uiWidth, uiHeight);
812
813 width = uiWidth;
814 height = uiHeight;
815}
816
817////////////////////////////////////////////////////////////////////////////////
818/// Get the list of lines as TObjStrings
819
821{
822 return fLatex ? fLatex->GetListOfLines() : 0;
823}
824
825////////////////////////////////////////////////////////////////////////////////
826/// convert fLatex to a gif by creating a TLatex, drawing it on a
827/// temporary canvas, and saving that to a filename in the output
828/// directory.
829
831{
834 filename.ReplaceAll(" ", "_");
835 const TString& firstLine = ((TObjString*)fLatex->GetListOfLines()->First())->String();
836 TString latexFilename(firstLine);
837 for (Ssiz_t namepos = 0; namepos < latexFilename.Length(); ++namepos)
838 if (!GetDocParser()->IsWord(latexFilename[namepos])) {
839 latexFilename.Remove(namepos, 1);
840 --namepos;
841 }
842 filename += "_";
843 filename += latexFilename;
844
846 filename += ".gif";
847
848 TString altText(firstLine);
850 altText.ReplaceAll("\"", "&quot;");
851 result = "<span class=\"latex\"><img class=\"latex\" alt=\"";
852 result += altText;
853 result += "\" title=\"LATEX\" src=\"";
854 result += filename;
855 result += "\" /></span>";
856
858
859 if (gDebug > 3)
860 Info("HandleDirective_Latex", "Writing Latex \"%s\" to file %s.",
861 fLatex->GetName(), filename.Data());
862
864
865 return kTRUE;
866}
867
868////////////////////////////////////////////////////////////////////////////////
869/// Parse fParameters, setting fFontSize, fAlignment, and fSeparator
870
871void TDocLatexDirective::AddParameter(const TString& name, const char* value /*=0*/)
872{
873 if (!name.CompareTo("fontsize", TString::kIgnoreCase)) {
874 if (!value || !value[0])
875 Error("AddParameter", "Option \"fontsize\" needs a value!");
876 else fFontSize = atol(value);
877 } else if (!name.CompareTo("separator", TString::kIgnoreCase)) {
878 if (!value || !value[0])
879 Error("AddParameter", "Option \"separator\" needs a value!");
880 else fSeparator = value;
881 } else if (!name.CompareTo("align", TString::kIgnoreCase)) {
882 if (!value || !value[0])
883 Error("AddParameter", "Option \"align\" needs a value!");
884 else fAlignment = value;
885 } else
886 Warning("AddParameter", "Unknown option %s!", name.Data());
887}
int Int_t
Definition RtypesCore.h:45
long Longptr_t
Definition RtypesCore.h:82
unsigned int UInt_t
Definition RtypesCore.h:46
float Float_t
Definition RtypesCore.h:57
constexpr Bool_t kFALSE
Definition RtypesCore.h:101
constexpr Ssiz_t kNPOS
Definition RtypesCore.h:124
constexpr Bool_t kTRUE
Definition RtypesCore.h:100
#define ClassImp(name)
Definition Rtypes.h:377
@ kWhite
Definition Rtypes.h:65
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t width
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t height
Option_t Option_t TPoint TPoint const char text
char name[80]
Definition TGX11.cxx:110
Int_t gDebug
Definition TROOT.cxx:595
#define gROOT
Definition TROOT.h:406
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2489
R__EXTERN TSystem * gSystem
Definition TSystem.h:555
#define R__LOCKGUARD(mutex)
#define gPad
#define gVirtualX
Definition TVirtualX.h:337
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition TAttFill.h:37
virtual void SetTextAlign(Short_t align=11)
Set the text alignment.
Definition TAttText.h:42
virtual void SetTextFont(Font_t tfont=62)
Set the text font.
Definition TAttText.h:46
virtual void SetTextSize(Float_t tsize=1)
Set the text size.
Definition TAttText.h:47
virtual Int_t GetEntries() const
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
TDocParser * fDocParser
TDocOutput * fDocOutput
virtual void AddParameter(const TString &, const char *=0)
TDocParser * GetDocParser() const
virtual void DeleteOutputFiles(const char *ext) const
Delete all output generated by the directive beginning with Name() and ending with ext.
THtml * GetHtml() const
TString fParameters
void SetParameters(const char *params)
Given a string containing parameters in params, we call AddParameter() for each of them.
TDocOutput * GetDocOutput() const
void SetParser(TDocParser *parser)
Set the parser, and fDocOutput, fHtml from that.
const char * GetName() const override
Returns name of object.
friend class TDocParser
const char * GetOutputDir() const
Get the directory for documentation output.
Bool_t GetResult(TString &result) override
Set result to the HTML code that was passed in via AddLine().
void AddLine(const TSubString &line) override
Add a line of HTML.
virtual void CreateLatex(const char *filename)
Create a gif file named filename from a latex expression in fLatex.
Bool_t GetResult(TString &result) override
convert fLatex to a gif by creating a TLatex, drawing it on a temporary canvas, and saving that to a ...
void AddParameter(const TString &name, const char *value=0) override
Parse fParameters, setting fFontSize, fAlignment, and fSeparator.
void AddLine(const TSubString &line) override
Add a latex line.
TList * GetListOfLines() const
Get the list of lines as TObjStrings.
virtual void GetBoundingBox(TLatex &latex, const char *text, Float_t &width, Float_t &height)
Determines the bounding box for text as height and width.
TVirtualPad * fBBCanvas
~TDocLatexDirective() override
Destructor.
~TDocMacroDirective() override
Destructor.
TString CreateSubprocessInputFile()
Create the input file for SubProcess().
static void SubProcess(const TString &what, const TString &out)
void AddLine(const TSubString &line) override
Add a macro line.
void AddParameter(const TString &name, const char *value=0) override
Setting fNeedGraphics if name is "GUI", setting fShowSource if name is "SOURCE".
Bool_t GetResult(TString &result) override
Get the result (i.e.
virtual void NameSpace2FileName(TString &name)
Replace "::" in name by "__" Replace "<", ">", " ", ",", "~", "=" in name by "_" Replace "A::X<A::Y>"...
virtual const char * ReplaceSpecialChars(char c)
Replace ampersand, less-than and greater-than character, writing to out.
THtml * GetHtml()
Definition TDocOutput.h:90
static Bool_t Strip(TString &s)
strips ' ', tabs, and newlines from both sides of str
void GetCurrentModule(TString &out_module) const
Return the name of module for which sources are currently parsed.
void Convert(std::ostream &out, std::istream &in, const char *relpath, Bool_t isCode, Bool_t interpretDirectives)
Parse text file "in", add links etc, and write output to "out".
TDocOutput * GetDocOutput() const
Definition TDocParser.h:173
TClass * GetCurrentClass() const
Definition TDocParser.h:171
void GetModuleMacroPath(const TString &module, TString &out_path) const
Definition THtml.h:324
Bool_t IsBatch() const
Definition THtml.h:353
virtual void GetHtmlFileName(TClass *classPtr, TString &filename) const
Return real HTML filename.
Definition THtml.cxx:2001
virtual void GetModuleNameForClass(TString &module, TClass *cl) const
Return the module name for a given class.
Definition THtml.cxx:1540
const TString & GetOutputDir(Bool_t createDir=kTRUE) const
Return the output directory as set by SetOutputDir().
Definition THtml.cxx:2177
void Reset()
To draw Mathematical Formula.
Definition TLatex.h:18
void GetBoundingBox(UInt_t &w, UInt_t &h, Bool_t angle=kFALSE) override
Return text size in pixels.
Definition TLatex.cxx:2600
TLatex * DrawLatex(Double_t x, Double_t y, const char *text)
Make a copy of this object with the new parameters And copy object attributes.
Definition TLatex.cxx:1943
A doubly linked list.
Definition TList.h:38
TObject * First() const override
Return the first object in the list. Returns 0 when list is empty.
Definition TList.cxx:657
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:468
Class supporting a collection of lines with C++ code.
Definition TMacro.h:31
virtual TObjString * AddLine(const char *text)
Add line with text in the list of lines of this macro.
Definition TMacro.cxx:138
void SaveSource(FILE *fp)
Save macro source in file pointer fp.
Definition TMacro.cxx:371
TList * GetListOfLines() const
Definition TMacro.h:51
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:48
TString fName
Definition TNamed.h:32
An array of TObjects.
Definition TObjArray.h:31
Int_t GetEntriesFast() const
Definition TObjArray.h:58
Int_t GetEntries() const override
Return the number of objects in array (i.e.
TObject * At(Int_t idx) const override
Definition TObjArray.h:164
void Add(TObject *obj) override
Definition TObjArray.h:68
Collectable string class.
Definition TObjString.h:28
TString & String()
Definition TObjString.h:48
Mother of all ROOT objects.
Definition TObject.h:41
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:973
virtual void SaveAs(const char *filename="", Option_t *option="") const
Save this object in the file specified by filename.
Definition TObject.cxx:686
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:987
virtual TClass * IsA() const
Definition TObject.h:245
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:961
TObjArray * MatchS(const TString &s, const TString &mods="", Int_t start=0, Int_t nMaxMatch=10)
Returns a TObjArray of matched substrings as TObjString's.
Definition TPRegexp.cxx:370
Basic string class.
Definition TString.h:139
Ssiz_t Length() const
Definition TString.h:417
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition TString.cxx:2244
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
Definition TString.cxx:1163
const char * Data() const
Definition TString.h:376
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:704
@ kBoth
Definition TString.h:276
@ kIgnoreCase
Definition TString.h:277
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition TString.cxx:931
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition TString.cxx:2264
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition TString.h:623
TString & Prepend(const char *cs)
Definition TString.h:673
TString & Remove(Ssiz_t pos)
Definition TString.h:685
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:632
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:651
A zero length substring is legal.
Definition TString.h:85
TString & String()
Definition TString.h:124
Ssiz_t Start() const
Definition TString.h:123
Ssiz_t Length() const
Definition TString.h:122
const char * pwd()
Definition TSystem.h:418
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition TSystem.cxx:845
virtual void * OpenDirectory(const char *name)
Open a directory. Returns 0 if directory does not exist.
Definition TSystem.cxx:836
virtual const char * FindFile(const char *search, TString &file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1538
virtual Int_t Exec(const char *shellcmd)
Execute a command.
Definition TSystem.cxx:653
virtual const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Definition TSystem.cxx:1081
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
Definition TSystem.cxx:1296
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition TSystem.cxx:853
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition TSystem.cxx:934
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
Definition TSystem.cxx:437
virtual Bool_t ProcessEvents()
Process pending events (GUI, timers, sockets).
Definition TSystem.cxx:416
virtual TString GetDirName(const char *pathname)
Return the directory name in pathname.
Definition TSystem.cxx:1032
virtual int Unlink(const char *name)
Unlink, i.e.
Definition TSystem.cxx:1381
virtual const char * TempDirectory() const
Return a user configured or systemwide directory to create temporary files in.
Definition TSystem.cxx:1482
virtual void SetText(Double_t x, Double_t y, const char *text)
Definition TText.h:74
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition TVirtualPad.h:51
virtual void SetBatch(Bool_t batch=kTRUE)=0
void Print(const char *filename="") const override=0
This method must be overridden when a class wants to print itself.
virtual TVirtualPad * cd(Int_t subpadnumber=0)=0
virtual void SetBorderMode(Short_t bordermode)=0
void Clear(Option_t *option="") override=0
TLine * line
Double_t x[n]
Definition legend1.C:17
const char * String
Definition TXMLSetup.cxx:94
const char * Size
Definition TXMLSetup.cxx:56
static const char * what
Definition stlLoader.cc:5