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