Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/intercoms/src/G4UIcommandTree.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 // ********************************************************************
  2 // * License and Disclaimer                                           *
  3 // *                                                                  *
  4 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  5 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  6 // * conditions of the Geant4 Software License,  included in the file *
  7 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  8 // * include a list of copyright holders.                             *
  9 // *                                                                  *
 10 // * Neither the authors of this software system, nor their employing *
 11 // * institutes,nor the agencies providing financial support for this *
 12 // * work  make  any representation or  warranty, express or implied, *
 13 // * regarding  this  software system or assume any liability for its *
 14 // * use.  Please see the license in the file  LICENSE  and URL above *
 15 // * for the full disclaimer and the limitation of liability.         *
 16 // *                                                                  *
 17 // * This  code  implementation is the result of  the  scientific and *
 18 // * technical work of the GEANT4 collaboration.                      *
 19 // * By using,  copying,  modifying or  distributing the software (or *
 20 // * any work based  on the software)  you  agree  to acknowledge its *
 21 // * use  in  resulting  scientific  publications,  and indicate your *
 22 // * acceptance of all terms of the Geant4 Software license.          *
 23 // ********************************************************************
 24 //
 25 // G4UIcommandTree
 26 //
 27 // Author: Makoto Asai (SLAC), 1998
 28 // Midified: Makoto Asai (SLAC), 2021
 29 //   Improve output HTML file layout and add option to sort
 30 //   command/directory names in alphabetic order
 31 // --------------------------------------------------------------------
 32 
 33 #include "G4UIcommandTree.hh"
 34 
 35 #include "G4StateManager.hh"
 36 #include "G4UIdirectory.hh"
 37 #include "G4UImanager.hh"
 38 #include "G4ios.hh"
 39 
 40 #include <fstream>
 41 
 42 // --------------------------------------------------------------------
 43 G4UIcommandTree::G4UIcommandTree(const char* thePathName)
 44 {
 45   pathName = thePathName;
 46 }
 47 
 48 // --------------------------------------------------------------------
 49 G4UIcommandTree::~G4UIcommandTree()
 50 {
 51   for (auto& i : tree) {
 52     delete i;
 53   }
 54 }
 55 
 56 // --------------------------------------------------------------------
 57 G4bool G4UIcommandTree::operator==(const G4UIcommandTree& right) const
 58 {
 59   return (pathName == right.GetPathName());
 60 }
 61 
 62 // --------------------------------------------------------------------
 63 G4bool G4UIcommandTree::operator!=(const G4UIcommandTree& right) const
 64 {
 65   return (pathName != right.GetPathName());
 66 }
 67 
 68 // --------------------------------------------------------------------
 69 void G4UIcommandTree::AddNewCommand(G4UIcommand* newCommand, G4bool workerThreadOnly)
 70 {
 71   G4String commandPath = newCommand->GetCommandPath();
 72   G4String remainingPath = commandPath;
 73   remainingPath.erase(0, pathName.length());
 74   if (remainingPath.empty()) {
 75     if (guidance == nullptr) {
 76       guidance = newCommand;
 77       if (!(newCommand->ToBeBroadcasted())) {
 78         broadcastCommands = false;
 79       }
 80       if (workerThreadOnly) {
 81         newCommand->SetWorkerThreadOnly();
 82       }
 83     }
 84     return;
 85   }
 86 
 87   if (guidance != nullptr) {
 88     auto* dir = static_cast<G4UIdirectory*>(guidance);
 89     ifSort = dir->IfSort();
 90   }
 91   std::size_t i = remainingPath.find('/');
 92   if (i == std::string::npos) {
 93     // Adding a new command to this directory
 94     std::size_t n_commandEntry = command.size();
 95     for (std::size_t i_thCommand = 0; i_thCommand < n_commandEntry; ++i_thCommand) {
 96       if (remainingPath == command[i_thCommand]->GetCommandName()) {
 97         // a command of same name has already defined. do nothing and return.
 98         if (G4UImanager::GetUIpointer()->GetVerboseLevel() > 8) {
 99           G4ExceptionDescription ed;
100           ed << "Command <" << commandPath << "> already exist. New command is not added.";
101           G4Exception("G4UIcommandTree::AddNewCommand", "UI_ComTree_001",
102                       // FatalException,
103                       JustWarning, ed);
104         }
105         return;
106       }
107     }
108     if (!broadcastCommands) {
109       newCommand->SetToBeBroadcasted(false);
110     }
111     if (workerThreadOnly) {
112       newCommand->SetWorkerThreadOnly();
113     }
114     if (ifSort) {
115       auto j = command.cbegin();
116       for (; j != command.cend(); ++j) {
117         if (newCommand->GetCommandPath() < (*j)->GetCommandPath()) {
118           break;
119         }
120       }
121       command.insert(j, newCommand);
122     }
123     else {
124       command.push_back(newCommand);
125     }
126     return;
127   }
128 
129   // Adding a new command to a sub-directory
130   G4String nextPath = pathName;
131   nextPath.append(remainingPath.substr(0, i + 1));
132   std::size_t n_treeEntry = tree.size();
133   for (std::size_t i_thTree = 0; i_thTree < n_treeEntry; ++i_thTree) {
134     if (nextPath == tree[i_thTree]->GetPathName()) {
135       if (!broadcastCommands) {
136         newCommand->SetToBeBroadcasted(false);
137       }
138       tree[i_thTree]->AddNewCommand(newCommand, workerThreadOnly);
139       return;
140     }
141   }
142   // Creating a new sub-directory
143   auto* newTree = new G4UIcommandTree(nextPath);
144   if (ifSort) {
145     auto j = tree.cbegin();
146     for (; j != tree.cend(); ++j) {
147       if (newTree->GetPathName() < (*j)->GetPathName()) {
148         break;
149       }
150     }
151     tree.insert(j, newTree);
152   }
153   else {
154     tree.push_back(newTree);
155   }
156   if (!broadcastCommands) {
157     newCommand->SetToBeBroadcasted(false);
158   }
159   // In case a new sub-directry is created with a new G4UIdirectory
160   // (most-likely this is the case), inherit the sort flag
161   newCommand->SetDefaultSortFlag(ifSort);
162   newTree->AddNewCommand(newCommand, workerThreadOnly);
163   return;
164 }
165 
166 // --------------------------------------------------------------------
167 void G4UIcommandTree::RemoveCommand(G4UIcommand* aCommand, G4bool workerThreadOnly)
168 {
169   if (workerThreadOnly && !(aCommand->IsWorkerThreadOnly())) {
170     return;
171   }
172   G4String commandPath = aCommand->GetCommandPath();
173   commandPath.erase(0, pathName.length());
174   if (commandPath.empty()) {
175     guidance = nullptr;
176   }
177   else {
178     std::size_t i = commandPath.find('/');
179     if (i == std::string::npos) {
180       // Find command
181       std::size_t n_commandEntry = command.size();
182       for (std::size_t i_thCommand = 0; i_thCommand < n_commandEntry; ++i_thCommand) {
183         if (commandPath == command[i_thCommand]->GetCommandName()) {
184           command.erase(command.begin() + i_thCommand);
185           break;
186         }
187       }
188     }
189     else {
190       // Find path
191       G4String nextPath = pathName;
192       nextPath.append(commandPath.substr(0, i + 1));
193       std::size_t n_treeEntry = tree.size();
194       for (std::size_t i_thTree = 0; i_thTree < n_treeEntry; ++i_thTree) {
195         if (nextPath == tree[i_thTree]->GetPathName()) {
196           tree[i_thTree]->RemoveCommand(aCommand);
197           G4int n_commandRemain = tree[i_thTree]->GetCommandEntry();
198           G4int n_treeRemain = tree[i_thTree]->GetTreeEntry();
199           if (n_commandRemain == 0 && n_treeRemain == 0) {
200             G4UIcommandTree* emptyTree = tree[i_thTree];
201             tree.erase(tree.begin() + i_thTree);
202             delete emptyTree;
203           }
204           break;
205         }
206       }
207     }
208   }
209 }
210 
211 // --------------------------------------------------------------------
212 G4UIcommand* G4UIcommandTree::FindPath(const char* commandPath) const
213 {
214   // This function tries to match a command name
215 
216   G4String remainingPath = commandPath;
217   if (remainingPath.find(pathName) == std::string::npos) {
218     return nullptr;
219   }
220   remainingPath.erase(0, pathName.length());
221   std::size_t i = remainingPath.find('/');
222   if (i == std::string::npos) {
223     // Find command
224     std::size_t n_commandEntry = command.size();
225     for (std::size_t i_thCommand = 0; i_thCommand < n_commandEntry; ++i_thCommand) {
226       if (remainingPath == command[i_thCommand]->GetCommandName()) {
227         return command[i_thCommand];
228       }
229     }
230   }
231   else {
232     // Find path
233     G4String nextPath = pathName;
234     nextPath.append(remainingPath.substr(0, i + 1));
235     std::size_t n_treeEntry = tree.size();
236     for (std::size_t i_thTree = 0; i_thTree < n_treeEntry; ++i_thTree) {
237       if (nextPath == tree[i_thTree]->GetPathName()) {
238         return tree[i_thTree]->FindPath(commandPath);
239       }
240     }
241   }
242   return nullptr;
243 }
244 
245 // --------------------------------------------------------------------
246 G4UIcommandTree* G4UIcommandTree::FindCommandTree(const char* commandPath)
247 {
248   // Try to match a command or a path with the one given.
249   // @commandPath : command or path to match
250   // @return the commandTree found or nullptr if not
251 
252   G4String remainingPath = commandPath;
253   if (remainingPath.find(pathName) == std::string::npos) {
254     return nullptr;
255   }
256   remainingPath.erase(0, pathName.length());
257   std::size_t i = remainingPath.find('/');
258   if (i != std::string::npos) {
259     // Find path
260     G4String nextPath = pathName;
261     nextPath.append(remainingPath.substr(0, i + 1));
262     std::size_t n_treeEntry = tree.size();
263     for (std::size_t i_thTree = 0; i_thTree < n_treeEntry; ++i_thTree) {
264       if (tree[i_thTree]->GetPathName() == commandPath) {
265         return tree[i_thTree];
266       }
267       if (nextPath == tree[i_thTree]->GetPathName()) {
268         return tree[i_thTree]->FindCommandTree(commandPath);
269       }
270     }
271   }
272   else {
273     return this;
274   }
275   return nullptr;
276 }
277 
278 // --------------------------------------------------------------------
279 G4String G4UIcommandTree::CompleteCommandPath(const G4String& aCommandPath)
280 {
281   G4String pName = aCommandPath;
282   G4String remainingPath = aCommandPath;
283   G4String empty = "";
284   G4String matchingPath = empty;
285 
286   // find the tree
287   auto jpre = pName.rfind('/');
288   if (jpre != G4String::npos) {
289     pName.erase(jpre + 1);
290   }
291   G4UIcommandTree* aTree = FindCommandTree(pName);
292 
293   if (aTree == nullptr) {
294     return empty;
295   }
296 
297   if (pName.find(pName) == std::string::npos) {
298     return empty;
299   }
300 
301   std::vector<G4String> paths;
302 
303   // list matched directories/commands
304   G4String strtmp;
305   G4int nMatch = 0;
306 
307   G4int Ndir = aTree->GetTreeEntry();
308   G4int Ncmd = aTree->GetCommandEntry();
309 
310   // directory ...
311   for (G4int idir = 1; idir <= Ndir; ++idir) {
312     const G4String& fpdir = aTree->GetTree(idir)->GetPathName();
313     // matching test
314     if (fpdir.find(remainingPath, 0) == 0) {
315       if (nMatch == 0) {
316         matchingPath = fpdir;
317       }
318       else {
319         matchingPath = GetFirstMatchedString(fpdir, matchingPath);
320       }
321       ++nMatch;
322       paths.push_back(fpdir);
323     }
324   }
325 
326   if (paths.size() >= 2) {
327     G4cout << "Matching directories :" << G4endl;
328     for (const auto& path : paths) {
329       G4cout << path << G4endl;
330     }
331   }
332 
333   // command ...
334   std::vector<G4String> commands;
335 
336   for (G4int icmd = 1; icmd <= Ncmd; ++icmd) {
337     G4String fpcmd = aTree->GetPathName() + aTree->GetCommand(icmd)->GetCommandName();
338     // matching test
339     if (fpcmd.find(remainingPath, 0) == 0) {
340       if (nMatch == 0) {
341         matchingPath = fpcmd + " ";
342       }
343       else {
344         strtmp = fpcmd + " ";
345         matchingPath = GetFirstMatchedString(matchingPath, strtmp);
346       }
347       nMatch++;
348       commands.emplace_back(fpcmd + " ");
349     }
350   }
351 
352   if (commands.size() >= 2) {
353     G4cout << "Matching commands :" << G4endl;
354     for (const auto& matched : commands) {
355       G4cout << matched << G4endl;
356     }
357   }
358 
359   return matchingPath;
360 }
361 
362 // --------------------------------------------------------------------
363 G4String G4UIcommandTree::GetFirstMatchedString(const G4String& str1, const G4String& str2) const
364 {
365   std::size_t nlen1 = str1.length();
366   std::size_t nlen2 = str2.length();
367 
368   std::size_t nmin = nlen1 < nlen2 ? nlen1 : nlen2;
369 
370   G4String strMatched;
371   for (G4int i = 0; i < (G4int)nmin; ++i) {
372     if (str1[i] == str2[i]) {
373       strMatched += str1[i];
374     }
375     else {
376       break;
377     }
378   }
379 
380   return strMatched;
381 }
382 
383 // --------------------------------------------------------------------
384 void G4UIcommandTree::ListCurrent() const
385 {
386   G4cout << "Command directory path : " << pathName << G4endl;
387   if (guidance != nullptr) {
388     guidance->List();
389   }
390   G4cout << " Sub-directories : " << G4endl;
391   std::size_t n_treeEntry = tree.size();
392   for (std::size_t i_thTree = 0; i_thTree < n_treeEntry; ++i_thTree) {
393     G4cout << "   " << tree[i_thTree]->GetPathName();
394     if ((tree[i_thTree]->GetGuidance() != nullptr)
395         && tree[i_thTree]->GetGuidance()->IsWorkerThreadOnly())
396     {
397       G4cout << " @ ";
398     }
399     else {
400       G4cout << "   ";
401     }
402     G4cout << tree[i_thTree]->GetTitle() << G4endl;
403   }
404   G4cout << " Commands : " << G4endl;
405   std::size_t n_commandEntry = command.size();
406   for (std::size_t i_thCommand = 0; i_thCommand < n_commandEntry; ++i_thCommand) {
407     G4cout << "   " << command[i_thCommand]->GetCommandName();
408     if (command[i_thCommand]->IsWorkerThreadOnly()) {
409       G4cout << " @ ";
410     }
411     else {
412       G4cout << " * ";
413     }
414     G4cout << command[i_thCommand]->GetTitle() << G4endl;
415   }
416 }
417 
418 // --------------------------------------------------------------------
419 void G4UIcommandTree::ListCurrentWithNum() const
420 {
421   G4cout << "Command directory path : " << pathName << G4endl;
422   if (guidance != nullptr) {
423     guidance->List();
424   }
425   G4int i = 0;
426   G4cout << " Sub-directories : " << G4endl;
427   std::size_t n_treeEntry = tree.size();
428   for (std::size_t i_thTree = 0; i_thTree < n_treeEntry; ++i_thTree) {
429     ++i;
430     G4cout << " " << i << ") " << tree[i_thTree]->GetPathName() << "   "
431            << tree[i_thTree]->GetTitle() << G4endl;
432   }
433   G4cout << " Commands : " << G4endl;
434   std::size_t n_commandEntry = command.size();
435   for (std::size_t i_thCommand = 0; i_thCommand < n_commandEntry; ++i_thCommand) {
436     ++i;
437     G4cout << " " << i << ") " << command[i_thCommand]->GetCommandName() << " * "
438            << command[i_thCommand]->GetTitle() << G4endl;
439   }
440 }
441 
442 // --------------------------------------------------------------------
443 void G4UIcommandTree::List() const
444 {
445   ListCurrent();
446   std::size_t n_commandEntry = command.size();
447   for (std::size_t i_thCommand = 0; i_thCommand < n_commandEntry; ++i_thCommand) {
448     command[i_thCommand]->List();
449   }
450   std::size_t n_treeEntry = tree.size();
451   for (std::size_t i_thTree = 0; i_thTree < n_treeEntry; ++i_thTree) {
452     tree[i_thTree]->List();
453   }
454 }
455 
456 // --------------------------------------------------------------------
457 G4String G4UIcommandTree::CreateFileName(const char* pName)
458 {
459   G4String fn = pName;
460   std::size_t idxs;
461   while ((idxs = fn.find('/')) != std::string::npos) {
462     fn[(G4int)idxs] = '_';
463   }
464   fn += ".html";
465   return fn;
466 }
467 
468 // --------------------------------------------------------------------
469 G4String G4UIcommandTree::ModStr(const char* strS)
470 {
471   G4String sx;
472   G4String str = strS;
473   for (G4int i = 0; i < G4int(str.length()); ++i) {
474     char c = str[i];
475     switch (c) {
476       case '<':
477         sx += "&lt;";
478         break;
479       case '>':
480         sx += "&gt;";
481         break;
482       case '&':
483         sx += "&amp;";
484         break;
485       default:
486         sx += c;
487     }
488   }
489   return sx;
490 }
491 
492 // --------------------------------------------------------------------
493 void G4UIcommandTree::CreateHTML(const G4String& sideBar)
494 {
495   G4String ofileName = CreateFileName(pathName);
496   std::ofstream oF(ofileName, std::ios::out);
497 
498   oF << "<html><head><title>Commands in " << ModStr(pathName) << "</title></head>" << G4endl;
499   oF << "<style> \
500     table,table td,table th { \
501        border:1px solid #eee \
502     } \
503     table td,table th { \
504       padding:5px 20px; \
505       line-height:1.3; \
506       text-align:inherit \
507     } \
508     a { \
509       color:#17a81a; \
510       text-decoration:none; \
511       transition-duration:0.3s \
512     } \
513       a:hover { \
514       color:#17a81a \
515     } \
516     table { \
517       border-collapse:collapse; \
518       border-spacing:0; \
519       margin-bottom:5px; \
520     } \
521     h1 { \
522       font-size:2.25em; \
523       font-weight:300; \
524       letter-spacing:-1px; \
525       line-height:1.15em; \
526       margin-bottom:0.5em; \
527       word-wrap:break-word \
528     } \
529     h2 { \
530       font-size:1.5em; \
531       font-weight:300; \
532       letter-spacing:-1px; \
533       line-height:1.15em; \
534       margin-bottom:0.5em; \
535       word-wrap:break-word \
536     } \
537     h3 { \
538       color:#26282a; \
539       font-weight:300; \
540       font-size:1.3em; \
541       padding:15px 0 15px 0; \
542       border-bottom:2px #eee solid; \
543       word-wrap:break-word \
544     } \
545     .sidebar { \
546       display:block; \
547       position:relative; \
548       position:sticky; \
549       float:left; \
550       -webkit-box-sizing:border-box; \
551       -moz-box-sizing:border-box; \
552       -ms-box-sizing:border-box; \
553       box-sizing:border-box; \
554       width:20%; \
555       padding-right:20px \
556     } \
557     .context { \
558     width:80%; \
559     display:inline-block; \
560     background-color:#fff; \
561     padding: 25px 35px 20px 30px; \
562     -webkit-box-sizing:border-box; \
563     -moz-box-sizing:border-box; \
564     -ms-box-sizing:border-box; \
565     box-sizing:border-box \
566   } \
567     </style>"
568      << G4endl;
569   oF << "<body bgcolor=\"#ffffff\">" << G4endl;
570 
571   // Left Panel
572   if (createHTMLTreeLevel == 0) {
573     oF << "<div class=\"sidebar\">" << sideBar << "</div>" << G4endl;
574   }
575   // Right Panel
576   oF << "<div class=\"context\">";
577   oF << "<h1>" << ModStr(pathName) << "</h1>" << G4endl;
578 
579   if (guidance != nullptr) {
580     for (G4int i = 0; i < (G4int)guidance->GetGuidanceEntries(); ++i) {
581       oF << ModStr(guidance->GetGuidanceLine(i)) << "<br>" << G4endl;
582     }
583   }
584   if (!tree.empty()) {
585     G4String menu = "";
586     G4String newSideBar = "";
587     menu += "<h2>Sub-directories </h2><table>";
588     newSideBar += "<h2><a href=\"" + ofileName + "\">Top level </a></h2><table>";
589     // Build menu short version
590     for (auto& i_thTree : tree) {
591       newSideBar += "<tr><td><a href=\"" + CreateFileName(i_thTree->GetPathName()) + "\">"
592                     + ModStr(i_thTree->GetPathName()) + "</a>";
593     }
594     // Build menu
595     for (auto& i_thTree : tree) {
596       menu += "<tr><td><a href=\"" + CreateFileName(i_thTree->GetPathName()) + "\">"
597               + ModStr(i_thTree->GetPathName()) + "</a>";
598       menu += "</td><td>" + ModStr(i_thTree->GetTitle()) + "</tr>";
599     }
600     menu += "</table>";
601     newSideBar += "</table>";
602     for (auto& i_thTree : tree) {
603       createHTMLTreeLevel++;
604       i_thTree->CreateHTML(newSideBar);
605       createHTMLTreeLevel--;
606     }
607     oF << menu << G4endl;
608   }
609 
610   if (!command.empty()) {
611     oF << "<h2>Commands </h2>" << G4endl;
612 
613     // resume
614     oF << "<table>" << G4endl;
615     for (std::size_t i_thCommand = 0; i_thCommand < command.size(); ++i_thCommand) {
616       G4UIcommand* cmd = command[i_thCommand];
617       oF << "<tr><td><a href=\"#c" << i_thCommand << "\">" << ModStr(cmd->GetCommandName());
618       oF << "</a></td></tr>" << G4endl;
619     }
620     oF << "</table>" << G4endl;
621     for (std::size_t i_thCommand = 0; i_thCommand < command.size(); ++i_thCommand) {
622       G4UIcommand* cmd = command[i_thCommand];
623       oF << "<h3 id=\"c" << i_thCommand << "\">" << ModStr(cmd->GetCommandName());
624       if (cmd->GetParameterEntries() > 0) {
625         for (G4int i_thParam = 0; i_thParam < (G4int)cmd->GetParameterEntries(); ++i_thParam) {
626           oF << " [<i>" << ModStr(cmd->GetParameter(i_thParam)->GetParameterName()) << "</i>]";
627         }
628       }
629       oF << "</h3>" << G4endl;
630       oF << "<p>" << G4endl;
631       for (G4int i = 0; i < (G4int)cmd->GetGuidanceEntries(); ++i) {
632         oF << ModStr(cmd->GetGuidanceLine(i)) << "<br>" << G4endl;
633       }
634       if (!(cmd->GetRange()).empty()) {
635         oF << "<p>Range : " << ModStr(cmd->GetRange()) << G4endl;
636       }
637       std::vector<G4ApplicationState>* availabelStateList = cmd->GetStateList();
638       if (availabelStateList->size() == 6) {
639         oF << "<p>Available at all Geant4 states." << G4endl;
640       }
641       else {
642         oF << "<p>Available Geant4 state(s) : ";
643         for (auto& ias : *availabelStateList) {
644           oF << G4StateManager::GetStateManager()->GetStateString(ias) << " " << G4endl;
645         }
646       }
647       if (cmd->GetParameterEntries() > 0) {
648         oF << "<p>Parameters<table border=1>" << G4endl;
649         for (G4int i_thParam = 0; i_thParam < (G4int)cmd->GetParameterEntries(); ++i_thParam) {
650           G4UIparameter* prm = cmd->GetParameter(i_thParam);
651           oF << "<tr><td>" << ModStr(prm->GetParameterName()) << G4endl;
652           oF << "<td>type " << prm->GetParameterType() << G4endl;
653           oF << "<td>";
654           if (prm->IsOmittable()) {
655             oF << "Omittable : ";
656             if (prm->GetCurrentAsDefault()) {
657               oF << "current value is used as the default value." << G4endl;
658             }
659             else {
660               oF << "default value = " << prm->GetDefaultValue() << G4endl;
661             }
662           }
663           oF << "<td>";
664           if (!(prm->GetParameterRange()).empty()) {
665             oF << "Parameter range : " << ModStr(prm->GetParameterRange()) << G4endl;
666           }
667           else if (!(prm->GetParameterCandidates()).empty()) {
668             oF << "Parameter candidates : " << ModStr(prm->GetParameterCandidates()) << G4endl;
669           }
670         }
671         oF << "</table>" << G4endl;
672       }
673     }
674   }
675   oF << "</div></body></html>" << G4endl;
676   oF.close();
677 }
678 
679 // --------------------------------------------------------------------
680 G4UIcommandTree* G4UIcommandTree::GetTree(const char* comNameC)
681 {
682   G4String comName = comNameC;
683   for (auto& i : tree) {
684     if (comName == i->GetPathName()) {
685       return i;
686     }
687   }
688   return nullptr;
689 }
690