46 ClassImp(TDocDirective);
52 void TDocDirective::DeleteOutputFiles(
const char* ext)
const
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());
65 gSystem->FreeDirectory(hDir);
71 void TDocDirective::GetName(TString& name)
const
74 if (fDocParser && fDocParser->GetCurrentClass()) {
77 GetHtml()->GetHtmlFileName(fDocParser->GetCurrentClass(), outfilename);
78 outfilename = gSystem->BaseName(outfilename);
79 Ssiz_t posExt = outfilename.Last(
'.');
80 outfilename.Remove(posExt, outfilename.Length() - posExt);
83 if (GetTitle() && strlen(GetTitle())) {
96 const char* TDocDirective::GetOutputDir()
const
98 return fHtml ? fHtml->GetOutputDir().Data() : 0;
114 void TDocDirective::SetParameters(
const char* params)
116 fParameters = params;
118 if (!fParameters.Length())
123 while (fParameters.Tokenize(param, pos,
",")) {
124 param = param.Strip(TString::kBoth);
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);
140 param = param.Strip(TString::kBoth);
141 AddParameter(param, 0);
149 void TDocDirective::SetParser(TDocParser* parser)
152 fDocOutput = parser ? parser->GetDocOutput() : 0;
153 fHtml = fDocOutput? fDocOutput->GetHtml() : 0;
163 ClassImp(TDocHtmlDirective);
168 void TDocHtmlDirective::AddLine(
const TSubString& line)
170 if (line.Start() == -1)
return;
172 TPRegexp pretag(
"</?[pP][rR][eE][ >]");
173 TSubString iLine(line);
174 Ssiz_t posPre = iLine.String().Index(pretag, iLine.Start());
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;
184 Ssiz_t len = posClose - posPre;
189 fText += iLine.String()(iLine.Start(), posPre - iLine.Start());
192 fText += iLine.String()(iLine.Start(), posPre + len - iLine.Start());
198 fText += iLine.String()(iLine.Start(), posPre - iLine.Start());
201 fText += iLine.String()(iLine.Start(), posPre + len - iLine.Start());
206 iLine = iLine.String()(posPre + len, iLine.Length());
207 posPre = iLine.String().Index(pretag, iLine.Start());
219 Bool_t TDocHtmlDirective::GetResult(TString& result)
221 result =
"</pre><!-- TDocHtmlDirective start -->";
222 result += fText +
"<!-- TDocHtmlDirective end --><pre>";
245 ClassImp(TDocMacroDirective);
250 TDocMacroDirective::~TDocMacroDirective()
257 void TDocMacroDirective::SubProcess(
const TString& what,
const TString& out) {
258 Int_t error = TInterpreter::kNoError;
259 Long_t ret = gROOT->ProcessLine(TString(
".x ") + what, &error);
260 Int_t sleepCycles = 50;
261 while (error == TInterpreter::kProcessing && --sleepCycles > 0)
264 gSystem->ProcessEvents();
266 if (error != TInterpreter::kNoError) {
267 ::Error(
"TDocMacroDirective::HandleDirective_Macro",
268 "Error processing macro for %s!", out.Data());
276 const TObject* objRet = (
const TObject*)ret;
278 typeid(*objRet).name();
279 objRet =
dynamic_cast<const TObject*
>(objRet);
290 ::Info(
"TDocMacroDirective::HandleDirective_Macro",
291 "Saving returned %s to file %s.",
292 objRet->IsA()->GetName(), out.Data());
294 if (!gROOT->IsBatch()) {
296 gSystem->Sleep(1000);
297 gVirtualX->Update(0);
298 gVirtualX->Update(1);
301 gSystem->ProcessEvents();
302 if (!gROOT->IsBatch()) {
303 gVirtualX->Update(0);
304 gVirtualX->Update(1);
308 gSystem->ProcessEvents();
310 #ifdef R__BEPAEPSTLICHERALSDERPAPST
312 if (objRet != gPad && padSave == gPad) {
324 void TDocMacroDirective::AddLine(
const TSubString& line)
329 fMacro =
new TMacro(name);
334 if (line.Start() == -1 &&
const_cast<TSubString&
>(line).String().Length())
return;
337 fMacro->AddLine(sLine);
338 fIsFilename &= !sLine.Contains(
'{');
344 TString TDocMacroDirective::CreateSubprocessInputFile() {
347 GetName(fileSysName);
349 gSystem->PrependPathName(gSystem->TempDirectory(), fileSysName);
350 fMacro->SaveSource(fileSysName);
356 TIter iLine(fMacro->GetListOfLines());
357 while (filename.Length() == 0)
358 filename = ((TObjString*)iLine())->String().Strip(TString::kBoth);
362 if (GetHtml() && GetDocParser()) {
363 if (GetDocParser()->GetCurrentClass())
364 GetHtml()->GetModuleNameForClass(modulename, GetDocParser()->GetCurrentClass());
365 else GetDocParser()->GetCurrentModule(modulename);
367 if (modulename.Length()) {
368 GetHtml()->GetModuleMacroPath(modulename, macroPath);
369 }
else macroPath = gSystem->pwd();
371 const char* pathDelimiter =
":";
372 TObjArray* arrDirs(macroPath.Tokenize(pathDelimiter));
374 TObjString* osDir = 0;
376 TString filenameDirPart(gSystem->DirName(filename));
377 filenameDirPart.Prepend(
'/');
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;
386 while (filename.EndsWith(
"+")) {
388 filename.Remove(filename.Length() - 1);
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());
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());
406 fileSysName += params;
407 fileSysName += plusplus;
412 std::ifstream ifMacro(fileSysName);
413 fMacro->GetListOfLines()->Delete();
416 if (!line.ReadLine(ifMacro, kFALSE) || ifMacro.eof())
418 fMacro->AddLine(line);
429 Bool_t TDocMacroDirective::GetResult(TString& result)
434 if (!fMacro->GetListOfLines()
435 || !fMacro->GetListOfLines()->First()) {
436 Warning(
"GetResult",
"Empty directive found!");
440 R__LOCKGUARD(GetHtml()->GetMakeClassMutex());
443 Info(
"HandleDirective_Macro",
"executing macro \"%s\" with %d lines.",
444 fMacro->GetName(), fMacro->GetListOfLines() ? fMacro->GetListOfLines()->GetEntries() + 1 : 0);
446 Bool_t wasBatch = gROOT->IsBatch();
447 Bool_t wantBatch = kFALSE;
448 if (!wasBatch && !fNeedGraphics)
450 else if (fNeedGraphics) {
451 if (fHtml->IsBatch()) {
452 Warning(
"GetResult()",
"Will not initialize the graphics system; skipping macro %s!", GetName());
460 GetName(outFileName);
461 GetDocOutput()->NameSpace2FileName(outFileName);
462 outFileName +=
".gif";
463 outFileName.ReplaceAll(
" ",
"_");
464 gSystem->PrependPathName(GetOutputDir(), outFileName);
467 TString subProcInputFile = CreateSubprocessInputFile();
468 if (!subProcInputFile.Length())
return kFALSE;
470 subProcInputFile.ReplaceAll(
"\\",
"\\\\");
471 subProcInputFile.ReplaceAll(
"\"",
"\\\"");
472 TString invoc(
"root.exe -l -q ");
476 invoc +=
"-e 'TDocMacroDirective::SubProcess(\""
477 + subProcInputFile +
"\",\"" + outFileName +
"\");'";
478 gSystem->Unlink(outFileName);
479 Int_t exitCode = gSystem->Exec(invoc.Data());
481 if (exitCode && gDebug > 0) {
482 Info(
"GetResult()",
"Subprocess exited with status %d\n", exitCode);
483 }
else if (!fIsFilename) {
485 gSystem->Unlink(subProcInputFile);
488 if (!gSystem->AccessPathName(outFileName)) {
490 result =
"<span class=\"macro\"><img class=\"macro\" alt=\"output of ";
491 result += outFileName;
493 result +=
"\" title=\"MACRO\" src=\"";
494 result += gSystem->BaseName(outFileName);
495 result +=
"\" /></span>";
500 TIter iLine(fMacro->GetListOfLines());
501 TObjString* osLine = 0;
502 std::stringstream ssRaw;
503 while ((osLine = (TObjString*)iLine()))
504 ssRaw << osLine->String() << std::endl;
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 , kFALSE );
514 fMacro->GetListOfLines()->Delete();
516 while (!ssConverted.fail()) {
517 if (!line.ReadLine(ssConverted, kFALSE) || ssConverted.eof())
519 fMacro->AddLine(line);
522 TString id(gSystem->BaseName(outFileName));
523 id = id(0,
id.Length()-4);
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\">");
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);
538 tags +=
"</pre></div></div><div class=\"clear\"></div></div><pre>";
542 result.ReplaceAll(
"<span class=\"comment\">",
"<span class=\"codecomment\">");
552 void TDocMacroDirective::AddParameter(
const TString& name,
const char* )
554 if (!name.CompareTo(
"gui", TString::kIgnoreCase))
555 fNeedGraphics = kTRUE;
556 else if (!name.CompareTo(
"source", TString::kIgnoreCase))
558 else Warning(
"AddParameter",
"Unknown option %s!", name.Data());
564 Float_t gLinePadding = 10.;
565 Float_t gColumnPadding = 10.;
569 std::vector<Float_t> fWidths;
574 TLatexLine(TObjArray* columns = 0):
575 fHeight(0.), fColumns(columns) {
if (columns) fWidths.resize(Size());}
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());
584 UInt_t Size()
const {
return fColumns ? fColumns->GetEntries() : 0; }
585 void Delete() {
delete fColumns; }
605 ClassImp(TDocLatexDirective);
610 TDocLatexDirective::~TDocLatexDirective()
612 gSystem->ProcessEvents();
615 gSystem->ProcessEvents();
621 void TDocLatexDirective::AddLine(
const TSubString& line)
623 if (line.Length() == 0)
629 fLatex =
new TMacro(name);
633 GetDocParser()->Strip(sLine);
634 if (sLine.Length() == 0)
637 fLatex->AddLine(sLine);
644 void TDocLatexDirective::CreateLatex(
const char* filename)
647 || !fLatex->GetListOfLines()
648 || !fLatex->GetListOfLines()->First())
651 R__LOCKGUARD(GetHtml()->GetMakeClassMutex());
653 TVirtualPad* oldPad = gPad;
655 Bool_t wasBatch = gROOT->IsBatch();
659 const Float_t canvSize = 1200.;
662 fBBCanvas = (TVirtualPad*)gROOT->ProcessLineFast(
663 Form(
"new TCanvas(\"R__TDocLatexDirective_BBCanvas\",\"fBBCanvas\",%g,%g);", -(canvSize + 4.), canvSize + 28.));
665 Error(
"CreateLatex",
"Cannot create a TCanvas via the interpreter!");
668 fBBCanvas->SetBorderMode(0);
669 fBBCanvas->SetFillColor(kWhite);
671 gSystem->ProcessEvents();
673 std::list<TLatexLine> latexLines;
674 std::vector<Float_t> maxWidth(20);
675 UInt_t numColumns = 0;
676 Float_t totalHeight = gLinePadding;
679 latex.SetTextFont(43);
680 latex.SetTextSize((Float_t)fFontSize);
681 latex.SetTextAlign(12);
684 TIter iterLine(fLatex->GetListOfLines());
685 TObjString* line = 0;
687 if (fSeparator.Length()) {
689 regexp = TPRegexp(fSeparator);
690 }
else fSepIsRegexp = kFALSE;
692 while ((line = (TObjString*) iterLine())) {
693 const TString& str = line->String();
694 TObjArray* split = 0;
696 split =
new TObjArray();
699 if (!fSeparator.Length())
700 split->Add(
new TObjString(str));
703 split = regexp.MatchS(str);
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))));
713 split->Add(
new TObjString(TString(str(prevStart, str.Length() - prevStart))));
717 latexLines.push_back(TLatexLine(split));
718 if (numColumns < (UInt_t)split->GetEntries())
719 numColumns = split->GetEntries();
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];
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;
735 latexLines.back().Height() = heightLine;
736 totalHeight += heightLine + gLinePadding;
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;
744 Float_t totalWidth = posX[numColumns];
749 Float_t padSizeX = totalWidth;
750 Float_t padSizeY = totalHeight + 8.;
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);
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];
767 if ((UInt_t)fAlignment.Length() > iCol)
768 align = fAlignment[(Int_t)iCol];
769 Float_t x = posX[iCol];
772 case 'r': x += maxWidth[iCol] - iLine->Width(iCol);
break;
773 case 'c': x += 0.5*(maxWidth[iCol] - iLine->Width(iCol));
break;
775 if (iLine == latexLines.begin())
776 Error(
"CreateLatex",
"Invalid alignment character '%c'!", align);
778 latex.DrawLatex( x / padSizeX, 1. - posY / padSizeY, str->Data());
780 posY += iLine->Height()/2.;
783 padImg->Print(filename);
786 for (std::list<TLatexLine>::iterator iLine = latexLines.begin();
787 iLine != latexLines.end(); ++iLine) {
794 gROOT->SetBatch(kFALSE);
803 void TDocLatexDirective::GetBoundingBox(TLatex& latex,
const char* text, Float_t& width, Float_t& height)
808 latex.SetText(0.1, 0.5, text);
809 latex.GetBoundingBox(uiWidth, uiHeight);
818 TList* TDocLatexDirective::GetListOfLines()
const
820 return fLatex ? fLatex->GetListOfLines() : 0;
828 Bool_t TDocLatexDirective::GetResult(TString& result)
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);
841 filename += latexFilename;
843 GetDocOutput()->NameSpace2FileName(filename);
846 TString altText(firstLine);
847 GetDocOutput()->ReplaceSpecialChars(altText);
848 altText.ReplaceAll(
"\"",
""");
849 result =
"<span class=\"latex\"><img class=\"latex\" alt=\"";
851 result +=
"\" title=\"LATEX\" src=\"";
853 result +=
"\" /></span>";
855 gSystem->PrependPathName(GetOutputDir(), filename);
858 Info(
"HandleDirective_Latex",
"Writing Latex \"%s\" to file %s.",
859 fLatex->GetName(), filename.Data());
861 CreateLatex(filename);
869 void TDocLatexDirective::AddParameter(
const TString& name,
const char* value )
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;
884 Warning(
"AddParameter",
"Unknown option %s!", name.Data());