<commit_before>// @(#)root/test:$name:  $:$id: filter.cxx,v 1.0 exp $
// Author: O.Couet

/// The ROOT doxygen filter implements ROOT's specific directives used to generate
/// the ROOT reference guide.
///
/// ## In the ROOT classes
///
/// ### `Begin_Macro` and `End_Macro`
/// The two tags where used the THtml version to generate images from ROOT code.
/// The generated picture is inlined exactly at the place where the macro is
/// defined. The Macro can be defined in two way:
///  - by direct in-lining of the the C++ code
///  - by a reference to a C++ file
/// The tag `Begin_Macro` can have the parameter `(source)`. The directive becomes:
/// `Begin_Macro(source)`. This parameter allows to show the macro's code in addition.
/// `Begin_Macro` also accept the image file type as option. "png" or "svg".
/// "png" is the default value. For example: `Begin_Macro(source, svg)` will show
/// the code of the macro and the image will be is svg format. The "width" keyword
/// can be added to define the width of the picture in pixel: "width=400" will
/// scale a picture to 400 pixel width. This allow to define large picture which
/// can then be scale done to have a better definition.
///
/// ## In the ROOT tutorials
///
/// ROOT tutorials are also included in the ROOT documentation. The tutorials'
/// macros headers should look like:
///
/// ~~~ {.cpp}
/// \file
/// \ingroup tutorial_hist
/// \notebook
/// Getting Contours From TH2D.
///
/// #### Image produced by `.x ContourList.C`
/// The contours values are drawn next to each contour.
/// \macro_image
///
/// #### Output produced by `.x ContourList.C`
/// It shows that 6 contours and 12 graphs were found.
/// \macro_output
///
/// #### `ContourList.C`
/// \macro_code
///
/// \authors  <NAME>, <NAME>
/// ~~~
///
/// This example shows that four new directives have been implemented:
///
///  1. `\macro_image`
///  The images produced by this macro are shown. A caption can be added to document
///  the pictures: `\macro_image This is a picture`. When the option `(nobatch)`
///  is passed, the macro is executed without the batch option.
///  Some tutorials generate pictures (png or pdf) with `Print` or `SaveAs`.
///  Such pictures can be displayed with `\macro_image (picture_name.png[.pdf])`
///  When the option (js) is used the image is displayed as JavaScript.
///
///  2. `\macro_code`
///  The macro code is shown.  A caption can be added: `\macro_code This is code`
///
///  3. `\macro_output`
///  The output produced by this macro is shown. A caption can be added:
///  `\macro_output This the macro output`
///
///  4. `\notebook`
///    To generate the corresponding jupyter notebook. In case the tutorial does
///    not generate any graphics output, the option `-nodraw` should be added.
///
/// Note that the doxygen directive `\authors` or `\author` must be the last one
/// of the macro header.

#include <unistd.h>
#include <stdio.h>
#include <string>
#include <cstring>
#include <iostream>
#include <stdlib.h>
#include <stdarg.h>
#include <memory>

using namespace std;

// Auxiliary functions
void   FilterClass();
void   FilterTutorial();
void   GetClassName();
int    NumberOfImages();
string ImagesList(string&);
void   ExecuteMacro();
void   ExecuteCommand(string);
void   ReplaceAll(string&, const string&, const string&);
string StringFormat(const string fmt_str, ...);
bool   EndsWith(string const &, string const &);
bool   BeginsWith(const string&, const string&);

// Global variables.
FILE  *f;              // Pointer to the file being parsed.
char   gLine[255];     // Current line in the current input file
string gFileName;      // Input file name
string gLineString;    // Current line (as a string) in the current input file
string gClassName;     // Current class name
string gImageName;     // Current image name
string gMacroName;     // Current macro name
string gImageType;     // Type of image used to produce pictures (png, svg ...)
string gImageWidth;    // Width of image
string gCwd;           // Current working directory
string gOutDir;        // Output directory
string gSourceDir;     // Source directory
string gPythonExec;    // Python executable
string gOutputName;    // File containing a macro std::out
bool   gHeader;        // True if the input file is a header
bool   gSource;        // True if the input file is a source file
bool   gPython;        // True if the input file is a Python script.
bool   gImageSource;   // True the source of the current macro should be shown
int    gInMacro;       // >0 if parsing a macro in a class documentation.
int    gImageID;       // Image Identifier.
int    gMacroID;       // Macro identifier in class documentation.


////////////////////////////////////////////////////////////////////////////////
/// Filter ROOT files for Doxygen.

int main(int argc, char *argv[])
{
   // Initialisation
   gFileName      = argv[1];
   gHeader        = false;
   gSource        = false;
   gPython        = false;
   gImageSource   = false;
   gInMacro       = 0;
   gImageID       = 0;
   gMacroID       = 0;
   gOutputName    = "stdout.dat";
   gImageType     = "png";
   gImageWidth    = "";
   if (EndsWith(gFileName,".cxx")) gSource = true;
   if (EndsWith(gFileName,".h"))   gHeader = true;
   if (EndsWith(gFileName,".py"))  gPython = true;
   GetClassName();

   // Retrieve the current working directory
   int last = gFileName.rfind("/");
   gCwd     = gFileName.substr(0,last);

   // Retrieve the output directory
   gOutDir = getenv("DOXYGEN_OUTPUT_DIRECTORY");
   ReplaceAll(gOutDir,"\"","");

   // Retrieve the source directory
   gSourceDir = getenv("DOXYGEN_SOURCE_DIRECTORY");
   ReplaceAll(gSourceDir,"\"","");

   // Retrieve the python executable
   gPythonExec = getenv("PYTHON_EXECUTABLE");
   ReplaceAll(gPythonExec,"\"","");

   // Open the input file name.
   f = fopen(gFileName.c_str(),"r");

   if (gFileName.find("tutorials") != string::npos) FilterTutorial();
   else                                             FilterClass();
}

////////////////////////////////////////////////////////////////////////////////
/// Filter ROOT class for Doxygen.

void FilterClass()
{
   // File for inline macros.
   FILE *m = 0;

   // File header.
   if (gHeader) {
      while (fgets(gLine,255,f)) {
         gLineString = gLine;
         printf("%s",gLineString.c_str());
      }
      fclose(f);
      return;
   }

   // Source file.
   if (gSource) {
      size_t spos = 0;
      while (fgets(gLine,255,f)) {
         gLineString = gLine;

         if (gInMacro && gLineString.find("End_Macro") != string::npos) {
            gInMacro = 0;
            spos = 0;
            if (m) {
               fclose(m);
               m = 0;
               ExecuteCommand(StringFormat("root -l -b -q \"makeimage.C(\\\"%s\\\",\\\"%s\\\",\\\"%s\\\",true,false)\""
                                              , StringFormat("%s_%3.3d.C", gClassName.c_str(), gMacroID).c_str()
                                              , StringFormat("%s_%3.3d.%s", gClassName.c_str(), gImageID, gImageType.c_str()).c_str()
                                              , gOutDir.c_str()));
               ExecuteCommand(StringFormat("rm %s_%3.3d.C", gClassName.c_str(), gMacroID));
            }
            int ImageSize = 300;
            FILE *f = fopen("ImagesSizes.dat", "r");
            fscanf(f, "%d", &ImageSize);
            fclose(f);
            remove("ImagesSizes.dat");
            ReplaceAll(gImageWidth,"IMAGESIZE",StringFormat("%d",ImageSize));
            ReplaceAll(gLineString,"End_Macro", StringFormat("\\image html pict1_%s_%3.3d.%s %s", gClassName.c_str(), gImageID, gImageType.c_str(), gImageWidth.c_str()));
            if(!gImageSource) ReplaceAll(gLineString,"/// ","");
            gImageSource = false;
         }

         if (gInMacro) {
            if (spos) gLineString = gLineString.substr(spos);
            if (gInMacro == 1) {
               if (EndsWith(gLineString,".C\n") || (gLineString.find(".C(") != string::npos)) {
                  ExecuteMacro();
                  gInMacro++;
               } else {
                  gMacroID++;
                  m = fopen(StringFormat("%s_%3.3d.C", gClassName.c_str(), gMacroID).c_str(), "w");
                  if (m) fprintf(m,"%s",gLineString.c_str());
                  if (BeginsWith(gLineString,"{")) {
                     if (gImageSource) {
                        ReplaceAll(gLineString,"{"
                                                , StringFormat("\\include %s_%3.3d.C"
                                                , gClassName.c_str()
                                                , gMacroID));<commit_msg>undo fix to remove extra /// (#5433)<commit_after>// @(#)root/test:$name:  $:$id: filter.cxx,v 1.0 exp $
// Author: O.Couet

/// The ROOT doxygen filter implements ROOT's specific directives used to generate
/// the ROOT reference guide.
///
/// ## In the ROOT classes
///
/// ### `Begin_Macro` and `End_Macro`
/// The two tags where used the THtml version to generate images from ROOT code.
/// The generated picture is inlined exactly at the place where the macro is
/// defined. The Macro can be defined in two way:
///  - by direct in-lining of the the C++ code
///  - by a reference to a C++ file
/// The tag `Begin_Macro` can have the parameter `(source)`. The directive becomes:
/// `Begin_Macro(source)`. This parameter allows to show the macro's code in addition.
/// `Begin_Macro` also accept the image file type as option. "png" or "svg".
/// "png" is the default value. For example: `Begin_Macro(source, svg)` will show
/// the code of the macro and the image will be is svg format. The "width" keyword
/// can be added to define the width of the picture in pixel: "width=400" will
/// scale a picture to 400 pixel width. This allow to define large picture which
/// can then be scale done to have a better definition.
///
/// ## In the ROOT tutorials
///
/// ROOT tutorials are also included in the ROOT documentation. The tutorials'
/// macros headers should look like:
///
/// ~~~ {.cpp}
/// \file
/// \ingroup tutorial_hist
/// \notebook
/// Getting Contours From TH2D.
///
/// #### Image produced by `.x ContourList.C`
/// The contours values are drawn next to each contour.
/// \macro_image
///
/// #### Output produced by `.x ContourList.C`
/// It shows that 6 contours and 12 graphs were found.
/// \macro_output
///
/// #### `ContourList.C`
/// \macro_code
///
/// \authors  <NAME>, <NAME>
/// ~~~
///
/// This example shows that four new directives have been implemented:
///
///  1. `\macro_image`
///  The images produced by this macro are shown. A caption can be added to document
///  the pictures: `\macro_image This is a picture`. When the option `(nobatch)`
///  is passed, the macro is executed without the batch option.
///  Some tutorials generate pictures (png or pdf) with `Print` or `SaveAs`.
///  Such pictures can be displayed with `\macro_image (picture_name.png[.pdf])`
///  When the option (js) is used the image is displayed as JavaScript.
///
///  2. `\macro_code`
///  The macro code is shown.  A caption can be added: `\macro_code This is code`
///
///  3. `\macro_output`
///  The output produced by this macro is shown. A caption can be added:
///  `\macro_output This the macro output`
///
///  4. `\notebook`
///    To generate the corresponding jupyter notebook. In case the tutorial does
///    not generate any graphics output, the option `-nodraw` should be added.
///
/// Note that the doxygen directive `\authors` or `\author` must be the last one
/// of the macro header.

#include <unistd.h>
#include <stdio.h>
#include <string>
#include <cstring>
#include <iostream>
#include <stdlib.h>
#include <stdarg.h>
#include <memory>

using namespace std;

// Auxiliary functions
void   FilterClass();
void   FilterTutorial();
void   GetClassName();
int    NumberOfImages();
string ImagesList(string&);
void   ExecuteMacro();
void   ExecuteCommand(string);
void   ReplaceAll(string&, const string&, const string&);
string StringFormat(const string fmt_str, ...);
bool   EndsWith(string const &, string const &);
bool   BeginsWith(const string&, const string&);

// Global variables.
FILE  *f;              // Pointer to the file being parsed.
char   gLine[255];     // Current line in the current input file
string gFileName;      // Input file name
string gLineString;    // Current line (as a string) in the current input file
string gClassName;     // Current class name
string gImageName;     // Current image name
string gMacroName;     // Current macro name
string gImageType;     // Type of image used to produce pictures (png, svg ...)
string gImageWidth;    // Width of image
string gCwd;           // Current working directory
string gOutDir;        // Output directory
string gSourceDir;     // Source directory
string gPythonExec;    // Python executable
string gOutputName;    // File containing a macro std::out
bool   gHeader;        // True if the input file is a header
bool   gSource;        // True if the input file is a source file
bool   gPython;        // True if the input file is a Python script.
bool   gImageSource;   // True the source of the current macro should be shown
int    gInMacro;       // >0 if parsing a macro in a class documentation.
int    gImageID;       // Image Identifier.
int    gMacroID;       // Macro identifier in class documentation.


////////////////////////////////////////////////////////////////////////////////
/// Filter ROOT files for Doxygen.

int main(int argc, char *argv[])
{
   // Initialisation
   gFileName      = argv[1];
   gHeader        = false;
   gSource        = false;
   gPython        = false;
   gImageSource   = false;
   gInMacro       = 0;
   gImageID       = 0;
   gMacroID       = 0;
   gOutputName    = "stdout.dat";
   gImageType     = "png";
   gImageWidth    = "";
   if (EndsWith(gFileName,".cxx")) gSource = true;
   if (EndsWith(gFileName,".h"))   gHeader = true;
   if (EndsWith(gFileName,".py"))  gPython = true;
   GetClassName();

   // Retrieve the current working directory
   int last = gFileName.rfind("/");
   gCwd     = gFileName.substr(0,last);

   // Retrieve the output directory
   gOutDir = getenv("DOXYGEN_OUTPUT_DIRECTORY");
   ReplaceAll(gOutDir,"\"","");

   // Retrieve the source directory
   gSourceDir = getenv("DOXYGEN_SOURCE_DIRECTORY");
   ReplaceAll(gSourceDir,"\"","");

   // Retrieve the python executable
   gPythonExec = getenv("PYTHON_EXECUTABLE");
   ReplaceAll(gPythonExec,"\"","");

   // Open the input file name.
   f = fopen(gFileName.c_str(),"r");

   if (gFileName.find("tutorials") != string::npos) FilterTutorial();
   else                                             FilterClass();
}

////////////////////////////////////////////////////////////////////////////////
/// Filter ROOT class for Doxygen.

void FilterClass()
{
   // File for inline macros.
   FILE *m = 0;

   // File header.
   if (gHeader) {
      while (fgets(gLine,255,f)) {
         gLineString = gLine;
         printf("%s",gLineString.c_str());
      }
      fclose(f);
      return;
   }

   // Source file.
   if (gSource) {
      size_t spos = 0;
      while (fgets(gLine,255,f)) {
         gLineString = gLine;

         if (gInMacro && gLineString.find("End_Macro") != string::npos) {
            gImageSource = false;
            gInMacro = 0;
            spos = 0;
            if (m) {
               fclose(m);
               m = 0;
               ExecuteCommand(StringFormat("root -l -b -q \"makeimage.C(\\\"%s\\\",\\\"%s\\\",\\\"%s\\\",true,false)\""
                                              , StringFormat("%s_%3.3d.C", gClassName.c_str(), gMacroID).c_str()
                                              , StringFormat("%s_%3.3d.%s", gClassName.c_str(), gImageID, gImageType.c_str()).c_str()
                                              , gOutDir.c_str()));
               ExecuteCommand(StringFormat("rm %s_%3.3d.C", gClassName.c_str(), gMacroID));
            }
            int ImageSize = 300;
            FILE *f = fopen("ImagesSizes.dat", "r");
            fscanf(f, "%d", &ImageSize);
            fclose(f);
            remove("ImagesSizes.dat");
            ReplaceAll(gImageWidth,"IMAGESIZE",StringFormat("%d",ImageSize));
            ReplaceAll(gLineString,"End_Macro", StringFormat("\\image html pict1_%s_%3.3d.%s %s", gClassName.c_str(), gImageID, gImageType.c_str(), gImageWidth.c_str()));
         }

         if (gInMacro) {
            if (spos) gLineString = gLineString.substr(spos);
            if (gInMacro == 1) {
               if (EndsWith(gLineString,".C\n") || (gLineString.find(".C(") != string::npos)) {
                  ExecuteMacro();
                  gInMacro++;
               } else {
                  gMacroID++;
                  m = fopen(StringFormat("%s_%3.3d.C", gClassName.c_str(), gMacroID).c_str(), "w");
                  if (m) fprintf(m,"%s",gLineString.c_str());
                  if (BeginsWith(gLineString,"{")) {
                     if (gImageSource) {
                        ReplaceAll(gLineString,"{"
                                                , StringFormat("\\include %s_%3.3d.C"
                                                , gClassName.c_str()
                                                , gMacroID));
{'fraction_non_alphanumeric': 0.15315783396836394, 'fraction_numerical': 0.006350305969287611, 'mean_word_length': 2.0671033994334276, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 28, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5373560', 'n_tokens_mistral': 5234, 'n_tokens_neox': 5028, 'n_words': 1658}