Secciones de la página

dct. tol


Declaraciones


Constantes


Funciones


Time oriented language


Árbol de ficheros

Funciones

Set DctGetInterface()

Set DctGetHeader()

Set DctGetHeaderRobust()

Set DctTolSplit()

Real DctRawCode()

Text DctLink()

Text DctPstReplace()

Text DctSecReplace()

Text DctFileLanguage()

Set DctDeclare()

Real DctAppendPost()

Real DctWriteHeader()

Real DctWriteTree()

Real DctWriteDisplay()

Real DctWriteIndex()

Real DctWriteCode()

Real DctWriteSource()

Real DctMake()

Set DctOcurrences()

Set DctLinkFileDeclaration()

Set DctLinkAllDeclaration()

Tol

Artículos del sitio

Presentación de Tol

Todos los programas

Simuladores visuales

Sitios que me gustan

Por categorías

Algoritmia

Búsqueda y ordenación

Computación fisiológica

Editorial y edición

Gráficos de datos

Herramientas y utilidades

Hipertexto

Informática forense

Lectura óptica de datos

Metaprogramación

No determinista

Ofimática

Recursión e iteración

Reglas y restricciones

Series y estadística









dct.tol de Dct.Writer

Funciones de docuentacion de Tol a una agenda de post.

Declaraciones

Constantes

  • Text DctTdy
    Fecha del dia que se genera la documentacion.
  • Real DctDesLen
    Numero maximo de caracteres de una descripcion.
  • Text DctUndLinHtm
    Separador de underscores en Html.
  • Text DctUndLinAsc
    Separador de underscores en Ascii.
  • Text DctTolSepBas
    Separador basico de codigo Tol.
  • Text DctTolSepLow
    Separador de codigo Tol de bajo nivel.
  • Text DctTolSepTop
    Separador de codigo Tol de alto nivel.
  • Text DctBr2
    Para forzar separaciones en comentarios.
  • Text DctPstSee
    Semilla de un post.
  • Text DctPstSep
    Separador entre posts.

Funciones

  • Set DctGetInterface(Text tolCod)
    Retorna, para una variable o una funcion, un conjunto de textos formado por [clase function|variable, tipo de retorno, nombre, argumentos, descripcion], en el caso de variables los argumentos son la tira vacia. En caso de error retorna Empty.
  • Set DctGetHeader(Text codHea)
    Retorna un conjunto con los 4 atributos de la cabecera de un fichero que son el nombre del fichero, el autor, sus clases y su proposito.
  • Set DctGetHeaderRobust(Text codHea, Text filNam, Text filPur)
    Retorna un conjunto con los 4 atributos de la cabecera de un fichero que son el nombre del fichero, el autor, sus clases y su proposito.
  • Set DctTolSplit(Text codInp)
    Retorna un conjunto de secciones (FILE, CONSTANTS, FUNCTIONS, etc.) resultado de romper el codigo Tol que recibe como parametro por secciones. Cada seccion esta formada por un conjunto con su nombre y su conjunto de declaraciones, salvo: - la primera que contiene la información general de la cabecera y - las secciones de codigo en bruto que retorna un conjunto formado por el texto nombre de la foncion y un texto (no un conjunto) que es el codigo en bruto formateado.
  • Real DctRawCode(Set dctSec)
    Retorna cierto si el segundo componente no existe o si existe no es un conjunto de declaraciones de codigo. Lo natural en caso de codigo bruto es que exista pero sea un texto con dicho codigo en bruto.
  • Text DctLink(Text prgNam, Text filNam, Text pstSec, Text ctrRet)
    Retorna: - si ctrRet=F el fichero de salida Html, salvo los Pdf que son Pdf, - si ctrRet=L el enlace global al programa, fichero y seccion y - si ctrRet=A el tag a href al enlace global. Si no hay fichero filNam asume la pagina principal index, lo que no tendria que suceder. Si no hay seccion no añade el #seccion.
  • Text DctPstReplace(Text prgNam, Text filNam, Text pstSec, Text addCla, Text pstSta, Text pstAut, Text pstDes, Text pstHtm)
    Retorna por reemplazamiento un post con todos sus campos.
  • Text DctSecReplace(Text pstSec)
    Retorna los nombres en castellano de los diferentes tipos de secciones.
  • Text DctFileLanguage(Text filNam, Real ctrLar)
    Retorna el nombre del lenguaje de programación en formato corto o largo dependiendo de ctrLar.
  • Set DctDeclare(Text prgNam, Text filNam, Text decCat, Text decTyp, Text decNam, Text decArg, Text ascDes)
    Para una declaracion Tol retorna un set de 5 elementos formado por: a) clases: Variable/Funcion, tipo Tol y nombre b) declaracion: tipo nombre(argumentos) c) descripcion: tipo nombre(argumentos) y proposito d) codigo para un li con tipo nombre(argumentos) y proposito y e) a href link para que el codigo de otras funciones le enlacen.
  • Real DctAppendPost(Text outFil, Text prgNam, Text filNam, Text pstSec, Text addCla, Text pstSta, Text pstAut, Text pstDes, Text pstHtm)
    Añade un post con todos sus campos al fichero de agenda llamado outFil. La cabecera no lleva separador, el resto es separador mas contenido.
  • Real DctWriteHeader(Text prgNam, Text filNam, Set dctCab, Text agePth, Text levCla)
    Inicia la agenda escribiendo el post de la cabecera de un programa.
  • Real DctWriteTree(Text prgNam, Text filNam, Set dctCab, Text agePth, Set inpTre, Text levCla)
    Escribe el post del arbol de navegacion de un programa con el fichero en curso activo.
  • Real DctWriteDisplay(Text prgNam, Text filNam, Set dctCab, Text agePth)
    Escribe el post de la presentación realizada a mano de un fichero filNam de un programa prgNam.
  • Real DctWriteIndex(Text prgNam, Text filNam, Set dctSHi, Text agePth, Text funDmp)
    Escribe el post del indice de declaraciones de variables y funciones de un fichero filNam de un programa prgNam. Es un indice con enlaces al resto de declaraciones, pero se le titula como declaraciones pues no indexa otras secciones.
  • Real DctWriteCode(Text prgNam, Text filNam, Set dctSHi, Text agePth, Set lnkTab)
    Escribe todos los posts de secciones de codigo (constantes, funciones, etc.) y todos los post de cada una de las estructuras, constantes, funciones, etc. de un fichero filNam de un programa prgNam.
  • Real DctWriteSource(Text prgNam, Text filNam, Set dctCab, Text agePth, Text codTxt, Set lnkTab, Text codDmp)
    Escribe el post de la presentación realizada a mano de un fichero filNam de un programa prgNam.
  • Real DctMake(Text dctPre, Set dctTre)
    Proceso principal de documentacion de todo el arbol de fichero de entrada.
  • Set DctOcurrences(Text funDmp, Text codDmp, Real ctrOcc)
    Retorna una tabla de funciones y numero de occurencias para aquellas funciones que no superan ctrOcc, como efecto latelar las visualiza.
  • Set DctLinkFileDeclaration(Text prgNam, Text filNam, Set dctSHi)
    Retorna una tabla de pares nombre de variable o funcion y su enlace de un fichero Tol de un programa.
  • Set DctLinkAllDeclaration(Set filTab)
    Retorna una tabla de pares nombre de variable o funcion y su enlace de todos los ficheros Tol de un programa.

Constantes

Text DctTdy

//////////////////////////////////////////////////////////////////////////////
Text DctTdy = FormatDate(Today, "%c%Y/%m/%d");
//////////////////////////////////////////////////////////////////////////////
PutDescription("Fecha del dia que se genera la documentacion.", DctTdy);
//////////////////////////////////////////////////////////////////////////////

Real DctDesLen

//////////////////////////////////////////////////////////////////////////////
Real DctDesLen = 350;
//////////////////////////////////////////////////////////////////////////////
PutDescription("Numero maximo de caracteres de una descripcion.", DctDesLen);
//////////////////////////////////////////////////////////////////////////////

Text DctUndLinHtm

//////////////////////////////////////////////////////////////////////////////
Text DctUndLinHtm = Repeat("_",78);
//////////////////////////////////////////////////////////////////////////////
PutDescription("Separador de underscores en Html.", DctUndLinHtm);
//////////////////////////////////////////////////////////////////////////////

Text DctUndLinAsc

//////////////////////////////////////////////////////////////////////////////
Text DctUndLinAsc = Repeat("_",78);
//////////////////////////////////////////////////////////////////////////////
PutDescription("Separador de underscores en Ascii.", DctUndLinAsc);
//////////////////////////////////////////////////////////////////////////////

Text DctTolSepBas

//////////////////////////////////////////////////////////////////////////////
Text DctTolSepBas = "\n"+Repeat("/",78)+"\n";
//////////////////////////////////////////////////////////////////////////////
PutDescription("Separador basico de codigo Tol.", DctTolSepBas);
//////////////////////////////////////////////////////////////////////////////

Text DctTolSepLow

//////////////////////////////////////////////////////////////////////////////
Text DctTolSepLow = "\n"+DctTolSepBas;
//////////////////////////////////////////////////////////////////////////////
PutDescription("Separador de codigo Tol de bajo nivel.", DctTolSepLow);
//////////////////////////////////////////////////////////////////////////////

Text DctTolSepTop

//////////////////////////////////////////////////////////////////////////////
Text DctTolSepTop = "\n"+DctTolSepLow+"// ";
//////////////////////////////////////////////////////////////////////////////
PutDescription("Separador de codigo Tol de alto nivel.", DctTolSepTop);
//////////////////////////////////////////////////////////////////////////////

Text DctBr2

//////////////////////////////////////////////////////////////////////////////
Text DctBr2 = Char(12); // Form feed
//////////////////////////////////////////////////////////////////////////////
PutDescription("Para forzar separaciones en comentarios.", DctTolSepTop);
//////////////////////////////////////////////////////////////////////////////

Text DctPstSee

//////////////////////////////////////////////////////////////////////////////
Text DctPstSee = "
<Pst.Cla> _CLA_
<Pst.Sta> B
<Pst.Dte> _DTE_
<Pst.Aut> _AUT_
<Pst.Pth> web/dct_writer/dct_tol.html
<Pst.Lnk> ../dct_writer/dct_tol.html#Dct_Writer_Text_DctPstSee
<Pst.Glo> _GLO_
<Pst.Loc> Text DctPstSee
<Pst.Des> _DES_
<Pst.Htm>
_HTM_
<Pst.End>
";
//////////////////////////////////////////////////////////////////////////////
PutDescription("Semilla de un post.", DctTolSepTop);
//////////////////////////////////////////////////////////////////////////////

Text DctPstSep

//////////////////////////////////////////////////////////////////////////////
Text DctPstSep = Repeat("_",78)+"\n";
//////////////////////////////////////////////////////////////////////////////
PutDescription("Separador entre posts.", DctPstSep);
//////////////////////////////////////////////////////////////////////////////

Funciones

Set DctGetInterface()

//////////////////////////////////////////////////////////////////////////////
Set DctGetInterface(Text tolCod)
//////////////////////////////////////////////////////////////////////////////
{
  Text clsQuo(Text desTxt) { Replace(desTxt, Char(34), "") };
  
  Set  trePar = Parse(tolCod)[3]; // Acesso al arbol del parse
  
  Case(
    trePar[1][1] == "=";   // Si es variable
    {
      Text varCla = "variable";
      Text varTyp = trePar[1][3][1][1];         // Tipo
      Text varNam = trePar[1][3][1][3][1][1];   // Nombre
      Text varDeQ = trePar[2][3][1][1];         // Descripcion con quote
      Text varDes = clsQuo(varDeQ);             // Descripcion sin quote
      Text argTxt = "";                         // Argumentos no hay

      SetOfText(varCla, varTyp, varNam, argTxt, varDes)
    },
    trePar[1][1] == "#F#"; // Si es funcion
    {
      Text funCla = "function";
      Text funTyp = trePar[1][3][1][1];         // Tipo
      Text funNam = trePar[1][3][1][3][1][1];   // Nombre
      Text funDeQ = trePar[2][3][1][1];         // Descripcion con quote
      Text funDes = clsQuo(funDeQ);             // Descripcion sin quote

      Set  argSet = trePar[1][3][1][3][1][3];   // Conjunto de argumentos
      Real argNum = Card(argSet);               // Numero de argumentos

      Set  argCic = For(1, argNum, Text(Real argPos)
      {
        Set  argInf = argSet[argPos]; // Informacion del argumento
        Text argTyp = argInf[1];
        Text argNam = argInf[3][1][1];

        If(EQ(argPos, 1), "", ", ")+ argTyp+" "+argNam
      });
      Text argTxt = "(" + SetSum(argCic) + ")";

      SetOfText(funCla, funTyp, funNam, argTxt, funDes)
    },
    TRUE, Empty) // Ni variable ni funcion
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna, para una variable o una funcion, un conjunto de textos formado por
[clase function|variable, tipo de retorno, nombre, argumentos, descripcion],
en el caso de variables los argumentos son la tira vacia.
En caso de error retorna Empty.",
DctGetInterface);
//////////////////////////////////////////////////////////////////////////////

Set DctGetHeader()

//////////////////////////////////////////////////////////////////////////////
Set DctGetHeader(Text codHea) // Trozo de codigo o todo para extraer atributos
//////////////////////////////////////////////////////////////////////////////
{
  Text repLar = ReplaceTable(codHea, [[ // Reemplazar los largos
    [["-- ///", "//////"]],                                  // Sql
    [[""/*////", "//////"]], [[ "////*/", "//////"]],         // Css
    [["/*-///", "//////"]], [[ "///-*/", "//////"]],         // Css
    [["# ////", "//////"]], [[ "#/////", "//////"]],         // Glp
    [[":: ///", "//////"]], [[ "::////", "//////"]],         // Bat
    [["<!-- /", "//////"]], [[ "// -->", "//////"]] ]], 1);  // Htm

  Text repSor = ReplaceTable(repLar, [[ // Reemplazar los cortos
    [["--",  "//"]],  // Sql
    [["# ",  "//"]],  // Glp
    [["::",  "//"]],  // Bat
    [[" : ", ": "]] ]], 4); // Como maximo 4 blancos antes de :
    
  Text filHea = repSor+"\n"; // Asegurarse el ultimo salto de linea
  
  Text filNam = TxtBetween2Tag(filHea, "FILE: ",    "\n", TRUE);
  Text autIde = TxtBetween2Tag(filHea, "AUTHOR: ",  "\n", TRUE);
  Text claLst = TxtBetween2Tag(filHea, "CLASS: ",   "\n", TRUE);
  Text verLst = TxtBetween2Tag(filHea, "VERSION: ", "\n", TRUE);
  Text purTxt = TxtBetween2Tag(filHea, "PURPOSE: ", DctTolSepBas, FALSE);
  Text purCls = ReplaceTable(purTxt, [[ [["\n// ",  "\n"]],
                                        [["_\n",    DctBr2+"\n"]] ]]);
  Text remTxt = TxtBetween2Tag(filHea, "COMMENT: ", DctTolSepBas, FALSE);
  Text remCls = Replace(Replace(remTxt, "\n// ", "\n"), "\n//", "\n");

  [[ filNam, autIde, claLst, verLst, purCls, remCls ]]
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna un conjunto con los 4 atributos de la cabecera de un fichero que
son el nombre del fichero, el autor, sus clases y su proposito.",
DctGetHeader);
//////////////////////////////////////////////////////////////////////////////
"

Set DctGetHeaderRobust()

//////////////////////////////////////////////////////////////////////////////
Set DctGetHeaderRobust(Text codHea, // Trozo de codigo para extraer atributos
                       Text filNam, // Nombre del fichero si no se encuentra
                       Text filPur) // Descripcion si no se encuentra
//////////////////////////////////////////////////////////////////////////////
{
Text WriteLn(filPur);
  Real posFil = TextFind(codHea, " FILE",    0);      // Nombre del fichero
  Real posDts = TextFind(codHea, ": ",       posFil); // : tras el nombre
  Real posPur = TextFind(codHea, " PURPOSE", posDts); // Proposito tras :

  Set  filAtr = If(And(posFil, posDts, posPur, LE(posPur, 500)),
                DctGetHeader(codHea),   // Parece una cabecera
                [["","","","","",""]]); // No parece una cabecera

  Text filAut = "http://www.asolver.com";
  Text chkNam = If(filAtr[1]=="", filNam, filAtr[1]); 
  Text chkAut = If(filAtr[2]=="", filAut, filAtr[2]);
  Text chkCla = filAtr[3];
  Text chkVer = filAtr[4];
  Text chkPur = If(filAtr[5]=="", filPur, filAtr[5]); 
  Text chkRem = filAtr[6];

  [[ chkNam, chkAut, chkCla, chkVer, chkPur, chkRem ]]
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna un conjunto con los 4 atributos de la cabecera de un fichero que
son el nombre del fichero, el autor, sus clases y su proposito.",
DctGetHeaderRobust);
//////////////////////////////////////////////////////////////////////////////

Set DctTolSplit()

//////////////////////////////////////////////////////////////////////////////
Set DctTolSplit(Text codInp) // Codigo Tol
//////////////////////////////////////////////////////////////////////////////
{
  Set  setTop = TxtTokenizer(codInp, DctTolSepTop); // Rotura de alto nivel
  
  Set  treTop = DctGetHeader(setTop[1]); // Cabecera del fichero

  Set  treSec = For(2, Card(setTop), Set(Real posSec)
  {
    Text codSec = setTop[posSec]+"\n"; // Ultima linea con su salto de linea
    Real lenSec = TextLength(codSec);
    Real heaEnd = TextFind(codSec, DctTolSepBas);
    Text heaSec = Compact(Sub(codSec, 1, heaEnd-1));
    Text decSec = Sub(codSec, heaEnd+TextLength(DctTolSepBas), lenSec);
    Set  decSet = TxtTokenizer("\n\n"+decSec, DctTolSepLow);

    If(EQ(Card(decSet),1), [[heaSec, SHiCompact(SHiTolPre(decSec))]], // Bruto
    { // Codigo correctamente delimitado
      Set  htmSet = For(2, Card(decSet), Set(Real posCod)
      {
        Text decCod = DctTolSepLow+decSet[posCod];
        Set  decInf = DctGetInterface(decCod); // 5 elementos

        decInf << SetOfText(SHiCompact(SHiTolPre(decCod))) // 6 elementos
      });
      [[heaSec, htmSet]]
    })
  });

  Set  treAll = [[ treTop ]] << treSec;

  treAll
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna un conjunto de secciones (FILE, CONSTANTS, FUNCTIONS, etc.) resultado
de romper el codigo Tol que recibe como parametro por secciones.
Cada seccion esta formada por un conjunto con su nombre y su conjunto de
declaraciones, salvo:
- la primera que contiene la información general de la cabecera y
- las secciones de codigo en bruto que retorna un conjunto formado por el
  texto nombre de la foncion y un texto (no un conjunto) que es el codigo
  en bruto formateado.",
DctTolSplit);
//////////////////////////////////////////////////////////////////////////////

Real DctRawCode()

//////////////////////////////////////////////////////////////////////////////
Real DctRawCode(Set dctSec) // Seccion de declaracion
//////////////////////////////////////////////////////////////////////////////
{ If(EQ(Card(dctSec), 2), Grammar(dctSec[2])!="Set", TRUE) };
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna cierto si el segundo componente no existe o si existe no es un 
conjunto de declaraciones de codigo. Lo natural en caso de codigo bruto es
que exista pero sea un texto con dicho codigo en bruto.",
DctRawCode);
//////////////////////////////////////////////////////////////////////////////

Text DctLink()

//////////////////////////////////////////////////////////////////////////////
Text DctLink(Text prgNam, // Nombre del programa
             Text filNam, // Nombre del fichero
             Text pstSec, // Seccion
             Text ctrRet) // Si F->fichero, L->link, A->a href y T A+title
//////////////////////////////////////////////////////////////////////////////
{
  Text filChk = If(filNam=="", "index", filNam); // No deberia ser vacio
  Text filExt = GetFileExtension(filChk);        // Extension
  Text filUrl =Case(
    filExt<:[["pdf","html"]],
      FilDelExtLow(prgNam)+"/"+filChk, // Pdf, Html no se cambian
    filExt=="htm",
      FilDelExtLow(prgNam)+"/"+filChk+"l",  // Poner la l de html
    TRUE,
      FilDelExtLow(prgNam +"/"+filChk)+".html");   // En general

  If(ctrRet=="F", "web/"+filUrl,
  {
    Text secUrl = TxtCat("../"+filUrl, "#", Htm2Ide(prgNam, pstSec, FALSE));
    Text secTit = pstSec+" en "+prgNam;
    Case(
      ctrRet=="L", secUrl,
      ctrRet=="A", "<a href="+Q(secUrl)+">",
      ctrRet=="T", "<a href="+Q(secUrl)+" title="+Q(secTit)+">",
      TRUE,        secUrl)      
  })
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna:
- si ctrRet=F el fichero de salida Html, salvo los Pdf que son Pdf,
- si ctrRet=L el enlace global al programa, fichero y seccion y
- si ctrRet=A el tag a href al enlace global.
Si no hay fichero filNam asume la pagina principal index, lo que no tendria
que suceder.
Si no hay seccion no añade el #seccion.",
DctLink);
//////////////////////////////////////////////////////////////////////////////

Text DctPstReplace()

//////////////////////////////////////////////////////////////////////////////
Text DctPstReplace(Text prgNam, // Nombre del programa
                   Text filNam, // Nombre del fichero
                   Text pstSec, // Seccion, para local, global y header
                   Text addCla, // Clase adicionales
                   Text pstSta, // Estado
                   Text pstAut, // Autor
                   Text pstDes, // Descripcion
                   Text pstHtm) // Html del post
//////////////////////////////////////////////////////////////////////////////
{
  Text pstPth = DctLink(prgNam, filNam, pstSec, "F"); // Fichero de salida
  Text pstLnk = DctLink(prgNam, filNam, pstSec, "L"); // Link a url
  
  Text pstCat = If(pstSec=="Presentación", "Escrito", "Código");
  Text topCla = pstCat+"; " + prgNam + "; " +  // Todas existen
                If(filNam==pstSec, filNam, filNam+"; "+pstSec) + "; " +
                DctFileLanguage(filNam,FALSE); // Lenguaje de programacion
  Text pstCla = TxtCat(topCla, "; ", addCla);
  
  Text lblGlo = pstSec+" de "+prgNam;
  Text wraDes = TxtLineWrap(pstDes, DctDesLen, TRUE)[1];
  Text nowFmt = DctTdy+" ["+FormatReal(Time, "%9.4lf")+"]"; // [9999.9999]

  // Eliminar los propios autoseparadores que puede contener pstHtm
  Text clsHtm = Replace(pstHtm, DctUndLinAsc, DctUndLinHtm);
  
  ReplaceTable(DctPstSee, [[ // Siempre se usa la misma semilla
    [["_CLA_",  pstCla]],
    [["B",  pstSta]],
    [["_DTE_",  nowFmt]], // Fecha DctTdy
    [["_AUT_",  pstAut]],
    [["web/dct_writer/dct_tol.html",  pstPth]], // Ruta del fichero Html de salida
    [["../dct_writer/dct_tol.html#Dct_Writer_Text_DctPstReplace__",  pstLnk]], // Enlace global
    [["_GLO_",  lblGlo]], // Titulo ventana, enlaces y headers globales
    [["Text DctPstReplace()",  pstSec]], // Etiqueta a names, enlaces y header local
    [["_DES_",  wraDes]], // Descripcion ajustada a tamaño
    [["_HTM_",  clsHtm]]  // Sin lineas de undersecore
  ]], 1) // 1 vuelta solo pues Htm puede contener etiquetas _XXX_ parecidas
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna por reemplazamiento un post con todos sus campos.",
DctPstReplace);
//////////////////////////////////////////////////////////////////////////////

Text DctSecReplace()

//////////////////////////////////////////////////////////////////////////////
Text DctSecReplace(Text pstSec) // Seccion
//////////////////////////////////////////////////////////////////////////////
{
  ReplaceTable(pstSec, [[
    [["INCLUDE",             "Inclusiones"]],
    [["COMMON",              "comunes"]],
    [["APPLICATION",         "de aplicación"]],
    [["BLACKBOARD",          "Pizarra"]],
    [["STRUCTS",             "Estructuras de datos"]],
    [["CONTROLS",            "Variables de control"]],
    [["CONSTANTS",           "Constantes"]],
    [["SHORTNAMES",          "Funciones de nombre corto"]],
    [["FUNCTIONS",           "Funciones"]],
    [["MAKE",                "Proceso"]],
    [["TEST",                "Pruebas"]],
    [["END",                 "Finalización"]]
  ]], 1)
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna los nombres en castellano de los diferentes tipos de secciones.",
DctSecReplace);
//////////////////////////////////////////////////////////////////////////////

Text DctFileLanguage()

//////////////////////////////////////////////////////////////////////////////
Text DctFileLanguage(Text filNam, // Nombre del fichero de entrada
                     Real ctrLar) // Si true largo, si false corto=extension
//////////////////////////////////////////////////////////////////////////////
{
  Text filExt = ToLower(GetFileExtension(filPth));
  If(ctrLar,
    Case(
      filExt == "tol", "Time oriented language",
      filExt == "bst", "Datos con estructura de Tol",
      filExt == "bdt", "Datos de series temporales",

      filExt == "bat", "Command bat",
      filExt == "css", "Cascade style sheet",
      filExt == "gpl", "Gnuplot",
      filExt == "js",  "Javascript",
      filExt == "sql", "Standard query language",
      filExt == "xml", "Extensible markup language",
      filExt == "htm", "HyperText markup language",
      filExt == "html","HyperText markup language",
      filExt == "age", "Agenda de posts",

      filExt == "gif",  "Graphic file Gif format",
      filExt == "jpg",  "Graphic file Jpe format",
      filExt == "png",  "Graphic file Png format",

      TRUE,            "Ascii code"),
    Case(
      filExt == "bat", "Cmd",
      filExt == "htm", "Html",
      TRUE,            FirstToUpper(filExt)))
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna el nombre del lenguaje de programación en formato corto o largo
dependiendo de ctrLar.",
DctFileLanguage);
//////////////////////////////////////////////////////////////////////////////

Set DctDeclare()

//////////////////////////////////////////////////////////////////////////////
Set DctDeclare(Text prgNam, // Programa
               Text filNam, // Fichero
               Text decCat, // Categoria: variable, funcion
               Text decTyp, // Tipo
               Text decNam, // Nombre
               Text decArg, // Argumentos si procede
               Text ascDes) // Descripcion en ascii, puede contener <, > o &
//////////////////////////////////////////////////////////////////////////////
{
  Text opeClo = If(decCat=="variable", "", "()");
  Text uppCat = FirstToUpper(decCat);
  Text simTol = decTyp+" "+decNam+opeClo; // Simula una declaracion Tol
  Text decLnk = DctLink(prgNam, filNam, simTol, "A"); // A href y url
  Text decTit = DctLink(prgNam, filNam, simTol, "T"); // A href url y title

  Text decDes = Compact(HtmAsc2Xml(ascDes));

  SetOfText(
    simTol,                                // Tipo var o fun()
    uppCat+"; "+decTyp+"; "+decNam,        // Clases
    decTyp+" "+decNam+decArg+" "+decDes,   // Descripciones
    "  <li><code>"+decTyp+" "+decLnk+      // Para indices
                   decNam+"</a>"+
                   decArg+"</code><br />"+
                   decDes+"</li>\n",
    decTit+decNam+"</a>")                  // Para inyectar en otro codigo
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Para una declaracion Tol retorna un set de 5 elementos formado por:
a) clases: Variable/Funcion, tipo Tol y nombre
b) declaracion: tipo nombre(argumentos)
c) descripcion: tipo nombre(argumentos) y proposito
d) codigo para un li con tipo nombre(argumentos) y proposito y
e) a href link para que el codigo de otras funciones le enlacen.",
DctDeclare);
//////////////////////////////////////////////////////////////////////////////

Real DctAppendPost()

//////////////////////////////////////////////////////////////////////////////
Real DctAppendPost(Text outFil, // Semilla
                   Text prgNam, // Nombre del programa
                   Text filNam, // Nombre del fichero
                   Text pstSec, // Seccion, para local, global y header
                   Text addCla, // Clase adicionales
                   Text pstSta, // Estado
                   Text pstAut, // Autor
                   Text pstDes, // Descripcion
                   Text pstHtm) // Html del post
//////////////////////////////////////////////////////////////////////////////
{
  Text putSep = If(TextBeginWith(addCla, "Cabecera"), "", DctPstSep);

  Text pstTxt = DctPstReplace(prgNam, filNam, pstSec, addCla, pstSta,
                              pstAut, pstDes, pstHtm); // Htm

  Text AppendFile(outFil, putSep+pstTxt);
  TRUE
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Añade un post con todos sus campos al fichero de agenda llamado outFil.
La cabecera no lleva separador, el resto es separador mas contenido.",
DctAppendPost);
//////////////////////////////////////////////////////////////////////////////

Real DctWriteHeader()

//////////////////////////////////////////////////////////////////////////////
Real DctWriteHeader(Text prgNam, // Nombre del progama
                    Text filNam, // Fichero
                    Set  dctCab, // Atributos de la cabecera del fichero
                    Text agePth, // Agenda
                    Text levCla) // Clase inicial de nivel
//////////////////////////////////////////////////////////////////////////////
{
  Text WriteFile(agePth, ""); // El header inicializa el fichero

  Text cabCla = "Cabecera; " + TxtCat(levCla, "; ", dctCab[3]);

  Text cabIni = HtmAsc2Xml(dctCab[5]);
  Text cabDes = Compact(Replace(cabIni, DctBr2, " "));
  Text cabHtm = "<p>\n"+Replace(cabIni, DctBr2, "<br /><br />")+"\n</p>\n";
  
  DctAppendPost(agePth,     // Fichero de salida
                prgNam,     // Nombre del programa
                filNam,     // Nombre del fichero
                filNam,     // Seccion, para local, global y header
                cabCla,     // Mas las clases de la cabecera del fichero
                "D",        // Estado
                dctCab[2],  // Autor
                cabDes,     // Descripcion
                cabHtm)     // Html del post
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Inicia la agenda escribiendo el post de la cabecera de un programa.",
DctWriteHeader);
//////////////////////////////////////////////////////////////////////////////

Real DctWriteTree()

//////////////////////////////////////////////////////////////////////////////
Real DctWriteTree(Text prgNam, // Nombre del progama
                  Text filNam, // Fichero
                  Set  dctCab, // Atributos de la cabecera del fichero
                  Text agePth, // Agenda
                  Set  inpTre, // Arbol de entrada
                  Text levCla) // Clase inicial de nivel
//////////////////////////////////////////////////////////////////////////////
{
  Text treCla = TxtCat("Árbol", "; ", TxtCat(levCla, "; ", dctCab[3]));
  Text pstHtm = DTrHtml(inpTre, prgNam, 0, filNam); // Arbol de ficheros
  Text pstDes = "Árbol de directorios y ficheros del programa "+prgNam+", "+
                "al que pertenece el fichero de código fuente "+filNam+". "+
                dctCab[5];

  DctAppendPost(agePth,              // Fichero de salida
                prgNam,              // Nombre del programa
                filNam,              // Nombre del fichero
                "Árbol de ficheros", // Seccion, para local, global y header
                treCla,              // Mas las clases de la cabecera
                "C",                 // Estado
                dctCab[2],           // Autor
                pstDes,              // Descripcion
                pstHtm)              // Html del post
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Escribe el post del arbol de navegacion de un programa con el fichero en
curso activo.",
DctWriteTree);
//////////////////////////////////////////////////////////////////////////////

Real DctWriteDisplay()

//////////////////////////////////////////////////////////////////////////////
Real DctWriteDisplay(Text prgNam, // Nombre del progama
                     Text filNam, // Fichero
                     Set  dctCab, // Atributos de la cabecera del fichero
                     Text agePth) // Agenda
//////////////////////////////////////////////////////////////////////////////
{
  Text htmPth = Replace(agePth, ".age", ".htm");
  Text iniTag = "<body><div class="+Q("Bdy")+">";
  Text htmCod = FilBetween2Tag(htmPth, iniTag, "</div></body>");
  Text pstDes = "Presentación del fichero de código fuente "+filNam+" "+
                "perteneciente al programa "+prgNam+". "+
                dctCab[5];
  
  If(htmCod=="", FALSE,
     DctAppendPost(agePth,         // Fichero de salida
                   prgNam,         // Nombre del programa
                   filNam,         // Nombre del fichero
                   "Presentación", // Seccion, para local, global y header
                   dctCab[3],      // Mas las clases de la cabecera
                   "C",            // Estado
                   dctCab[2],      // Autor
                   pstDes,         // Descripcion
                   htmCod))        // Html del post
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Escribe el post de la presentación realizada a mano de un fichero filNam de
un programa prgNam.",
DctWriteDisplay);
//////////////////////////////////////////////////////////////////////////////

Real DctWriteIndex()

//////////////////////////////////////////////////////////////////////////////
Real DctWriteIndex(Text prgNam, // Nombre del progama
                   Text filNam, // Fichero
                   Set  dctSHi, // Codigo cortado y realzado
                   Text agePth, // Agenda
                   Text funDmp) // Fichero de volcado de funciones
//////////////////////////////////////////////////////////////////////////////
{
  Set  dctCab = dctSHi[1]; // Atributos de cabecera del fichero
  Text pstDes = "Índice de las variables y funciones declaradas en "+
                "el fichero de código fuente "+filNam+" "+
                "del programa "+prgNam+". "+dctCab[5];

  // Indice de variables y funciones
  Set  dctInd = For(2, Card(dctSHi), Text(Real dctPos)
  {
    Set  dctSec = dctSHi[dctPos];
    If(dctSec[1]=="END", "", // A partir del end no ha de haber nada
    {
      Text secCls = DctSecReplace(dctSec[1]); // Nombre de la seccion

      If(DctRawCode(dctSec), "", // No tiene declaraciones o son en bruto
      {
        Set  decLst = dctSec[2]; // Lista de declaraciones de la seccion
        Set  decCic = EvalSet(decLst, Text(Set tolSet) // Por declaracion
        {
          Text If(dctSec[1]!="FUNCTIONS", "",         // No es funcion larga
                  AppendFile(funDmp, tolSet[3]+"\n")); // Dump de la funcion

          Set  decSet = DctDeclare(prgNam, filNam, // Proyecto y fichero
                                   tolSet[1],      // Variable, funcion
                                   tolSet[2],      // Tipo, gramatica
                                   tolSet[3],      // Nombre
                                   tolSet[4],      // Argumentos si procede
                                   tolSet[5]);     // Descripcion de funcion
          decSet[4] // Es el li con enlace y resumen
        });
        "<p><b>"+secCls+"</b></p>\n<ul>\n"+SetSum(decCic)+"</ul>\n"
      })
    })
  });
  Text htmInd = SetSum(dctInd); // Une los textos de todas las secciones

  DctAppendPost(agePth,          // Fichero de salida
                prgNam,          // Nombre del programa
                filNam,          // Nombre del fichero
                "Declaraciones", // Seccion, para local, global y header
                dctCab[3],       // Mas las clases de la cabecera
                "C",             // Estado
                dctCab[2],       // Autor
                pstDes,          // Descripcion
                htmInd)          // Html del post
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Escribe el post del indice de declaraciones de variables y funciones de un
fichero filNam de un programa prgNam.
Es un indice con enlaces al resto de declaraciones, pero se le titula como
declaraciones pues no indexa otras secciones.",
DctWriteIndex);
//////////////////////////////////////////////////////////////////////////////

Real DctWriteCode()

//////////////////////////////////////////////////////////////////////////////
Real DctWriteCode(Text prgNam, // Nombre del progama
                  Text filNam, // Fichero
                  Set  dctSHi, // Codigo cortado y realzado
                  Text agePth, // Agenda
                  Set  lnkTab) // Tabla de declaraciones y sus enlaces
//////////////////////////////////////////////////////////////////////////////
{
  Set  dctCab = dctSHi[1]; // Atributos de cabecera del fichero

  // Escribir todas las secciones con todas sus declaraciones
  Set  dctCic = For(2, Card(dctSHi), Real(Real dctPos)
  {
    Set  dctSec = dctSHi[dctPos];
    Text secCls = DctSecReplace(dctSec[1]);         // Seccion en castellano
    Text secCla = FirstToUpper(ToLower(dctSec[1])); // Seccion en ingles
    Text pstDes = secCls+" ("+dctSec[1]+") del fichero de código fuente "+
                  filNam+" del programa "+prgNam+". "+
                  dctCab[5];

    Real notFmt = DctRawCode(dctSec); // Codigo bruto, sin formato
    Text secCod = If(!notFmt, "",     // El codigo se pone luego
                     HtmPutLinks(dctSec[2], lnkTab, "")); // Bruto+links

    DctAppendPost(agePth,     // Fichero de salida
                  prgNam,     // Nombre del programa
                  filNam,     // Nombre del fichero
                  secCls,     // Seccion, para local, global y header
                  secCla,     // Clase = seccion en formato original
                  "C",        // Estado
                  dctCab[2],  // Autor
                  pstDes,     // Descripcion
                  secCod);    // Solo si es codigo bruto

    If(notFmt, FALSE,         // Sin formato->sin ciclo
    {
      Set  decLst = dctSec[2]; // Lista de declaraciones de la seccion

      Set  decCic = EvalSet(decLst, Real(Set tolSet) // Para cada declaracion
      {
        Set decSet = DctDeclare(prgNam, filNam, // Proyecto y fichero
                                tolSet[1],      // Categoria: variable, funcion
                                tolSet[2],      // Tipo, gramatica
                                tolSet[3],      // Nombre
                                tolSet[4],      // Argumentos si procede
                                tolSet[5]);     // Descripcion de la funcion

        Text codImg = HtmPutCharts(tolSet[6]);  // Añade graficos online
        Text codLnk = HtmPutLinks (codImg, lnkTab, "");   // Poner links

        DctAppendPost(agePth,     // Fichero de salida
                      prgNam,     // Nombre del programa
                      filNam,     // Nombre del fichero
                      decSet[1],  // Type var o type fun()
                      decSet[2],  // Clases + nombre
                      "B",        // Estado
                      dctCab[2],  // Autor
                      dctCab[3],  // Descripcion tipo var/fun arg purpose
                      codLnk)     // Codigo realzado y con links
      }); 
      Card(decCic)
    })
  });
  Card(dctCic)
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Escribe todos los posts de secciones de codigo (constantes, funciones, etc.)
y todos los post de cada una de las estructuras, constantes, funciones, etc.
de un fichero filNam de un programa prgNam.",
DctWriteCode);
//////////////////////////////////////////////////////////////////////////////

Real DctWriteSource()

//////////////////////////////////////////////////////////////////////////////
Real DctWriteSource(Text prgNam, // Nombre del progama
                    Text filNam, // Fichero
                    Set  dctCab, // Atributos de la cabecera del fichero
                    Text agePth, // Agenda
                    Text codTxt, // Codigo fuente del fichero, total o parcial
                    Set  lnkTab, // Tabla de declaraciones y sus enlaces
                    Text codDmp) // Fichero de volcado de codigo
//////////////////////////////////////////////////////////////////////////////
{
  Text AppendFile(codDmp,"\n"+DctUndLinAsc+"\n"+filNam+"\n"+codTxt); // Dump

  If(Compact(codTxt)=="", FALSE, // No hay codigo que escribir
  {
    Text lanLar = DctFileLanguage(filNam, TRUE);  // Nombre largo del lenguaje
    Text lanTin = DctFileLanguage(filNam, FALSE); // Nombre corto del lenguaje
    Text lanCla = TxtCat("Fuente",  "; ", lanTin);
    Text allCla = TxtCat(dctCab[3], "; ", lanCla);
    
    Text cabNam = dctCab[1]; // Nombre del fichero segun la cabecera
    Text lanTst = If(filNam==cabNam, lanLar, "¿"+filNam+" o "+cabNam+"?");

    Text pstDes = "Código fuente en lenguaje "+lanLar+" ("+lanTin+") "+
                  "del fichero "+filNam+" del programa "+prgNam+". ";

    Text notMai = Replace(codTxt, " asalmeronasolver.com", ""); // Eliminable

    Text codSHi = SHiPreCode  (filNam, notMai);     // Realza el texto
    Text codImg = HtmPutCharts(codSHi);             // Añade graficos online
    Text codLnk = HtmPutLinks (codImg, lnkTab, ""); // Poner links

    DctAppendPost(agePth,           // Fichero de salida
                  prgNam,           // Nombre del programa
                  filNam,           // Nombre del fichero
                  lanTst,           // Seccion, para local, global y header
                  allCla,           // Mas las clases de la cabecera
                  "C",              // Estado
                  dctCab[2],        // Autor
                  pstDes,           // Descripcion
                  codLnk)           // Html del post codigo realzado con links
  })
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Escribe el post de la presentación realizada a mano de un fichero filNam de
un programa prgNam.",
DctWriteSource);
//////////////////////////////////////////////////////////////////////////////

Real DctMake()

//////////////////////////////////////////////////////////////////////////////
Real DctMake(Text dctPre, // Directorio contenedor del directorio del programa
             Set  dctTre) // Arbol de ficheros a documentar
//////////////////////////////////////////////////////////////////////////////
{
  Text WriteLn(DTrText(dctTre, "", 0)); // Test visual previo

  Text prgNam = Anything A(dctTre[1],                   "Program.........");
  Text prgPth = Anything A(TxtCat(dctPre, "/", prgNam), "Input directory.");
  Text outPth = Anything A(TxtCat(prgPth, "/", "dct"),  "Output directory");

  // Ficheros de volcado completo
  Text funDmp = Anything A(outPth+"/_dmpfun.txt",       "Func dump file..");
  Text codDmp = Anything A(outPth+"/_dmpcod.txt",       "Code dump file..");
  Text WriteFile(funDmp, "");
  Text WriteFile(codDmp, "");

  Set  filTab = DtrFileExc(DtrFileSet(dctTre, dctPre)); // Tabla de ficheros

  Set  lnkTab = DctLinkAllDeclaration(filTab); // Tabla (declaracion, enlace)

  Set  filCic = EvalSet(filTab, Real(Set filSet)
  {
    Text filNam = Anything A(filSet[3], "File to agenda..");
    Text filPth = filSet[2];
    Text filPur = FirstToUpper(filSet[4]); // Descripcion por defecto

    Text agePth = outPth+"/"+FilDelExtLow(filNam)+".age";

    Text tagIni = filSet[5]; // Tag inicial si lo hubiera
    Text tagEnd = filSet[6]; // Tag inicial si lo hubiera

    Text filCod = FilBetween2Tag(filPth,  tagIni, tagEnd);

    If(TextEndAt(filNam, ".tol"), // Ficheros Tol
    {
      Text levCla = If(filSet[1]=="Rot", "Raíz", "Hoja");
      Set  dctSHi = DctTolSplit(filCod); // Corta y realza el codigo
      Set  dctCab = dctSHi[1];           // Atributos de cabecera del fichero

      DctWriteHeader (prgNam, filNam, dctCab, agePth, levCla);

      If(filSet[1]!="Rot", FALSE, // Si no es raiz el arbol al final
         DctWriteTree   (prgNam, filNam, dctCab, agePth, dctTre, levCla));

      DctWriteDisplay(prgNam, filNam, dctCab, agePth);
      DctWriteIndex  (prgNam, filNam, dctSHi, agePth, funDmp);
      DctWriteCode   (prgNam, filNam, dctSHi, agePth, lnkTab);
      DctWriteSource (prgNam, filNam, dctCab, agePth, filCod, lnkTab, codDmp);

      If(filSet[1]=="Rot", FALSE,
         DctWriteTree   (prgNam, filNam, dctCab, agePth, dctTre, levCla))
    },
    If(TextEndAt(filNam, ".pdf"), FALSE, // Archivos Pdf, nada que hacer
    {
      // Puede haber codigo Tol en ficheros htm, no html
      Set  lnkChk = If(TextEndAt(filNam, ".htm"), lnkTab, Empty);
      // Los ficheros no Tol pueden no tener buenas cabeceras
      Set  dctCab = DctGetHeaderRobust(filCod, filNam, filPur); // Atributos

      DctWriteHeader (prgNam, filNam, dctCab, agePth, "Hoja");
      DctWriteDisplay(prgNam, filNam, dctCab, agePth);
      DctWriteSource (prgNam, filNam, dctCab, agePth, filCod, lnkChk, codDmp);
      DctWriteTree   (prgNam, filNam, dctCab, agePth, dctTre, "Hoja")
    }))
  });

  Set DctOcurrences(funDmp, codDmp, 2);

  Card(filCic)
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Proceso principal de documentacion de todo el arbol de fichero de entrada.",
DctMake);
//////////////////////////////////////////////////////////////////////////////

Set DctOcurrences()

//////////////////////////////////////////////////////////////////////////////
Set DctOcurrences(Text funDmp, // Fichero de volcado de funciones
                  Text codDmp, // Fichero de volcado de codigo
                  Real ctrOcc) // Control de ocurrencias
//////////////////////////////////////////////////////////////////////////////
{
  Set  funSet = Select(Tokenizer(ReadFile(funDmp),"\n"), Real(Text funNam)
                { Compact(funNam)!="" });
  Text codAll = ReadFile(codDmp);
  Set  funTab = EvalSet(funSet, Set(Text funNam)
                { [[funNam, TextOccurrences(codAll, funNam)]] });
  Set  funFew = Select(funTab, Real(Set funOcc) { LT(funOcc[2], ctrOcc) });
  If(!Card(funFew), Empty,
  {
    Text WriteLn("\nOcurrences:");
    EvalSet(funFew, Set(Set funOcc)
    {
      Text WriteLn("->"+funOcc[1]+": "+F(funOcc[2]));
      funOcc
    })
  })
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna una tabla de funciones y numero de occurencias para aquellas
funciones que no superan ctrOcc, como efecto latelar las visualiza.",
DctOcurrences);
//////////////////////////////////////////////////////////////////////////////

Set DctLinkFileDeclaration()

//////////////////////////////////////////////////////////////////////////////
Set DctLinkFileDeclaration(Text prgNam, // Nombre del progama
                           Text filNam, // Fichero
                           Set  dctSHi) // Codigo cortado y realzado
//////////////////////////////////////////////////////////////////////////////
{
  // Para todas las variables y funciones
  Set  lblCic = For(2, Card(dctSHi), Set(Real dctPos)
  {
    Set  dctSec = dctSHi[dctPos];
    If(DctRawCode(dctSec), Empty, // No tiene declaraciones o son en bruto
    {
      Set  decLst = dctSec[2]; // Lista de declaraciones de la seccion
      Set  decCic = EvalSet(decLst, Set(Set tolSet) // Por declaracion
      {
        Set  decSet = DctDeclare(prgNam, filNam, // Proyecto y fichero
                                 tolSet[1],      // Variable, funcion
                                 tolSet[2],      // Tipo, gramatica
                                 tolSet[3],      // Nombre
                                 tolSet[4],      // Argumentos si procede
                                 tolSet[5]);     // Descripcion de funcion
        Text decNam = tolSet[3]; // Nombre de la funcion o variable
        Text decLnk = decSet[5]; // a href a la funcion o variable
        SetOfText(decNam,decLnk) // Par (declaracion, enlace)
      })
    })
  });
  BinGroup("<<", lblCic)
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna una tabla de pares nombre de variable o funcion y su enlace de un
fichero Tol de un programa.",
DctLinkFileDeclaration);
//////////////////////////////////////////////////////////////////////////////

Set DctLinkAllDeclaration()

//////////////////////////////////////////////////////////////////////////////
Set DctLinkAllDeclaration(Set  filTab) // Tabla de ficheros, selecciona Tol
//////////////////////////////////////////////////////////////////////////////
{
  Set  lnkCic = EvalSet(filTab, Set(Set filSet)
  {
    Text filNam = Anything A(filSet[3], "File get links..");
    If(!TextEndAt(filNam, ".tol"), Empty, // No es fichero Tol
    {
      Text tagIni = filSet[5]; // Tag inicial si lo hubiera
      Text tagEnd = filSet[6]; // Tag inicial si lo hubiera
      Text filPth = filSet[2]; // Ruta del fichero
      Text filCod = FilBetween2Tag(filPth,  tagIni, tagEnd); // Lee codigo
      Set  dctSHi = DctTolSplit(filCod); // Corta y realza el codigo
      DctLinkFileDeclaration(prgNam, filNam, dctSHi) // Tabla (declara,enlace)
    })
  });
  BinGroup("<<", lnkCic)
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna una tabla de pares nombre de variable o funcion y su enlace de todos
los ficheros Tol de un programa.",
DctLinkAllDeclaration);
//////////////////////////////////////////////////////////////////////////////

Time oriented language

//////////////////////////////////////////////////////////////////////////////
// FILE    : dct.tol
// AUTHOR  : http://www.asolver.com
// PURPOSE : Funciones de docuentacion de Tol a una agenda de post.
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
// CONSTANTS
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
Text DctTdy = FormatDate(Today, "%c%Y/%m/%d");
//////////////////////////////////////////////////////////////////////////////
PutDescription("Fecha del dia que se genera la documentacion.", DctTdy);
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
Real DctDesLen = 350;
//////////////////////////////////////////////////////////////////////////////
PutDescription("Numero maximo de caracteres de una descripcion.", DctDesLen);
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
Text DctUndLinHtm = Repeat("&#95;",78);
//////////////////////////////////////////////////////////////////////////////
PutDescription("Separador de underscores en Html.", DctUndLinHtm);
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
Text DctUndLinAsc = Repeat("_",78);
//////////////////////////////////////////////////////////////////////////////
PutDescription("Separador de underscores en Ascii.", DctUndLinAsc);
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
Text DctTolSepBas = "\n"+Repeat("/",78)+"\n";
//////////////////////////////////////////////////////////////////////////////
PutDescription("Separador basico de codigo Tol.", DctTolSepBas);
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
Text DctTolSepLow = "\n"+DctTolSepBas;
//////////////////////////////////////////////////////////////////////////////
PutDescription("Separador de codigo Tol de bajo nivel.", DctTolSepLow);
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
Text DctTolSepTop = "\n"+DctTolSepLow+"// ";
//////////////////////////////////////////////////////////////////////////////
PutDescription("Separador de codigo Tol de alto nivel.", DctTolSepTop);
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
Text DctBr2 = Char(12); // Form feed
//////////////////////////////////////////////////////////////////////////////
PutDescription("Para forzar separaciones en comentarios.", DctTolSepTop);
//////////////////////////////////////////////////////////////////////////////



//////////////////////////////////////////////////////////////////////////////
Text DctPstSee = "
<Pst.Cla> _CLA_
<Pst.Sta> C
<Pst.Dte> _DTE_
<Pst.Aut> _AUT_
<Pst.Pth> web/dct_writer/dct_tol.html
<Pst.Lnk> ../dct_writer/dct_tol.html#Dct_Writer_Time_oriented_language
<Pst.Glo> _GLO_
<Pst.Loc> Time oriented language
<Pst.Des> _DES_
<Pst.Htm>
_HTM_
<Pst.End>
";
//////////////////////////////////////////////////////////////////////////////
PutDescription("Semilla de un post.", DctTolSepTop);
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
Text DctPstSep = Repeat("_",78)+"\n";
//////////////////////////////////////////////////////////////////////////////
PutDescription("Separador entre posts.", DctPstSep);
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
// FUNCTIONS
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
Set DctGetInterface(Text tolCod)
//////////////////////////////////////////////////////////////////////////////
{
  Text clsQuo(Text desTxt) { Replace(desTxt, Char(34), "") };
  
  Set  trePar = Parse(tolCod)[3]; // Acesso al arbol del parse
  
  Case(
    trePar[1][1] == "=";   // Si es variable
    {
      Text varCla = "variable";
      Text varTyp = trePar[1][3][1][1];         // Tipo
      Text varNam = trePar[1][3][1][3][1][1];   // Nombre
      Text varDeQ = trePar[2][3][1][1];         // Descripcion con quote
      Text varDes = clsQuo(varDeQ);             // Descripcion sin quote
      Text argTxt = "";                         // Argumentos no hay

      SetOfText(varCla, varTyp, varNam, argTxt, varDes)
    },
    trePar[1][1] == "#F#"; // Si es funcion
    {
      Text funCla = "function";
      Text funTyp = trePar[1][3][1][1];         // Tipo
      Text funNam = trePar[1][3][1][3][1][1];   // Nombre
      Text funDeQ = trePar[2][3][1][1];         // Descripcion con quote
      Text funDes = clsQuo(funDeQ);             // Descripcion sin quote

      Set  argSet = trePar[1][3][1][3][1][3];   // Conjunto de argumentos
      Real argNum = Card(argSet);               // Numero de argumentos

      Set  argCic = For(1, argNum, Text(Real argPos)
      {
        Set  argInf = argSet[argPos]; // Informacion del argumento
        Text argTyp = argInf[1];
        Text argNam = argInf[3][1][1];

        If(EQ(argPos, 1), "", ", ")+ argTyp+" "+argNam
      });
      Text argTxt = "(" + SetSum(argCic) + ")";

      SetOfText(funCla, funTyp, funNam, argTxt, funDes)
    },
    TRUE, Empty) // Ni variable ni funcion
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna, para una variable o una funcion, un conjunto de textos formado por
[clase function|variable, tipo de retorno, nombre, argumentos, descripcion],
en el caso de variables los argumentos son la tira vacia.
En caso de error retorna Empty.",
DctGetInterface);
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
Set DctGetHeader(Text codHea) // Trozo de codigo o todo para extraer atributos
//////////////////////////////////////////////////////////////////////////////
{
  Text repLar = ReplaceTable(codHea, [[ // Reemplazar los largos
    [["-- ///", "//////"]],                                  // Sql
    [[""/*////", "//////"]], [[ "////*/", "//////"]],         // Css
    [["/*-///", "//////"]], [[ "///-*/", "//////"]],         // Css
    [["# ////", "//////"]], [[ "#/////", "//////"]],         // Glp
    [[":: ///", "//////"]], [[ "::////", "//////"]],         // Bat
    [["<!-- /", "//////"]], [[ "// -->", "//////"]] ]], 1);  // Htm

  Text repSor = ReplaceTable(repLar, [[ // Reemplazar los cortos
    [["--",  "//"]],  // Sql
    [["# ",  "//"]],  // Glp
    [["::",  "//"]],  // Bat
    [[" : ", ": "]] ]], 4); // Como maximo 4 blancos antes de :
    
  Text filHea = repSor+"\n"; // Asegurarse el ultimo salto de linea
  
  Text filNam = TxtBetween2Tag(filHea, "FILE: ",    "\n", TRUE);
  Text autIde = TxtBetween2Tag(filHea, "AUTHOR: ",  "\n", TRUE);
  Text claLst = TxtBetween2Tag(filHea, "CLASS: ",   "\n", TRUE);
  Text verLst = TxtBetween2Tag(filHea, "VERSION: ", "\n", TRUE);
  Text purTxt = TxtBetween2Tag(filHea, "PURPOSE: ", DctTolSepBas, FALSE);
  Text purCls = ReplaceTable(purTxt, [[ [["\n// ",  "\n"]],
                                        [["_\n",    DctBr2+"\n"]] ]]);
  Text remTxt = TxtBetween2Tag(filHea, "COMMENT: ", DctTolSepBas, FALSE);
  Text remCls = Replace(Replace(remTxt, "\n// ", "\n"), "\n//", "\n");

  [[ filNam, autIde, claLst, verLst, purCls, remCls ]]
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna un conjunto con los 4 atributos de la cabecera de un fichero que
son el nombre del fichero, el autor, sus clases y su proposito.",
DctGetHeader);
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
Set DctGetHeaderRobust(Text codHea, // Trozo de codigo para extraer atributos
                       Text filNam, // Nombre del fichero si no se encuentra
                       Text filPur) // Descripcion si no se encuentra
//////////////////////////////////////////////////////////////////////////////
{
Text WriteLn(filPur);
  Real posFil = TextFind(codHea, " FILE",    0);      // Nombre del fichero
  Real posDts = TextFind(codHea, ": ",       posFil); // : tras el nombre
  Real posPur = TextFind(codHea, " PURPOSE", posDts); // Proposito tras :

  Set  filAtr = If(And(posFil, posDts, posPur, LE(posPur, 500)),
                DctGetHeader(codHea),   // Parece una cabecera
                [["","","","","",""]]); // No parece una cabecera

  Text filAut = "http://www.asolver.com";
  Text chkNam = If(filAtr[1]=="", filNam, filAtr[1]); 
  Text chkAut = If(filAtr[2]=="", filAut, filAtr[2]);
  Text chkCla = filAtr[3];
  Text chkVer = filAtr[4];
  Text chkPur = If(filAtr[5]=="", filPur, filAtr[5]); 
  Text chkRem = filAtr[6];

  [[ chkNam, chkAut, chkCla, chkVer, chkPur, chkRem ]]
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna un conjunto con los 4 atributos de la cabecera de un fichero que
son el nombre del fichero, el autor, sus clases y su proposito.",
DctGetHeaderRobust);
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
Set DctTolSplit(Text codInp) // Codigo Tol
//////////////////////////////////////////////////////////////////////////////
{
  Set  setTop = TxtTokenizer(codInp, DctTolSepTop); // Rotura de alto nivel
  
  Set  treTop = DctGetHeader(setTop[1]); // Cabecera del fichero

  Set  treSec = For(2, Card(setTop), Set(Real posSec)
  {
    Text codSec = setTop[posSec]+"\n"; // Ultima linea con su salto de linea
    Real lenSec = TextLength(codSec);
    Real heaEnd = TextFind(codSec, DctTolSepBas);
    Text heaSec = Compact(Sub(codSec, 1, heaEnd-1));
    Text decSec = Sub(codSec, heaEnd+TextLength(DctTolSepBas), lenSec);
    Set  decSet = TxtTokenizer("\n\n"+decSec, DctTolSepLow);

    If(EQ(Card(decSet),1), [[heaSec, SHiCompact(SHiTolPre(decSec))]], // Bruto
    { // Codigo correctamente delimitado
      Set  htmSet = For(2, Card(decSet), Set(Real posCod)
      {
        Text decCod = DctTolSepLow+decSet[posCod];
        Set  decInf = DctGetInterface(decCod); // 5 elementos

        decInf << SetOfText(SHiCompact(SHiTolPre(decCod))) // 6 elementos
      });
      [[heaSec, htmSet]]
    })
  });

  Set  treAll = [[ treTop ]] << treSec;

  treAll
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna un conjunto de secciones (FILE, CONSTANTS, FUNCTIONS, etc.) resultado
de romper el codigo Tol que recibe como parametro por secciones.
Cada seccion esta formada por un conjunto con su nombre y su conjunto de
declaraciones, salvo:
- la primera que contiene la información general de la cabecera y
- las secciones de codigo en bruto que retorna un conjunto formado por el
  texto nombre de la foncion y un texto (no un conjunto) que es el codigo
  en bruto formateado.",
DctTolSplit);
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
Real DctRawCode(Set dctSec) // Seccion de declaracion
//////////////////////////////////////////////////////////////////////////////
{ If(EQ(Card(dctSec), 2), Grammar(dctSec[2])!="Set", TRUE) };
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna cierto si el segundo componente no existe o si existe no es un 
conjunto de declaraciones de codigo. Lo natural en caso de codigo bruto es
que exista pero sea un texto con dicho codigo en bruto.",
DctRawCode);
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
Text DctLink(Text prgNam, // Nombre del programa
             Text filNam, // Nombre del fichero
             Text pstSec, // Seccion
             Text ctrRet) // Si F->fichero, L->link, A->a href y T A+title
//////////////////////////////////////////////////////////////////////////////
{
  Text filChk = If(filNam=="", "index", filNam); // No deberia ser vacio
  Text filExt = GetFileExtension(filChk);        // Extension
  Text filUrl =Case(
    filExt<:[["pdf","html"]],
      FilDelExtLow(prgNam)+"/"+filChk, // Pdf, Html no se cambian
    filExt=="htm",
      FilDelExtLow(prgNam)+"/"+filChk+"l",  // Poner la l de html
    TRUE,
      FilDelExtLow(prgNam +"/"+filChk)+".html");   // En general

  If(ctrRet=="F", "web/"+filUrl,
  {
    Text secUrl = TxtCat("../"+filUrl, "#", Htm2Ide(prgNam, pstSec, FALSE));
    Text secTit = pstSec+" en "+prgNam;
    Case(
      ctrRet=="L", secUrl,
      ctrRet=="A", "<a href="+Q(secUrl)+">",
      ctrRet=="T", "<a href="+Q(secUrl)+" title="+Q(secTit)+">",
      TRUE,        secUrl)      
  })
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna:
- si ctrRet=F el fichero de salida Html, salvo los Pdf que son Pdf,
- si ctrRet=L el enlace global al programa, fichero y seccion y
- si ctrRet=A el tag a href al enlace global.
Si no hay fichero filNam asume la pagina principal index, lo que no tendria
que suceder.
Si no hay seccion no añade el #seccion.",
DctLink);
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
Text DctPstReplace(Text prgNam, // Nombre del programa
                   Text filNam, // Nombre del fichero
                   Text pstSec, // Seccion, para local, global y header
                   Text addCla, // Clase adicionales
                   Text pstSta, // Estado
                   Text pstAut, // Autor
                   Text pstDes, // Descripcion
                   Text pstHtm) // Html del post
//////////////////////////////////////////////////////////////////////////////
{
  Text pstPth = DctLink(prgNam, filNam, pstSec, "F"); // Fichero de salida
  Text pstLnk = DctLink(prgNam, filNam, pstSec, "L"); // Link a url
  
  Text pstCat = If(pstSec=="Presentación", "Escrito", "Código");
  Text topCla = pstCat+"; " + prgNam + "; " +  // Todas existen
                If(filNam==pstSec, filNam, filNam+"; "+pstSec) + "; " +
                DctFileLanguage(filNam,FALSE); // Lenguaje de programacion
  Text pstCla = TxtCat(topCla, "; ", addCla);
  
  Text lblGlo = pstSec+" de "+prgNam;
  Text wraDes = TxtLineWrap(pstDes, DctDesLen, TRUE)[1];
  Text nowFmt = DctTdy+" ["+FormatReal(Time, "%9.4lf")+"]"; // [9999.9999]

  // Eliminar los propios autoseparadores que puede contener pstHtm
  Text clsHtm = Replace(pstHtm, DctUndLinAsc, DctUndLinHtm);
  
  ReplaceTable(DctPstSee, [[ // Siempre se usa la misma semilla
    [["_CLA_",  pstCla]],
    [["C",  pstSta]],
    [["_DTE_",  nowFmt]], // Fecha DctTdy
    [["_AUT_",  pstAut]],
    [["web/dct_writer/dct_tol.html",  pstPth]], // Ruta del fichero Html de salida
    [["../dct_writer/dct_tol.html#Dct_Writer_Time_oriented_language",  pstLnk]], // Enlace global
    [["_GLO_",  lblGlo]], // Titulo ventana, enlaces y headers globales
    [["Time oriented language",  pstSec]], // Etiqueta a names, enlaces y header local
    [["_DES_",  wraDes]], // Descripcion ajustada a tamaño
    [["_HTM_",  clsHtm]]  // Sin lineas de undersecore
  ]], 1) // 1 vuelta solo pues Htm puede contener etiquetas _XXX_ parecidas
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna por reemplazamiento un post con todos sus campos.",
DctPstReplace);
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
Text DctSecReplace(Text pstSec) // Seccion
//////////////////////////////////////////////////////////////////////////////
{
  ReplaceTable(pstSec, [[
    [["INCLUDE",             "Inclusiones"]],
    [["COMMON",              "comunes"]],
    [["APPLICATION",         "de aplicación"]],
    [["BLACKBOARD",          "Pizarra"]],
    [["STRUCTS",             "Estructuras de datos"]],
    [["CONTROLS",            "Variables de control"]],
    [["CONSTANTS",           "Constantes"]],
    [["SHORTNAMES",          "Funciones de nombre corto"]],
    [["FUNCTIONS",           "Funciones"]],
    [["MAKE",                "Proceso"]],
    [["TEST",                "Pruebas"]],
    [["END",                 "Finalización"]]
  ]], 1)
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna los nombres en castellano de los diferentes tipos de secciones.",
DctSecReplace);
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
Text DctFileLanguage(Text filNam, // Nombre del fichero de entrada
                     Real ctrLar) // Si true largo, si false corto=extension
//////////////////////////////////////////////////////////////////////////////
{
  Text filExt = ToLower(GetFileExtension(filPth));
  If(ctrLar,
    Case(
      filExt == "tol", "Time oriented language",
      filExt == "bst", "Datos con estructura de Tol",
      filExt == "bdt", "Datos de series temporales",

      filExt == "bat", "Command bat",
      filExt == "css", "Cascade style sheet",
      filExt == "gpl", "Gnuplot",
      filExt == "js",  "Javascript",
      filExt == "sql", "Standard query language",
      filExt == "xml", "Extensible markup language",
      filExt == "htm", "HyperText markup language",
      filExt == "html","HyperText markup language",
      filExt == "age", "Agenda de posts",

      filExt == "gif",  "Graphic file Gif format",
      filExt == "jpg",  "Graphic file Jpe format",
      filExt == "png",  "Graphic file Png format",

      TRUE,            "Ascii code"),
    Case(
      filExt == "bat", "Cmd",
      filExt == "htm", "Html",
      TRUE,            FirstToUpper(filExt)))
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna el nombre del lenguaje de programación en formato corto o largo
dependiendo de ctrLar.",
DctFileLanguage);
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
Set DctDeclare(Text prgNam, // Programa
               Text filNam, // Fichero
               Text decCat, // Categoria: variable, funcion
               Text decTyp, // Tipo
               Text decNam, // Nombre
               Text decArg, // Argumentos si procede
               Text ascDes) // Descripcion en ascii, puede contener <, > o &
//////////////////////////////////////////////////////////////////////////////
{
  Text opeClo = If(decCat=="variable", "", "()");
  Text uppCat = FirstToUpper(decCat);
  Text simTol = decTyp+" "+decNam+opeClo; // Simula una declaracion Tol
  Text decLnk = DctLink(prgNam, filNam, simTol, "A"); // A href y url
  Text decTit = DctLink(prgNam, filNam, simTol, "T"); // A href url y title

  Text decDes = Compact(HtmAsc2Xml(ascDes));

  SetOfText(
    simTol,                                // Tipo var o fun()
    uppCat+"; "+decTyp+"; "+decNam,        // Clases
    decTyp+" "+decNam+decArg+" "+decDes,   // Descripciones
    "  <li><code>"+decTyp+" "+decLnk+      // Para indices
                   decNam+"</a>"+
                   decArg+"</code><br />"+
                   decDes+"</li>\n",
    decTit+decNam+"</a>")                  // Para inyectar en otro codigo
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Para una declaracion Tol retorna un set de 5 elementos formado por:
a) clases: Variable/Funcion, tipo Tol y nombre
b) declaracion: tipo nombre(argumentos)
c) descripcion: tipo nombre(argumentos) y proposito
d) codigo para un li con tipo nombre(argumentos) y proposito y
e) a href link para que el codigo de otras funciones le enlacen.",
DctDeclare);
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
Real DctAppendPost(Text outFil, // Semilla
                   Text prgNam, // Nombre del programa
                   Text filNam, // Nombre del fichero
                   Text pstSec, // Seccion, para local, global y header
                   Text addCla, // Clase adicionales
                   Text pstSta, // Estado
                   Text pstAut, // Autor
                   Text pstDes, // Descripcion
                   Text pstHtm) // Html del post
//////////////////////////////////////////////////////////////////////////////
{
  Text putSep = If(TextBeginWith(addCla, "Cabecera"), "", DctPstSep);

  Text pstTxt = DctPstReplace(prgNam, filNam, pstSec, addCla, pstSta,
                              pstAut, pstDes, pstHtm); // Htm

  Text AppendFile(outFil, putSep+pstTxt);
  TRUE
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Añade un post con todos sus campos al fichero de agenda llamado outFil.
La cabecera no lleva separador, el resto es separador mas contenido.",
DctAppendPost);
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
Real DctWriteHeader(Text prgNam, // Nombre del progama
                    Text filNam, // Fichero
                    Set  dctCab, // Atributos de la cabecera del fichero
                    Text agePth, // Agenda
                    Text levCla) // Clase inicial de nivel
//////////////////////////////////////////////////////////////////////////////
{
  Text WriteFile(agePth, ""); // El header inicializa el fichero

  Text cabCla = "Cabecera; " + TxtCat(levCla, "; ", dctCab[3]);

  Text cabIni = HtmAsc2Xml(dctCab[5]);
  Text cabDes = Compact(Replace(cabIni, DctBr2, " "));
  Text cabHtm = "<p>\n"+Replace(cabIni, DctBr2, "<br /><br />")+"\n</p>\n";
  
  DctAppendPost(agePth,     // Fichero de salida
                prgNam,     // Nombre del programa
                filNam,     // Nombre del fichero
                filNam,     // Seccion, para local, global y header
                cabCla,     // Mas las clases de la cabecera del fichero
                "D",        // Estado
                dctCab[2],  // Autor
                cabDes,     // Descripcion
                cabHtm)     // Html del post
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Inicia la agenda escribiendo el post de la cabecera de un programa.",
DctWriteHeader);
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
Real DctWriteTree(Text prgNam, // Nombre del progama
                  Text filNam, // Fichero
                  Set  dctCab, // Atributos de la cabecera del fichero
                  Text agePth, // Agenda
                  Set  inpTre, // Arbol de entrada
                  Text levCla) // Clase inicial de nivel
//////////////////////////////////////////////////////////////////////////////
{
  Text treCla = TxtCat("Árbol", "; ", TxtCat(levCla, "; ", dctCab[3]));
  Text pstHtm = DTrHtml(inpTre, prgNam, 0, filNam); // Arbol de ficheros
  Text pstDes = "Árbol de directorios y ficheros del programa "+prgNam+", "+
                "al que pertenece el fichero de código fuente "+filNam+". "+
                dctCab[5];

  DctAppendPost(agePth,              // Fichero de salida
                prgNam,              // Nombre del programa
                filNam,              // Nombre del fichero
                "Árbol de ficheros", // Seccion, para local, global y header
                treCla,              // Mas las clases de la cabecera
                "C",                 // Estado
                dctCab[2],           // Autor
                pstDes,              // Descripcion
                pstHtm)              // Html del post
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Escribe el post del arbol de navegacion de un programa con el fichero en
curso activo.",
DctWriteTree);
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
Real DctWriteDisplay(Text prgNam, // Nombre del progama
                     Text filNam, // Fichero
                     Set  dctCab, // Atributos de la cabecera del fichero
                     Text agePth) // Agenda
//////////////////////////////////////////////////////////////////////////////
{
  Text htmPth = Replace(agePth, ".age", ".htm");
  Text iniTag = "<body><div class="+Q("Bdy")+">";
  Text htmCod = FilBetween2Tag(htmPth, iniTag, "</div></body>");
  Text pstDes = "Presentación del fichero de código fuente "+filNam+" "+
                "perteneciente al programa "+prgNam+". "+
                dctCab[5];
  
  If(htmCod=="", FALSE,
     DctAppendPost(agePth,         // Fichero de salida
                   prgNam,         // Nombre del programa
                   filNam,         // Nombre del fichero
                   "Presentación", // Seccion, para local, global y header
                   dctCab[3],      // Mas las clases de la cabecera
                   "C",            // Estado
                   dctCab[2],      // Autor
                   pstDes,         // Descripcion
                   htmCod))        // Html del post
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Escribe el post de la presentación realizada a mano de un fichero filNam de
un programa prgNam.",
DctWriteDisplay);
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
Real DctWriteIndex(Text prgNam, // Nombre del progama
                   Text filNam, // Fichero
                   Set  dctSHi, // Codigo cortado y realzado
                   Text agePth, // Agenda
                   Text funDmp) // Fichero de volcado de funciones
//////////////////////////////////////////////////////////////////////////////
{
  Set  dctCab = dctSHi[1]; // Atributos de cabecera del fichero
  Text pstDes = "Índice de las variables y funciones declaradas en "+
                "el fichero de código fuente "+filNam+" "+
                "del programa "+prgNam+". "+dctCab[5];

  // Indice de variables y funciones
  Set  dctInd = For(2, Card(dctSHi), Text(Real dctPos)
  {
    Set  dctSec = dctSHi[dctPos];
    If(dctSec[1]=="END", "", // A partir del end no ha de haber nada
    {
      Text secCls = DctSecReplace(dctSec[1]); // Nombre de la seccion

      If(DctRawCode(dctSec), "", // No tiene declaraciones o son en bruto
      {
        Set  decLst = dctSec[2]; // Lista de declaraciones de la seccion
        Set  decCic = EvalSet(decLst, Text(Set tolSet) // Por declaracion
        {
          Text If(dctSec[1]!="FUNCTIONS", "",         // No es funcion larga
                  AppendFile(funDmp, tolSet[3]+"\n")); // Dump de la funcion

          Set  decSet = DctDeclare(prgNam, filNam, // Proyecto y fichero
                                   tolSet[1],      // Variable, funcion
                                   tolSet[2],      // Tipo, gramatica
                                   tolSet[3],      // Nombre
                                   tolSet[4],      // Argumentos si procede
                                   tolSet[5]);     // Descripcion de funcion
          decSet[4] // Es el li con enlace y resumen
        });
        "<p><b>"+secCls+"</b></p>\n<ul>\n"+SetSum(decCic)+"</ul>\n"
      })
    })
  });
  Text htmInd = SetSum(dctInd); // Une los textos de todas las secciones

  DctAppendPost(agePth,          // Fichero de salida
                prgNam,          // Nombre del programa
                filNam,          // Nombre del fichero
                "Declaraciones", // Seccion, para local, global y header
                dctCab[3],       // Mas las clases de la cabecera
                "C",             // Estado
                dctCab[2],       // Autor
                pstDes,          // Descripcion
                htmInd)          // Html del post
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Escribe el post del indice de declaraciones de variables y funciones de un
fichero filNam de un programa prgNam.
Es un indice con enlaces al resto de declaraciones, pero se le titula como
declaraciones pues no indexa otras secciones.",
DctWriteIndex);
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
Real DctWriteCode(Text prgNam, // Nombre del progama
                  Text filNam, // Fichero
                  Set  dctSHi, // Codigo cortado y realzado
                  Text agePth, // Agenda
                  Set  lnkTab) // Tabla de declaraciones y sus enlaces
//////////////////////////////////////////////////////////////////////////////
{
  Set  dctCab = dctSHi[1]; // Atributos de cabecera del fichero

  // Escribir todas las secciones con todas sus declaraciones
  Set  dctCic = For(2, Card(dctSHi), Real(Real dctPos)
  {
    Set  dctSec = dctSHi[dctPos];
    Text secCls = DctSecReplace(dctSec[1]);         // Seccion en castellano
    Text secCla = FirstToUpper(ToLower(dctSec[1])); // Seccion en ingles
    Text pstDes = secCls+" ("+dctSec[1]+") del fichero de código fuente "+
                  filNam+" del programa "+prgNam+". "+
                  dctCab[5];

    Real notFmt = DctRawCode(dctSec); // Codigo bruto, sin formato
    Text secCod = If(!notFmt, "",     // El codigo se pone luego
                     HtmPutLinks(dctSec[2], lnkTab, "")); // Bruto+links

    DctAppendPost(agePth,     // Fichero de salida
                  prgNam,     // Nombre del programa
                  filNam,     // Nombre del fichero
                  secCls,     // Seccion, para local, global y header
                  secCla,     // Clase = seccion en formato original
                  "C",        // Estado
                  dctCab[2],  // Autor
                  pstDes,     // Descripcion
                  secCod);    // Solo si es codigo bruto

    If(notFmt, FALSE,         // Sin formato->sin ciclo
    {
      Set  decLst = dctSec[2]; // Lista de declaraciones de la seccion

      Set  decCic = EvalSet(decLst, Real(Set tolSet) // Para cada declaracion
      {
        Set decSet = DctDeclare(prgNam, filNam, // Proyecto y fichero
                                tolSet[1],      // Categoria: variable, funcion
                                tolSet[2],      // Tipo, gramatica
                                tolSet[3],      // Nombre
                                tolSet[4],      // Argumentos si procede
                                tolSet[5]);     // Descripcion de la funcion

        Text codImg = HtmPutCharts(tolSet[6]);  // Añade graficos online
        Text codLnk = HtmPutLinks (codImg, lnkTab, "");   // Poner links

        DctAppendPost(agePth,     // Fichero de salida
                      prgNam,     // Nombre del programa
                      filNam,     // Nombre del fichero
                      decSet[1],  // Type var o type fun()
                      decSet[2],  // Clases + nombre
                      "B",        // Estado
                      dctCab[2],  // Autor
                      dctCab[3],  // Descripcion tipo var/fun arg purpose
                      codLnk)     // Codigo realzado y con links
      }); 
      Card(decCic)
    })
  });
  Card(dctCic)
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Escribe todos los posts de secciones de codigo (constantes, funciones, etc.)
y todos los post de cada una de las estructuras, constantes, funciones, etc.
de un fichero filNam de un programa prgNam.",
DctWriteCode);
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
Real DctWriteSource(Text prgNam, // Nombre del progama
                    Text filNam, // Fichero
                    Set  dctCab, // Atributos de la cabecera del fichero
                    Text agePth, // Agenda
                    Text codTxt, // Codigo fuente del fichero, total o parcial
                    Set  lnkTab, // Tabla de declaraciones y sus enlaces
                    Text codDmp) // Fichero de volcado de codigo
//////////////////////////////////////////////////////////////////////////////
{
  Text AppendFile(codDmp,"\n"+DctUndLinAsc+"\n"+filNam+"\n"+codTxt); // Dump

  If(Compact(codTxt)=="", FALSE, // No hay codigo que escribir
  {
    Text lanLar = DctFileLanguage(filNam, TRUE);  // Nombre largo del lenguaje
    Text lanTin = DctFileLanguage(filNam, FALSE); // Nombre corto del lenguaje
    Text lanCla = TxtCat("Fuente",  "; ", lanTin);
    Text allCla = TxtCat(dctCab[3], "; ", lanCla);
    
    Text cabNam = dctCab[1]; // Nombre del fichero segun la cabecera
    Text lanTst = If(filNam==cabNam, lanLar, "¿"+filNam+" o "+cabNam+"?");

    Text pstDes = "Código fuente en lenguaje "+lanLar+" ("+lanTin+") "+
                  "del fichero "+filNam+" del programa "+prgNam+". ";

    Text notMai = Replace(codTxt, "", ""); // Eliminable

    Text codSHi = SHiPreCode  (filNam, notMai);     // Realza el texto
    Text codImg = HtmPutCharts(codSHi);             // Añade graficos online
    Text codLnk = HtmPutLinks (codImg, lnkTab, ""); // Poner links

    DctAppendPost(agePth,           // Fichero de salida
                  prgNam,           // Nombre del programa
                  filNam,           // Nombre del fichero
                  lanTst,           // Seccion, para local, global y header
                  allCla,           // Mas las clases de la cabecera
                  "C",              // Estado
                  dctCab[2],        // Autor
                  pstDes,           // Descripcion
                  codLnk)           // Html del post codigo realzado con links
  })
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Escribe el post de la presentación realizada a mano de un fichero filNam de
un programa prgNam.",
DctWriteSource);
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
Real DctMake(Text dctPre, // Directorio contenedor del directorio del programa
             Set  dctTre) // Arbol de ficheros a documentar
//////////////////////////////////////////////////////////////////////////////
{
  Text WriteLn(DTrText(dctTre, "", 0)); // Test visual previo

  Text prgNam = Anything A(dctTre[1],                   "Program.........");
  Text prgPth = Anything A(TxtCat(dctPre, "/", prgNam), "Input directory.");
  Text outPth = Anything A(TxtCat(prgPth, "/", "dct"),  "Output directory");

  // Ficheros de volcado completo
  Text funDmp = Anything A(outPth+"/_dmpfun.txt",       "Func dump file..");
  Text codDmp = Anything A(outPth+"/_dmpcod.txt",       "Code dump file..");
  Text WriteFile(funDmp, "");
  Text WriteFile(codDmp, "");

  Set  filTab = DtrFileExc(DtrFileSet(dctTre, dctPre)); // Tabla de ficheros

  Set  lnkTab = DctLinkAllDeclaration(filTab); // Tabla (declaracion, enlace)

  Set  filCic = EvalSet(filTab, Real(Set filSet)
  {
    Text filNam = Anything A(filSet[3], "File to agenda..");
    Text filPth = filSet[2];
    Text filPur = FirstToUpper(filSet[4]); // Descripcion por defecto

    Text agePth = outPth+"/"+FilDelExtLow(filNam)+".age";

    Text tagIni = filSet[5]; // Tag inicial si lo hubiera
    Text tagEnd = filSet[6]; // Tag inicial si lo hubiera

    Text filCod = FilBetween2Tag(filPth,  tagIni, tagEnd);

    If(TextEndAt(filNam, ".tol"), // Ficheros Tol
    {
      Text levCla = If(filSet[1]=="Rot", "Raíz", "Hoja");
      Set  dctSHi = DctTolSplit(filCod); // Corta y realza el codigo
      Set  dctCab = dctSHi[1];           // Atributos de cabecera del fichero

      DctWriteHeader (prgNam, filNam, dctCab, agePth, levCla);

      If(filSet[1]!="Rot", FALSE, // Si no es raiz el arbol al final
         DctWriteTree   (prgNam, filNam, dctCab, agePth, dctTre, levCla));

      DctWriteDisplay(prgNam, filNam, dctCab, agePth);
      DctWriteIndex  (prgNam, filNam, dctSHi, agePth, funDmp);
      DctWriteCode   (prgNam, filNam, dctSHi, agePth, lnkTab);
      DctWriteSource (prgNam, filNam, dctCab, agePth, filCod, lnkTab, codDmp);

      If(filSet[1]=="Rot", FALSE,
         DctWriteTree   (prgNam, filNam, dctCab, agePth, dctTre, levCla))
    },
    If(TextEndAt(filNam, ".pdf"), FALSE, // Archivos Pdf, nada que hacer
    {
      // Puede haber codigo Tol en ficheros htm, no html
      Set  lnkChk = If(TextEndAt(filNam, ".htm"), lnkTab, Empty);
      // Los ficheros no Tol pueden no tener buenas cabeceras
      Set  dctCab = DctGetHeaderRobust(filCod, filNam, filPur); // Atributos

      DctWriteHeader (prgNam, filNam, dctCab, agePth, "Hoja");
      DctWriteDisplay(prgNam, filNam, dctCab, agePth);
      DctWriteSource (prgNam, filNam, dctCab, agePth, filCod, lnkChk, codDmp);
      DctWriteTree   (prgNam, filNam, dctCab, agePth, dctTre, "Hoja")
    }))
  });

  Set DctOcurrences(funDmp, codDmp, 2);

  Card(filCic)
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Proceso principal de documentacion de todo el arbol de fichero de entrada.",
DctMake);
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
Set DctOcurrences(Text funDmp, // Fichero de volcado de funciones
                  Text codDmp, // Fichero de volcado de codigo
                  Real ctrOcc) // Control de ocurrencias
//////////////////////////////////////////////////////////////////////////////
{
  Set  funSet = Select(Tokenizer(ReadFile(funDmp),"\n"), Real(Text funNam)
                { Compact(funNam)!="" });
  Text codAll = ReadFile(codDmp);
  Set  funTab = EvalSet(funSet, Set(Text funNam)
                { [[funNam, TextOccurrences(codAll, funNam)]] });
  Set  funFew = Select(funTab, Real(Set funOcc) { LT(funOcc[2], ctrOcc) });
  If(!Card(funFew), Empty,
  {
    Text WriteLn("\nOcurrences:");
    EvalSet(funFew, Set(Set funOcc)
    {
      Text WriteLn("->"+funOcc[1]+": "+F(funOcc[2]));
      funOcc
    })
  })
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna una tabla de funciones y numero de occurencias para aquellas
funciones que no superan ctrOcc, como efecto latelar las visualiza.",
DctOcurrences);
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
Set DctLinkFileDeclaration(Text prgNam, // Nombre del progama
                           Text filNam, // Fichero
                           Set  dctSHi) // Codigo cortado y realzado
//////////////////////////////////////////////////////////////////////////////
{
  // Para todas las variables y funciones
  Set  lblCic = For(2, Card(dctSHi), Set(Real dctPos)
  {
    Set  dctSec = dctSHi[dctPos];
    If(DctRawCode(dctSec), Empty, // No tiene declaraciones o son en bruto
    {
      Set  decLst = dctSec[2]; // Lista de declaraciones de la seccion
      Set  decCic = EvalSet(decLst, Set(Set tolSet) // Por declaracion
      {
        Set  decSet = DctDeclare(prgNam, filNam, // Proyecto y fichero
                                 tolSet[1],      // Variable, funcion
                                 tolSet[2],      // Tipo, gramatica
                                 tolSet[3],      // Nombre
                                 tolSet[4],      // Argumentos si procede
                                 tolSet[5]);     // Descripcion de funcion
        Text decNam = tolSet[3]; // Nombre de la funcion o variable
        Text decLnk = decSet[5]; // a href a la funcion o variable
        SetOfText(decNam,decLnk) // Par (declaracion, enlace)
      })
    })
  });
  BinGroup("<<", lblCic)
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna una tabla de pares nombre de variable o funcion y su enlace de un
fichero Tol de un programa.",
DctLinkFileDeclaration);
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
Set DctLinkAllDeclaration(Set  filTab) // Tabla de ficheros, selecciona Tol
//////////////////////////////////////////////////////////////////////////////
{
  Set  lnkCic = EvalSet(filTab, Set(Set filSet)
  {
    Text filNam = Anything A(filSet[3], "File get links..");
    If(!TextEndAt(filNam, ".tol"), Empty, // No es fichero Tol
    {
      Text tagIni = filSet[5]; // Tag inicial si lo hubiera
      Text tagEnd = filSet[6]; // Tag inicial si lo hubiera
      Text filPth = filSet[2]; // Ruta del fichero
      Text filCod = FilBetween2Tag(filPth,  tagIni, tagEnd); // Lee codigo
      Set  dctSHi = DctTolSplit(filCod); // Corta y realza el codigo
      DctLinkFileDeclaration(prgNam, filNam, dctSHi) // Tabla (declara,enlace)
    })
  });
  BinGroup("<<", lnkCic)
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna una tabla de pares nombre de variable o funcion y su enlace de todos
los ficheros Tol de un programa.",
DctLinkAllDeclaration);
//////////////////////////////////////////////////////////////////////////////
"

Árbol de ficheros

Dct.Writer documenta programas Tol generado agendas para Html

  • make.tol proceso principal de documentación de programas Tol
  • tol directorios de código Tol
    • cmm funciones comunes
    • app funciones especificas de aplicacion
      • shi.tol sintaxis realzada de código Tol, Xml, Html, etc.
      • dtr.tol de árboles de ficheros para documentación
      • dct.tol de documentación de código en Html
    • inc.tol para la inclusion de ficheros Tol
  • dct donde se generan las agenda de post de documentación
  • arbol.html ejemplo de árbol para documentar codigo fuente
  • dct_writer.pdf documento resumen de funciones del programa

2015 asolver.com | Aviso legal | XHTML | Δ Θ Ξ | Creative Commons | Mapa y funciones del sitio

Tol