Logo ROOT  
Reference Guide
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 "TStyle.h"
18#include "TSystem.h"
19#include "TVirtualPad.h"
20#include "TVirtualMutex.h"
21#include "TVirtualX.h"
22#include <typeinfo>
23#include <fstream>
24#include <sstream>
25#include <stdlib.h>
26
27//______________________________________________________________________________
28//
29// When THtml parses documentation (through TDocParser), it checks for special
30// words ("begin_something", "end_something", where the begin and end are the
31// significant part). THtml then searches for a TDocDirective which can handle
32// these tags ("whatever" in the example), passes the text enclosed by these
33// tags to the directive, which in turn processes it.
34//
35// That way, HTML, latex, and C++ macros can be processed by THtml, e.g. to
36// generate plain HTML or GIF pictures. The classes reposinsible for parsing
37// that are TDocHtmlDirective, TDocLatexDirective, and TDocMacroDirective,
38// respecively.
39//
40// Directives can have optional parameters; these are passed as paranthesis
41// enclosed, comma delimited name=value pairs; see SetParameters().
42//
43// You can implement your own directive simply by deriving from TDocDirective;
44// the tag corresponds to TDocDirective's name (e.g. "HTML" for "begin_html" /
45// "end_html").
46//______________________________________________________________________________
47
49
50////////////////////////////////////////////////////////////////////////////////
51/// Delete all output generated by the directive beginning
52/// with Name() and ending with ext
53
54void TDocDirective::DeleteOutputFiles(const char* ext) const
55{
56 TString basename;
57 GetName(basename);
58 basename += "_";
59 TString dirname(GetOutputDir());
60 void* hDir = gSystem->OpenDirectory(dirname);
61 const char* entry = 0;
62 while ((entry = gSystem->GetDirEntry(hDir))) {
63 TString sEntry(entry);
64 if (sEntry.BeginsWith(basename) && isdigit(sEntry[basename.Length()]) && (!ext || sEntry.EndsWith(ext)))
65 gSystem->Unlink((dirname + "/" + entry).Data());
66 }
68}
69
70////////////////////////////////////////////////////////////////////////////////
71/// Get the full name, based on fName, fTitle, fDocParser's tag.
72
74{
75 name = fName;
77 name += "_";
78 TString outfilename;
80 outfilename = gSystem->BaseName(outfilename);
81 Ssiz_t posExt = outfilename.Last('.');
82 outfilename.Remove(posExt, outfilename.Length() - posExt);
83 name += outfilename;
84 }
85 if (GetTitle() && strlen(GetTitle())) {
86 name += "_";
87 name += GetTitle();
88 }
89 if (fCounter != -1) {
90 name += "_";
91 name += fCounter;
92 }
93}
94
95////////////////////////////////////////////////////////////////////////////////
96/// Get the directory for documentation output.
97
98const char* TDocDirective::GetOutputDir() const
99{
100 return fHtml ? fHtml->GetOutputDir().Data() : 0;
101}
102
103////////////////////////////////////////////////////////////////////////////////
104/// Given a string containing parameters in params,
105/// we call AddParameter() for each of them.
106/// This function splits the parameter names and
107/// extracts their values if they are given.
108/// Parameters are separated by ",", values are
109/// separated from parameter names by "=".
110/// params being
111/// a = "a, b, c", b='d,e'
112/// will issue two calls to AddParameter(), one for
113/// a with value "a, b, c" and one for b with value
114/// "d,e" (each without the quotation marks).
115
116void TDocDirective::SetParameters(const char* params)
117{
118 fParameters = params;
119
120 if (!fParameters.Length())
121 return;
122
123 TString param;
124 Ssiz_t pos = 0;
125 while (fParameters.Tokenize(param, pos, ",")) {
126 param = param.Strip(TString::kBoth);
127 if (!param.Length())
128 continue;
129
130 Ssiz_t posAssign = param.Index('=');
131 if (posAssign != kNPOS) {
132 TString value(param(posAssign + 1, param.Length()));
133 value = value.Strip(TString::kBoth);
134 if (value[0] == '\'')
135 value = value.Strip(TString::kBoth, '\'');
136 else if (value[0] == '"')
137 value = value.Strip(TString::kBoth, '"');
138 param.Remove(posAssign, param.Length());
139 param = param.Strip(TString::kBoth);
140 AddParameter(param, value);
141 } else {
142 param = param.Strip(TString::kBoth);
143 AddParameter(param, 0);
144 }
145 }
146}
147
148////////////////////////////////////////////////////////////////////////////////
149/// Set the parser, and fDocOutput, fHtml from that
150
152{
153 fDocParser = parser;
154 fDocOutput = parser ? parser->GetDocOutput() : 0;
156}
157
158
159//______________________________________________________________________________
160//
161// Process a "begin_html" / "end_html" block. Stop linking keywords and simply
162// copy the text enclosed by the directive to the output HTML file.
163//______________________________________________________________________________
164
166
167////////////////////////////////////////////////////////////////////////////////
168/// Add a line of HTML
169
171{
172 if (line.Start() == -1) return;
173
174 TPRegexp pretag("</?[pP][rR][eE][ >]");
175 TSubString iLine(line);
176 Ssiz_t posPre = iLine.String().Index(pretag, iLine.Start());
177 if (posPre == kNPOS)
178 fText += line;
179 else {
180 // remove <pre> in fVerbatim environments, and
181 // </pre> in !fVerbatim environments.
182 while (posPre != kNPOS && posPre > 0) {
183 Bool_t isOpen = line[posPre + 1 - line.Start()] != '/';
184 Ssiz_t posClose = iLine.String().Index(">", posPre);
185 if (posClose ==kNPOS) break; // aka oops.
186 Ssiz_t len = posClose - posPre;
187
188 if (fVerbatim) {
189 if (isOpen) {
190 // skip
191 fText += iLine.String()(iLine.Start(), posPre - iLine.Start());
192 } else {
193 // write it out
194 fText += iLine.String()(iLine.Start(), posPre + len - iLine.Start());
196 }
197 } else {
198 if (!isOpen) {
199 // skip
200 fText += iLine.String()(iLine.Start(), posPre - iLine.Start());
201 } else {
202 // write it out
203 fText += iLine.String()(iLine.Start(), posPre + len - iLine.Start());
205 }
206 }
207
208 iLine = iLine.String()(posPre + len, iLine.Length());
209 posPre = iLine.String().Index(pretag, iLine.Start());
210 }
211
212 fText += iLine;
213 }
214 fText += "\n";
215}
216
217////////////////////////////////////////////////////////////////////////////////
218/// Set result to the HTML code that was passed in via AddLine().
219/// Prepend a closing </pre>, append an opening <pre>
220
222{
223 result = "</pre><!-- TDocHtmlDirective start -->";
224 result += fText + "<!-- TDocHtmlDirective end --><pre>";
225 return kTRUE;
226}
227
228
229
230//______________________________________________________________________________
231//
232// Process a "begin_macro" / "end_macro" block. The block can be a file name
233// or a CINT script (i.e. even ".x file.C" is allowed). See AddParameter() for
234// supported options. Example (the quotes prevent THtml from expanding the
235// example):
236//
237// "BEGIN_MACRO"
238// .x $ROOTSYS/tutorials/hsimple.C
239// "END_MACRO"
240//
241// The macro is meant to create an object that can be saved as a GIF file by
242// calling object->SaveAs(outputfile.gif). The macro is expected to return that
243// object as a TObject*; if it does not, gPad is used and saved. The object
244// is deleted by TDocMacroDirective once saved.
245//______________________________________________________________________________
246
248
249////////////////////////////////////////////////////////////////////////////////
250/// Destructor
251
253{
254 delete fMacro;
255}
256
257////////////////////////////////////////////////////////////////////////////////
258
261 Long_t ret = gROOT->ProcessLine(TString(".x ") + what, &error);
262 Int_t sleepCycles = 50; // 50 = 5 seconds
263 while (error == TInterpreter::kProcessing && --sleepCycles > 0)
264 gSystem->Sleep(100);
265
266 gSystem->ProcessEvents(); // in case ret needs to handle some events first
267
268 if (error != TInterpreter::kNoError) {
269 ::Error("TDocMacroDirective::HandleDirective_Macro",
270 "Error processing macro for %s!", out.Data());
271 return;
272 }
273 if (!ret) {
274 return;
275 }
276
277 // Something with a vtable
278 const TObject* objRet = (const TObject*)ret;
279 try {
280 typeid(*objRet).name(); // needed to test whether ret is indeed an object with a vtable!
281 objRet = dynamic_cast<const TObject*>(objRet);
282 }
283 catch (...) {
284 objRet = 0;
285 }
286
287 if (!objRet) {
288 return;
289 }
290
291 if (gDebug > 3)
292 ::Info("TDocMacroDirective::HandleDirective_Macro",
293 "Saving returned %s to file %s.",
294 objRet->IsA()->GetName(), out.Data());
295
296 if (!gROOT->IsBatch()) {
297 // to get X11 to sync :-( gVirtualX->Update()/Sync() don't do it
298 gSystem->Sleep(1000);
299 gVirtualX->Update(0);
300 gVirtualX->Update(1);
301 }
302
304 if (!gROOT->IsBatch()) {
305 gVirtualX->Update(0);
306 gVirtualX->Update(1);
307 }
308
309 objRet->SaveAs(out);
310 gSystem->ProcessEvents(); // SaveAs triggers an event
311
312#ifdef R__BEPAEPSTLICHERALSDERPAPST
313 // ensure objRet is not e.g. the TGMainFrame of a new TCanvas: require padSave == gPad
314 if (objRet != gPad && padSave == gPad) {
315 delete objRet;
316 }
317#endif
318}
319
320////////////////////////////////////////////////////////////////////////////////
321/// Add a macro line.
322/// Lines ending on "*HIDE*" will be executed as part of the
323/// macro, but not shown in the source tab if the parameter
324/// source is supplied.
325
327{
328 if (!fMacro) {
330 GetName(name);
331 fMacro = new TMacro(name);
332 }
333
334 // return if no line - or if there was an intentinal line-break,
335 // i.e. an empty line
336 if (line.Start() == -1 && const_cast<TSubString&>(line).String().Length()) return;
337
338 TString sLine(line);
339 fMacro->AddLine(sLine);
340 fIsFilename &= !sLine.Contains('{');
341}
342
343////////////////////////////////////////////////////////////////////////////////
344/// Create the input file for SubProcess().
345
347 if (!fIsFilename) {
348 TString fileSysName;
349 GetName(fileSysName);
350 fileSysName += ".C";
352 fMacro->SaveSource(fileSysName);
353 return fileSysName;
354 }
355
356 // We have a filename; find it and build the invocation.
357 TString filename;
358 TIter iLine(fMacro->GetListOfLines());
359 while (filename.Length() == 0)
360 filename = ((TObjString*)iLine())->String().Strip(TString::kBoth);
361
362 TString macroPath;
363 TString modulename;
364 if (GetHtml() && GetDocParser()) {
367 else GetDocParser()->GetCurrentModule(modulename);
368 }
369 if (modulename.Length()) {
370 GetHtml()->GetModuleMacroPath(modulename, macroPath);
371 } else macroPath = gSystem->pwd();
372
373 const char* pathDelimiter = ":"; // use ":" even on windows
374 TObjArray* arrDirs(macroPath.Tokenize(pathDelimiter));
375 TIter iDir(arrDirs);
376 TObjString* osDir = nullptr;
377 macroPath = "";
378 TString filenameDirPart = gSystem->GetDirName(filename);
379 filenameDirPart.Prepend('/'); // as dir delimiter, not as root dir
380 while ((osDir = (TObjString*)iDir())) {
381 if (osDir->String().EndsWith("\\"))
382 osDir->String().Remove(osDir->String().Length() - 1);
383 osDir->String() += filenameDirPart;
384 macroPath += osDir->String() + pathDelimiter;
385 }
386
387 TString plusplus;
388 while (filename.EndsWith("+")) {
389 plusplus += '+';
390 filename.Remove(filename.Length() - 1);
391 }
392
393 TString params;
394 if (filename.EndsWith(")")) {
395 Ssiz_t posOpen = filename.Last('(');
396 if (posOpen != kNPOS) {
397 params = filename(posOpen, filename.Length());
398 filename.Remove(posOpen, filename.Length());
399 }
400 }
401
402 TString fileSysName(gSystem->BaseName(filename));
403 if (!gSystem->FindFile(macroPath, fileSysName)) {
404 Error("GetResult", "Cannot find macro '%s' in path '%s'!",
405 gSystem->BaseName(filename), macroPath.Data());
406 return "";
407 }
408 fileSysName += params;
409 fileSysName += plusplus;
410
411
412 if (fShowSource) {
413 // copy macro into fMacro - before running it, in case the macro blocks its file
414 std::ifstream ifMacro(fileSysName);
417 while (ifMacro) {
418 if (!line.ReadLine(ifMacro, kFALSE) || ifMacro.eof())
419 break;
421 }
422 }
423 return fileSysName;
424}
425
426////////////////////////////////////////////////////////////////////////////////
427/// Get the result (i.e. an HTML img tag) for the macro invocation.
428/// If fShowSource is set, a second tab will be created which shows
429/// the source.
430
432{
433 if (!fMacro)
434 return kFALSE;
435
436 if (!fMacro->GetListOfLines()
437 || !fMacro->GetListOfLines()->First()) {
438 Warning("GetResult", "Empty directive found!");
439 return kTRUE;
440 }
441
442 R__LOCKGUARD(GetHtml()->GetMakeClassMutex());
443
444 if (gDebug > 3)
445 Info("HandleDirective_Macro", "executing macro \"%s\" with %d lines.",
447
448 Bool_t wasBatch = gROOT->IsBatch();
449 Bool_t wantBatch = kFALSE;
450 if (!wasBatch && !fNeedGraphics)
451 wantBatch = kTRUE;
452 else if (fNeedGraphics) {
453 if (fHtml->IsBatch()) {
454 Warning("GetResult()", "Will not initialize the graphics system; skipping macro %s!", GetName());
455 result = "";
456 return kFALSE;
457 }
458 }
459
460 TString outFileName;
461 {
462 GetName(outFileName);
463 GetDocOutput()->NameSpace2FileName(outFileName);
464 outFileName += ".gif";
465 outFileName.ReplaceAll(" ", "_");
466 gSystem->PrependPathName(GetOutputDir(), outFileName);
467 }
468
469 TString subProcInputFile = CreateSubprocessInputFile();
470 if (!subProcInputFile.Length()) return kFALSE;
471
472 subProcInputFile.ReplaceAll("\\", "\\\\");
473 subProcInputFile.ReplaceAll("\"", "\\\"");
474 TString invoc("root.exe -l -q ");
475 if (wantBatch) {
476 invoc += "-b ";
477 }
478 invoc += "-e 'TDocMacroDirective::SubProcess(\""
479 + subProcInputFile + "\",\"" + outFileName + "\");'";
480 gSystem->Unlink(outFileName);
481 Int_t exitCode = gSystem->Exec(invoc.Data());
482
483 if (exitCode && gDebug > 0) {
484 Info("GetResult()", "Subprocess exited with status %d\n", exitCode);
485 } else if (!fIsFilename) {
486 // we have created the input file.
487 gSystem->Unlink(subProcInputFile);
488 }
489
490 if (!gSystem->AccessPathName(outFileName)) {
491 // Output file was created
492 result = "<span class=\"macro\"><img class=\"macro\" alt=\"output of ";
493 result += outFileName;
494
495 result += "\" title=\"MACRO\" src=\"";
496 result += gSystem->BaseName(outFileName);
497 result += "\" /></span>";
498 }
499
500 if (fShowSource) {
501 // convert the macro source
502 TIter iLine(fMacro->GetListOfLines());
503 TObjString* osLine = 0;
504 std::stringstream ssRaw;
505 while ((osLine = (TObjString*)iLine()))
506 ssRaw << osLine->String() << std::endl;
507
508 TDocParser *dparser = 0;
509 if (GetDocParser()->GetCurrentClass())
510 dparser = new TDocParser(*(TClassDocOutput*)GetDocOutput(), GetDocParser()->GetCurrentClass());
511 else dparser = new TDocParser(*GetDocOutput());
512 std::stringstream ssConverted;
513 dparser->Convert(ssConverted, ssRaw, "./", kTRUE /*code*/, kFALSE /*process directives*/);
514 delete dparser;
515
518 while (!ssConverted.fail()) {
519 if (!line.ReadLine(ssConverted, kFALSE) || ssConverted.eof())
520 break;
522 }
523
524 TString id(gSystem->BaseName(outFileName));
525 id = id(0, id.Length()-4); // remove ".gif"
526 // TODO: we need an accessible version of the source, i.e. visible w/o javascript
527 TString tags("</pre><div class=\"tabs\">\n"
528 "<a id=\"" + id + "_A0\" class=\"tabsel\" href=\"" + gSystem->BaseName(outFileName) + "\" onclick=\"javascript:return SetDiv('" + id + "',0);\">Picture</a>\n"
529 "<a id=\"" + id + "_A1\" class=\"tab\" href=\"#\" onclick=\"javascript:return SetDiv('" + id + "',1);\">Source</a>\n"
530 "<br /></div><div class=\"tabcontent\">\n"
531 "<div id=\"" + id + "_0\" class=\"tabvisible\">" + result + "</div>\n"
532 "<div id=\"" + id + "_1\" class=\"tabhidden\"><div class=\"listing\"><pre class=\"code\">");
533 iLine.Reset();
534 osLine = 0;
535 while ((osLine = (TObjString*) iLine()))
536 if (!TString(osLine->String().Strip()).EndsWith("*HIDE*"))
537 tags += osLine->String() + "\n";
538 if (tags.EndsWith("\n"))
539 tags.Remove(tags.Length()-1); // trailing line break
540 tags += "</pre></div></div><div class=\"clear\"></div></div><pre>";
541 result = tags;
542 // Protect the nested comments from being stripped by a
543 // TDocParser::ProcessComment() in the call stack.
544 result.ReplaceAll("<span class=\"comment\">", "<span class=\"codecomment\">");
545 }
546
547 return kTRUE;
548}
549
550////////////////////////////////////////////////////////////////////////////////
551/// Setting fNeedGraphics if name is "GUI",
552/// setting fShowSource if name is "SOURCE"
553
554void TDocMacroDirective::AddParameter(const TString& name, const char* /*value=0*/)
555{
556 if (!name.CompareTo("gui", TString::kIgnoreCase))
558 else if (!name.CompareTo("source", TString::kIgnoreCase))
560 else Warning("AddParameter", "Unknown option %s!", name.Data());
561}
562
563
564
565namespace {
566 Float_t gLinePadding = 10.; //px
567 Float_t gColumnPadding = 10.; //px
568
569 class TLatexLine {
570 private:
571 std::vector<Float_t> fWidths;
572 Float_t fHeight;
573 TObjArray* fColumns; // of TObjString*
574
575 public:
576 TLatexLine(TObjArray* columns = 0):
577 fHeight(0.), fColumns(columns) { if (columns) fWidths.resize(Size());}
578
579 Float_t& Width(UInt_t col) {return fWidths[col];}
580 Float_t& Height() {return fHeight;}
581 TString* operator[](Int_t column) {
582 if (fColumns && fColumns->GetEntriesFast() > column)
583 return &(((TObjString*)fColumns->At(column))->String());
584 return 0;
585 }
586 UInt_t Size() const { return fColumns ? fColumns->GetEntries() : 0; }
587 void Delete() { delete fColumns; }
588 };
589}
590
591//______________________________________________________________________________
592//
593// Handle a "Begin_Latex"/"End_Latex" directive.
594// called as
595// "Begin_Latex(fontsize=10, separator='=,', rseparator='=|,', align=lcl)"
596// will create and include a TLatex-processed image, with a given fontsize
597// in pixels (defaults to 16). If (r)separator is given, the formulas on the
598// following lines will be grouped into columns; a new column starts with
599// (regexp) match of the separator; by default there is only one column.
600// separator matches any character, rseparator matches as regexp with one
601// column per pattern match. Only one of separator or rseparator can be given.
602// align defines the alignment for each columns; be default, all columns
603// are right aligned. NOTE that the column separator counts as a column itself!
604//______________________________________________________________________________
605
606
608
609////////////////////////////////////////////////////////////////////////////////
610/// Destructor
611
613{
615 delete fLatex;
616 delete fBBCanvas;
618}
619
620////////////////////////////////////////////////////////////////////////////////
621/// Add a latex line
622
624{
625 if (line.Length() == 0)
626 return;
627
628 if (!fLatex) {
630 GetName(name);
631 fLatex = new TMacro(name);
632 }
633
634 TString sLine(line);
635 GetDocParser()->Strip(sLine);
636 if (sLine.Length() == 0)
637 return;
638
639 fLatex->AddLine(sLine);
640}
641
642////////////////////////////////////////////////////////////////////////////////
643/// Create a gif file named filename from a latex expression in fLatex.
644/// Called when "Begin_Latex"/"End_Latex" is processed.
645
646void TDocLatexDirective::CreateLatex(const char* filename)
647{
648 if (!fLatex
650 || !fLatex->GetListOfLines()->First())
651 return;
652
653 R__LOCKGUARD(GetHtml()->GetMakeClassMutex());
654
655 TVirtualPad* oldPad = gPad;
656
657 Bool_t wasBatch = gROOT->IsBatch();
658 if (!wasBatch)
659 gROOT->SetBatch();
660
661 const Float_t canvSize = 1200.;
662 if (!fBBCanvas)
663 // add magic batch vs. gui canvas sizes (4, 28)
664 fBBCanvas = (TVirtualPad*)gROOT->ProcessLineFast(
665 Form("new TCanvas(\"R__TDocLatexDirective_BBCanvas\",\"fBBCanvas\",%g,%g);", -(canvSize + 4.), canvSize + 28.));
666 if (!fBBCanvas) {
667 Error("CreateLatex", "Cannot create a TCanvas via the interpreter!");
668 return;
669 }
672
674
675 std::list<TLatexLine> latexLines;
676 std::vector<Float_t> maxWidth(20);
677 UInt_t numColumns = 0;
678 Float_t totalHeight = gLinePadding;
679
680 TLatex latex;
681 latex.SetTextFont(43);
683 latex.SetTextAlign(12);
684
685 // calculate positions
686 TIter iterLine(fLatex->GetListOfLines());
687 TObjString* line = 0;
688 TPRegexp regexp;
689 if (fSeparator.Length()) {
690 if (fSepIsRegexp)
691 regexp = TPRegexp(fSeparator);
692 } else fSepIsRegexp = kFALSE;
693
694 while ((line = (TObjString*) iterLine())) {
695 const TString& str = line->String();
696 TObjArray* split = 0;
697 if (!fSepIsRegexp) {
698 split = new TObjArray();
699 split->SetOwner();
700 }
701 if (!fSeparator.Length())
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)
796 gROOT->SetBatch(kFALSE);
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{
832 TString filename;
833 GetName(filename);
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
845 GetDocOutput()->NameSpace2FileName(filename);
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
863 CreateLatex(filename);
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}
const Ssiz_t kNPOS
Definition: RtypesCore.h:113
int Int_t
Definition: RtypesCore.h:43
unsigned int UInt_t
Definition: RtypesCore.h:44
const Bool_t kFALSE
Definition: RtypesCore.h:90
long Long_t
Definition: RtypesCore.h:52
R__EXTERN Int_t gDebug
Definition: RtypesCore.h:117
float Float_t
Definition: RtypesCore.h:55
const Bool_t kTRUE
Definition: RtypesCore.h:89
#define ClassImp(name)
Definition: Rtypes.h:361
@ kWhite
Definition: Rtypes.h:63
include TDocParser_001 C image html pict1_TDocParser_001 png width
Definition: TDocParser.cxx:121
XFontStruct * id
Definition: TGX11.cxx:108
char name[80]
Definition: TGX11.cxx:109
#define gROOT
Definition: TROOT.h:406
char * Form(const char *fmt,...)
R__EXTERN TSystem * gSystem
Definition: TSystem.h:556
#define R__LOCKGUARD(mutex)
#define gPad
Definition: TVirtualPad.h:287
#define gVirtualX
Definition: TVirtualX.h:338
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:41
virtual void SetTextFont(Font_t tfont=62)
Set the text font.
Definition: TAttText.h:45
virtual void SetTextSize(Float_t tsize=1)
Set the text size.
Definition: TAttText.h:46
virtual Int_t GetEntries() const
Definition: TCollection.h:177
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
TDocParser * fDocParser
Definition: TDocDirective.h:36
TDocOutput * fDocOutput
Definition: TDocDirective.h:38
virtual void AddParameter(const TString &, const char *=0)
Definition: TDocDirective.h:42
TDocParser * GetDocParser() const
Definition: TDocDirective.h:51
const char * GetName() const
Returns name of object.
Definition: TDocDirective.h:49
virtual void DeleteOutputFiles(const char *ext) const
Delete all output generated by the directive beginning with Name() and ending with ext.
THtml * GetHtml() const
Definition: TDocDirective.h:53
TString fParameters
Definition: TDocDirective.h:39
void SetParameters(const char *params)
Given a string containing parameters in params, we call AddParameter() for each of them.
TDocOutput * GetDocOutput() const
Definition: TDocDirective.h:52
void SetParser(TDocParser *parser)
Set the parser, and fDocOutput, fHtml from that.
friend class TDocParser
Definition: TDocDirective.h:75
const char * GetOutputDir() const
Get the directory for documentation output.
virtual void AddLine(const TSubString &line)
Add a line of HTML.
virtual Bool_t GetResult(TString &result)
Set result to the HTML code that was passed in via AddLine().
virtual void CreateLatex(const char *filename)
Create a gif file named filename from a latex expression in fLatex.
virtual ~TDocLatexDirective()
Destructor.
virtual void AddLine(const TSubString &line)
Add a latex line.
TList * GetListOfLines() const
Get the list of lines as TObjStrings.
virtual Bool_t GetResult(TString &result)
convert fLatex to a gif by creating a TLatex, drawing it on a temporary canvas, and saving that to a ...
virtual void AddParameter(const TString &name, const char *value=0)
Parse fParameters, setting fFontSize, fAlignment, and fSeparator.
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
virtual Bool_t GetResult(TString &result)
Get the result (i.e.
virtual void AddLine(const TSubString &line)
Add a macro line.
virtual ~TDocMacroDirective()
Destructor.
TString CreateSubprocessInputFile()
Create the input file for SubProcess().
virtual void AddParameter(const TString &name, const char *value=0)
Setting fNeedGraphics if name is "GUI", setting fShowSource if name is "SOURCE".
static void SubProcess(const TString &what, const TString &out)
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.
Definition: TDocParser.cxx:967
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".
Definition: TDocParser.cxx:402
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:1994
virtual void GetModuleNameForClass(TString &module, TClass *cl) const
Return the module name for a given class.
Definition: THtml.cxx:1533
const TString & GetOutputDir(Bool_t createDir=kTRUE) const
Return the output directory as set by SetOutputDir().
Definition: THtml.cxx:2170
void Reset()
Definition: TCollection.h:252
To draw Mathematical Formula.
Definition: TLatex.h:18
void GetBoundingBox(UInt_t &w, UInt_t &h, Bool_t angle=kFALSE)
Return text size in pixels.
Definition: TLatex.cxx:2552
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:1926
A doubly linked list.
Definition: TList.h:44
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:469
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:658
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:139
void SaveSource(FILE *fp)
Save macro source in file pointer fp.
Definition: TMacro.cxx:381
TList * GetListOfLines() const
Definition: TMacro.h:51
TString fName
Definition: TNamed.h:32
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
An array of TObjects.
Definition: TObjArray.h:37
Int_t GetEntriesFast() const
Definition: TObjArray.h:64
void Add(TObject *obj)
Definition: TObjArray.h:74
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:523
TObject * At(Int_t idx) const
Definition: TObjArray.h:166
Collectable string class.
Definition: TObjString.h:28
TString & String()
Definition: TObjString.h:48
Mother of all ROOT objects.
Definition: TObject.h:37
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:357
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:877
virtual void SaveAs(const char *filename="", Option_t *option="") const
Save this object in the file specified by filename.
Definition: TObject.cxx:599
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:891
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:865
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:131
Ssiz_t Length() const
Definition: TString.h:405
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2177
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
Definition: TString.cxx:1106
const char * Data() const
Definition: TString.h:364
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:687
@ kBoth
Definition: TString.h:262
@ kIgnoreCase
Definition: TString.h:263
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition: TString.cxx:892
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition: TString.cxx:2197
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:610
TString & Prepend(const char *cs)
Definition: TString.h:656
TString & Remove(Ssiz_t pos)
Definition: TString.h:668
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:634
A zero length substring is legal.
Definition: TString.h:77
TString & String()
Definition: TString.h:116
Ssiz_t Start() const
Definition: TString.h:115
Ssiz_t Length() const
Definition: TString.h:114
const char * pwd()
Definition: TSystem.h:420
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition: TSystem.cxx:841
virtual void * OpenDirectory(const char *name)
Open a directory. Returns 0 if directory does not exist.
Definition: TSystem.cxx:832
virtual const char * FindFile(const char *search, TString &file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1531
virtual Int_t Exec(const char *shellcmd)
Execute a command.
Definition: TSystem.cxx:651
virtual const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Definition: TSystem.cxx:1076
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:1291
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition: TSystem.cxx:849
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:930
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
Definition: TSystem.cxx:435
virtual Bool_t ProcessEvents()
Process pending events (GUI, timers, sockets).
Definition: TSystem.cxx:414
virtual TString GetDirName(const char *pathname)
Return the directory name in pathname.
Definition: TSystem.cxx:1027
virtual int Unlink(const char *name)
Unlink, i.e.
Definition: TSystem.cxx:1376
virtual const char * TempDirectory() const
Return a user configured or systemwide directory to create temporary files in.
Definition: TSystem.cxx:1477
virtual void SetText(Double_t x, Double_t y, const char *text)
Definition: TText.h:75
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition: TVirtualPad.h:51
virtual TVirtualPad * cd(Int_t subpadnumber=0)=0
virtual void Print(const char *filename="") const =0
Print function.
virtual void SetBorderMode(Short_t bordermode)=0
virtual void Clear(Option_t *option="")=0
TText * text
TLine * line
Double_t x[n]
Definition: legend1.C:17
const char * String
Definition: TXMLSetup.cxx:93
const char * Size
Definition: TXMLSetup.cxx:55
static const char * what
Definition: stlLoader.cc:6