Funciones de textos.
Funciones de nombre corto
Text Q(Text txtVal)Text F(Anything anyVal)Funciones
Real TxtBeginStrict(Text txtInp, Text txtIni)Text TxtBetween2Tag(Text inpTxt, Text tagIni, Text tagEnd, Real cmpFlg)Text TxtCat(Text iniTxt, Text sepTxt, Text endTxt)Real TxtEndStrict(Text txtInp, Text txtEnd)Set TxtForChr(Text inpTxt, Code funChr)Set TxtLineWrap(Text txtInp, Real linMax, Real cmpCtr)Set TxtSplitBy1Tag(Text txtInp, Text tagBrk)Set TxtSplitBy2Fast(Text txtInp, Text tagIni, Text tagEnd)Set TxtSplitBy2Tag(Text txtInp, Text tagIni, Text tagEnd)Set TxtTokenizer(Text txtInp, Text tagBrk)//////////////////////////////////////////////////////////////////////////////
Text Q(Text txtVal) // Text
//////////////////////////////////////////////////////////////////////////////
{ Char(34) + txtVal + Char(34) };
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna un texto entre dobles comillas. Equivalente a la funcion Tol Qt().",
Q);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Text F(Anything anyVal)
//////////////////////////////////////////////////////////////////////////////
{
Text graVal = Grammar(anyVal);
Case
(
graVal=="Text", anyVal, // Ya es texto
graVal=="Real", If(EQ(anyVal, Round(anyVal)),
FormatReal(anyVal, "%.0lf"), // Entero sin decimales
FormatReal(anyVal, "%.2lf")), // 2 decimales
graVal=="Date", If(Hour(anyVal),
FormatDate(anyVal, "%c%Y/%m/%d %h:%i:%s"), // Tiempo
FormatDate(anyVal, "%c%Y/%m/%d")), // Fecha
graVal=="Set",
{
Real crdSet = Card(anyVal);
Case(
EQ(crdSet,0), "[]",
EQ(crdSet,1), "["+F(anyVal[1])+"]",
TRUE, "["+F(anyVal[1])+SetSum(For(2,crdSet,Text(Real setPos)
{ "|"+F(anyVal[setPos]) }))+"]")
},
TRUE, "Not basic type"
)
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna numeros, fechas, textos, conjuntos como un texto de formato simple.",
F);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Real TxtBeginStrict(Text txtInp, // Texto de entrada
Text txtIni) // Texto inicial
//////////////////////////////////////////////////////////////////////////////
{ If(txtIni=="", FALSE, TextBeginWith(txtInp, txtIni)) };
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Version estricta de TextBeginWith(), da falso siempre que txtIni sea nulo.",
TxtBeginStrict);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Text TxtBetween2Tag(Text inpTxt, // Texto de entrada
Text tagIni, // Tag inicial
Text tagEnd, // Tag final
Real cmpFlg) // Si true aplica Compact()
//////////////////////////////////////////////////////////////////////////////
{
Real posIni = TextFind(inpTxt, tagIni);
Text result = If(LE(posIni,0), "",
{
Real lenIni = TextLength(tagIni);
Real posSub = posIni + lenIni;
Real posEnd = TextFind(inpTxt, tagEnd, posSub);
If(LE(posEnd, 0), "", Sub(inpTxt, posSub, posEnd-1))
});
If(cmpFlg, Compact(result), result)
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna un subtexto entre la primera ocurrencia de tagIni y tagEnd.
Si tagIni o tagEnd no aparecen retorna la tira vacia.
Si cmpFlg es cierto entonces aplica la funcion Compact() al texto que retorna.
Por ejemplo:
TxtBetween2Tag('a b [[ c ]] d [[ e ]] f', '[[', ']]', TRUE)
retorna 'c'.",
TxtBetween2Tag);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Text TxtCat(Text iniTxt, // Texto inicial
Text sepTxt, // Texto de separacion
Text endTxt) // Texto final
//////////////////////////////////////////////////////////////////////////////
{
Case(
iniTxt=="", endTxt,
endTxt=="", iniTxt,
TRUE, iniTxt + sepTxt + endTxt)
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna un texto resultado de concatenar 2 textos con un separador en medio,
si alguno de los 2 textos son la tira vacia retorna el otro texto.",
TxtCat);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Real TxtEndStrict(Text txtInp, // Texto de entrada
Text txtEnd) // Texto final
//////////////////////////////////////////////////////////////////////////////
{ If(txtEnd=="", FALSE, TextEndAt(txtInp, txtEnd)) };
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Version estricta de TextEndAt(), da falso siempre que txtEnd sea nulo.",
TxtEndStrict);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Set TxtForChr(Text inpTxt, // Texto de entrada
Code funChr) // Funcion tipo Anything(Text oneChr)
//////////////////////////////////////////////////////////////////////////////
{
Real lenTxt = TextLength(inpTxt);
For(1, lenTxt, Anything(Real posTxt) { funChr(Sub(inpTxt,posTxt,posTxt)) })
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna el conjunto resultado de aplicar la funcion funChr(Text oneChr)
a todos los caracteres del texto de entrada txtInp.
Retorna un Set a imagen de las funciones basicas For() y EvalSet().",
TxtForChr);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Set TxtLineWrap(Text txtInp, // Texto de entrada
Real linMax, // Maximo numero de caracteres por linea
Real cmpCtr) // Si true entonces compacta
//////////////////////////////////////////////////////////////////////////////
{
Text txtCmp = If(cmpCtr, Compact(txtInp), txtInp);
Text txtRev = Reverse(txtCmp);
Real txtLen = TextLength(txtCmp);
Set cutSet = If(LE(txtLen, linMax), [[txtCmp, ""]], // Ya esta hecho
{
Real blkPos = TextFind(txtRev, " ", txtLen-linMax); // Busca para atras
If(GE(blkPos, 1),
{
SetOfText(Sub(txtCmp, 0, txtLen-blkPos),
Sub(txtCmp, txtLen-blkPos+1, txtLen))
},
{
// No se puede cortar
Real blkBad = TextFind(txtCmp, " ", linMax+1); // Busca hacia adelante
If(LT(blkBad, 0), [[txtCmp, ""]], // No hay corte posible
{
SetOfText(Sub(txtCmp, 0, blkBad-1), // Hay un mal corte
Sub(txtCmp, blkBad+1, txtLen))
})
})
});
If(cmpCtr, SetOfText(Compact(cutSet[1]),Compact(cutSet[2])), cutSet)
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna un conjunto de 2 texto el primero con un máximo de linMax caracteres
y el segundo con el resto.
Es el resultado de cortar txtInp por el primer blanco que permita que el corte
cumpla la condición inicial.
Si el texto de entrada es mas corte que linMax retorna un conjunto formado
por el texto inicial y la tira vacia.
Si el corte es imposible busca el mejor corte posible y si no lo encuentra
retorna un conjunto formado por el texto inicial y la tira vacia.
Si cmpCtr es true los resultados son compactados.
Tambien existe en Tol la funcion Wrap() con ciertas semejanzas,
aunque mas a TxtParagraphWrap().",
TxtLineWrap);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Set TxtSplitBy1Tag(Text txtInp, // Texto de entrada
Text tagBrk) // Tag por el que se corta
//////////////////////////////////////////////////////////////////////////////
{
Set txtTok = TxtTokenizer(txtInp, tagBrk);
For(1, Card(txtTok), Text(Real posTok) // Ciclo para impares y pares
{ If(posTok%2, txtTok[posTok], tagBrk+txtTok[posTok]+tagBrk) })
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna un conjunto de textos resultado de cortar el texto de entrada por un
unico tag tagBrk incluyendo dicho tagBrk al inicio y al final de cada texto
que enmarca, las ocurrencias impares de tagBrk al inicio del texto y
las impares al final.
Tiene mas sentido cuando el numero de ocurrencias de tagBrk es par.
Si el numero de ocurrencias de tagbrk es impar funciona como si al final del
texto txtInp hubiera una ultima ocurrencia.
Fue una funcion recursiva, pero la versión 2.0.1 de Tol se caia con textos
grandes, ahora es una funcion iterativa.
TxtSplitBy1Tag(aaa|::|bbb|---|ccc, |) -> [aaav, |::|, bbb, |---|, ccc].",
TxtSplitBy1Tag);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Set TxtSplitBy2Fast(Text txtInp, // Texto de entrada
Text tagIni, // Tag inicial por el que se corta
Text tagEnd) // Tag final por el que se corta
//////////////////////////////////////////////////////////////////////////////
{
Text chrBrk = Char(7); // Caracter auxiliar de corte que se espera unico
Text repEnd = Replace(txtInp, tagEnd, tagEnd+chrBrk);
Set txtSet = Tokenizer(repEnd, chrBrk);
Set cicSet = EvalSet(txtSet, Set(Text txtTok)
{
Text repIni = Replace(txtTok, tagIni, chrBrk+tagIni);
Set tokSet = Tokenizer(repIni, chrBrk);
Select(tokSet, Real(Text tokTxt) { tokTxt != "" }) // Elimina los vacios
});
BinGroup("<<", cicSet) // De conjunto de pares a conjunto lineal
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna un conjunto de textos resultado de cortar el texto de entrada por
dos tags de inicio y de fin incluyendo dichos tags al inicio y al final de
cada texto que enmarcan.
Los tags tagIni y tabEnd no han de ser nulos ni iguales, si son iguales lo
correcto seria utilizar la funcion TxtSplitBy1Tag().
No es una funcion recursiva, es mas rapida que TxtSplitBy2Tag() pero menos
resistente a la reiteracion de tags de inicio con un unico final.
No funciona correctamente si los tags inicial y final son iguales.
Tiene mas sentido cuando a cada tag de inicio le corresponde uno de final.
TxtSplitBy2Fast(aaa<::>bbb<--->ccc, <, >) -> [aaav, <::>, bbb, <--->, ccc].",
TxtSplitBy2Fast);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Set TxtSplitBy2Tag(Text txtInp, // Texto de entrada
Text tagIni, // Tag inicial por el que se corta
Text tagEnd) // Tag final por el que se corta
//////////////////////////////////////////////////////////////////////////////
{
Real posIni = TextFind(txtInp, tagIni);
If(LE(posIni,0), SetOfText(txtInp), // Nada que cortar
{
Real lenTxt = TextLength(txtInp); // Longitud del texto de entrada
Real lenIni = TextLength(tagIni); // Longitud del tag inicial
Real lenEnd = TextLength(tagEnd); // Longitud del tag final
Real posSub = posIni + lenIni;
Real posEnd = TextFind(txtInp, tagEnd, posSub);
Case(
Or(And(EQ(posIni,1),LE(posEnd,0)), // Ini en posicion 1 pero no termina
And(EQ(posIni,1),EQ(posEnd+lenEnd-1,lenTxt))), // Justo ini y final
SetOfText(txtInp),
Or(And(GT(posIni,1),LE(posEnd,0)), // Ini en posicion >1 pero no termina
And(GT(posIni,1),EQ(posEnd+lenEnd-1,lenTxt))), // Justo al final
SetOfText(
Sub(txtInp, 1, posIni-1),
Sub(txtInp, posIni, lenTxt)),
And(EQ(posIni,1),GT(posEnd,1)), // Inicia en posicion 1, termina y sigue
SetOfText(
Sub(txtInp, 1, posEnd+lenEnd-1)) <<
TxtSplitBy2Tag(Sub(txtInp, posEnd+lenEnd, lenTxt), tagIni, tagEnd),
TRUE, // Inicia posicion >1, termina y sigue
SetOfText(
Sub(txtInp, 1, posIni-1),
Sub(txtInp, posIni, posEnd+lenEnd-1)) <<
TxtSplitBy2Tag(Sub(txtInp, posEnd+lenEnd, lenTxt), tagIni, tagEnd))
})
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna un conjunto de textos resultado de cortar el texto de entrada por un
dos tags de inicio y de fin incluyendo dichos tags al inicio y al final de
cada texto que enmarcan.
Los tags tagIni y tabEnd no han de ser nulos.
Tiene mas sentido cuando a cada tag de inicio le corresponde uno de final.
Es una funcion recursiva.
Si funciona correctamente si los tags inicial y final son iguales.
TxtSplitBy2Tag(aaa<::>bbb<--->ccc, <, >) -> [aaav, <::>, bbb, <--->, ccc].",
TxtSplitBy2Tag);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Set TxtTokenizer(Text txtInp, // Texto de entrada
Text tagBrk) // Tag por el que se corta
//////////////////////////////////////////////////////////////////////////////
{ Tokenizer(Replace(txtInp, tagBrk, Char(7)), Char(7)) };
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna un conjunto de textos resultado de cortar el texto de entrada por un
unico tag tagBrk no incluyendo el tag tagBrk dentro de los textos.
Se soporta en la funcion Tol Tokenizer() que rompe por un unico caracter.
Usa como caracter interno de corte el 7 (bell), esperando que no aparezca.",
TxtTokenizer);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// FILE : txt.tol
// AUTHOR : http://www.asolver.com
// PURPOSE : Funciones de textos.
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// SHORTNAMES
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Text Q(Text txtVal) // Text
//////////////////////////////////////////////////////////////////////////////
{ Char(34) + txtVal + Char(34) };
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna un texto entre dobles comillas. Equivalente a la funcion Tol Qt().",
Q);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Text F(Anything anyVal)
//////////////////////////////////////////////////////////////////////////////
{
Text graVal = Grammar(anyVal);
Case
(
graVal=="Text", anyVal, // Ya es texto
graVal=="Real", If(EQ(anyVal, Round(anyVal)),
FormatReal(anyVal, "%.0lf"), // Entero sin decimales
FormatReal(anyVal, "%.2lf")), // 2 decimales
graVal=="Date", If(Hour(anyVal),
FormatDate(anyVal, "%c%Y/%m/%d %h:%i:%s"), // Tiempo
FormatDate(anyVal, "%c%Y/%m/%d")), // Fecha
graVal=="Set",
{
Real crdSet = Card(anyVal);
Case(
EQ(crdSet,0), "[]",
EQ(crdSet,1), "["+F(anyVal[1])+"]",
TRUE, "["+F(anyVal[1])+SetSum(For(2,crdSet,Text(Real setPos)
{ "|"+F(anyVal[setPos]) }))+"]")
},
TRUE, "Not basic type"
)
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna numeros, fechas, textos, conjuntos como un texto de formato simple.",
F);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// FUNCTIONS
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Real TxtBeginStrict(Text txtInp, // Texto de entrada
Text txtIni) // Texto inicial
//////////////////////////////////////////////////////////////////////////////
{ If(txtIni=="", FALSE, TextBeginWith(txtInp, txtIni)) };
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Version estricta de TextBeginWith(), da falso siempre que txtIni sea nulo.",
TxtBeginStrict);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Text TxtBetween2Tag(Text inpTxt, // Texto de entrada
Text tagIni, // Tag inicial
Text tagEnd, // Tag final
Real cmpFlg) // Si true aplica Compact()
//////////////////////////////////////////////////////////////////////////////
{
Real posIni = TextFind(inpTxt, tagIni);
Text result = If(LE(posIni,0), "",
{
Real lenIni = TextLength(tagIni);
Real posSub = posIni + lenIni;
Real posEnd = TextFind(inpTxt, tagEnd, posSub);
If(LE(posEnd, 0), "", Sub(inpTxt, posSub, posEnd-1))
});
If(cmpFlg, Compact(result), result)
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna un subtexto entre la primera ocurrencia de tagIni y tagEnd.
Si tagIni o tagEnd no aparecen retorna la tira vacia.
Si cmpFlg es cierto entonces aplica la funcion Compact() al texto que retorna.
Por ejemplo:
TxtBetween2Tag('a b [[ c ]] d [[ e ]] f', '[[', ']]', TRUE)
retorna 'c'.",
TxtBetween2Tag);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Text TxtCat(Text iniTxt, // Texto inicial
Text sepTxt, // Texto de separacion
Text endTxt) // Texto final
//////////////////////////////////////////////////////////////////////////////
{
Case(
iniTxt=="", endTxt,
endTxt=="", iniTxt,
TRUE, iniTxt + sepTxt + endTxt)
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna un texto resultado de concatenar 2 textos con un separador en medio,
si alguno de los 2 textos son la tira vacia retorna el otro texto.",
TxtCat);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Real TxtEndStrict(Text txtInp, // Texto de entrada
Text txtEnd) // Texto final
//////////////////////////////////////////////////////////////////////////////
{ If(txtEnd=="", FALSE, TextEndAt(txtInp, txtEnd)) };
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Version estricta de TextEndAt(), da falso siempre que txtEnd sea nulo.",
TxtEndStrict);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Set TxtForChr(Text inpTxt, // Texto de entrada
Code funChr) // Funcion tipo Anything(Text oneChr)
//////////////////////////////////////////////////////////////////////////////
{
Real lenTxt = TextLength(inpTxt);
For(1, lenTxt, Anything(Real posTxt) { funChr(Sub(inpTxt,posTxt,posTxt)) })
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna el conjunto resultado de aplicar la funcion funChr(Text oneChr)
a todos los caracteres del texto de entrada txtInp.
Retorna un Set a imagen de las funciones basicas For() y EvalSet().",
TxtForChr);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Set TxtLineWrap(Text txtInp, // Texto de entrada
Real linMax, // Maximo numero de caracteres por linea
Real cmpCtr) // Si true entonces compacta
//////////////////////////////////////////////////////////////////////////////
{
Text txtCmp = If(cmpCtr, Compact(txtInp), txtInp);
Text txtRev = Reverse(txtCmp);
Real txtLen = TextLength(txtCmp);
Set cutSet = If(LE(txtLen, linMax), [[txtCmp, ""]], // Ya esta hecho
{
Real blkPos = TextFind(txtRev, " ", txtLen-linMax); // Busca para atras
If(GE(blkPos, 1),
{
SetOfText(Sub(txtCmp, 0, txtLen-blkPos),
Sub(txtCmp, txtLen-blkPos+1, txtLen))
},
{
// No se puede cortar
Real blkBad = TextFind(txtCmp, " ", linMax+1); // Busca hacia adelante
If(LT(blkBad, 0), [[txtCmp, ""]], // No hay corte posible
{
SetOfText(Sub(txtCmp, 0, blkBad-1), // Hay un mal corte
Sub(txtCmp, blkBad+1, txtLen))
})
})
});
If(cmpCtr, SetOfText(Compact(cutSet[1]),Compact(cutSet[2])), cutSet)
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna un conjunto de 2 texto el primero con un máximo de linMax caracteres
y el segundo con el resto.
Es el resultado de cortar txtInp por el primer blanco que permita que el corte
cumpla la condición inicial.
Si el texto de entrada es mas corte que linMax retorna un conjunto formado
por el texto inicial y la tira vacia.
Si el corte es imposible busca el mejor corte posible y si no lo encuentra
retorna un conjunto formado por el texto inicial y la tira vacia.
Si cmpCtr es true los resultados son compactados.
Tambien existe en Tol la funcion Wrap() con ciertas semejanzas,
aunque mas a TxtParagraphWrap().",
TxtLineWrap);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Set TxtSplitBy1Tag(Text txtInp, // Texto de entrada
Text tagBrk) // Tag por el que se corta
//////////////////////////////////////////////////////////////////////////////
{
Set txtTok = TxtTokenizer(txtInp, tagBrk);
For(1, Card(txtTok), Text(Real posTok) // Ciclo para impares y pares
{ If(posTok%2, txtTok[posTok], tagBrk+txtTok[posTok]+tagBrk) })
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna un conjunto de textos resultado de cortar el texto de entrada por un
unico tag tagBrk incluyendo dicho tagBrk al inicio y al final de cada texto
que enmarca, las ocurrencias impares de tagBrk al inicio del texto y
las impares al final.
Tiene mas sentido cuando el numero de ocurrencias de tagBrk es par.
Si el numero de ocurrencias de tagbrk es impar funciona como si al final del
texto txtInp hubiera una ultima ocurrencia.
Fue una funcion recursiva, pero la versión 2.0.1 de Tol se caia con textos
grandes, ahora es una funcion iterativa.
TxtSplitBy1Tag(aaa|::|bbb|---|ccc, |) -> [aaav, |::|, bbb, |---|, ccc].",
TxtSplitBy1Tag);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Set TxtSplitBy2Fast(Text txtInp, // Texto de entrada
Text tagIni, // Tag inicial por el que se corta
Text tagEnd) // Tag final por el que se corta
//////////////////////////////////////////////////////////////////////////////
{
Text chrBrk = Char(7); // Caracter auxiliar de corte que se espera unico
Text repEnd = Replace(txtInp, tagEnd, tagEnd+chrBrk);
Set txtSet = Tokenizer(repEnd, chrBrk);
Set cicSet = EvalSet(txtSet, Set(Text txtTok)
{
Text repIni = Replace(txtTok, tagIni, chrBrk+tagIni);
Set tokSet = Tokenizer(repIni, chrBrk);
Select(tokSet, Real(Text tokTxt) { tokTxt != "" }) // Elimina los vacios
});
BinGroup("<<", cicSet) // De conjunto de pares a conjunto lineal
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna un conjunto de textos resultado de cortar el texto de entrada por
dos tags de inicio y de fin incluyendo dichos tags al inicio y al final de
cada texto que enmarcan.
Los tags tagIni y tabEnd no han de ser nulos ni iguales, si son iguales lo
correcto seria utilizar la funcion TxtSplitBy1Tag().
No es una funcion recursiva, es mas rapida que TxtSplitBy2Tag() pero menos
resistente a la reiteracion de tags de inicio con un unico final.
No funciona correctamente si los tags inicial y final son iguales.
Tiene mas sentido cuando a cada tag de inicio le corresponde uno de final.
TxtSplitBy2Fast(aaa<::>bbb<--->ccc, <, >) -> [aaav, <::>, bbb, <--->, ccc].",
TxtSplitBy2Fast);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Set TxtSplitBy2Tag(Text txtInp, // Texto de entrada
Text tagIni, // Tag inicial por el que se corta
Text tagEnd) // Tag final por el que se corta
//////////////////////////////////////////////////////////////////////////////
{
Real posIni = TextFind(txtInp, tagIni);
If(LE(posIni,0), SetOfText(txtInp), // Nada que cortar
{
Real lenTxt = TextLength(txtInp); // Longitud del texto de entrada
Real lenIni = TextLength(tagIni); // Longitud del tag inicial
Real lenEnd = TextLength(tagEnd); // Longitud del tag final
Real posSub = posIni + lenIni;
Real posEnd = TextFind(txtInp, tagEnd, posSub);
Case(
Or(And(EQ(posIni,1),LE(posEnd,0)), // Ini en posicion 1 pero no termina
And(EQ(posIni,1),EQ(posEnd+lenEnd-1,lenTxt))), // Justo ini y final
SetOfText(txtInp),
Or(And(GT(posIni,1),LE(posEnd,0)), // Ini en posicion >1 pero no termina
And(GT(posIni,1),EQ(posEnd+lenEnd-1,lenTxt))), // Justo al final
SetOfText(
Sub(txtInp, 1, posIni-1),
Sub(txtInp, posIni, lenTxt)),
And(EQ(posIni,1),GT(posEnd,1)), // Inicia en posicion 1, termina y sigue
SetOfText(
Sub(txtInp, 1, posEnd+lenEnd-1)) <<
TxtSplitBy2Tag(Sub(txtInp, posEnd+lenEnd, lenTxt), tagIni, tagEnd),
TRUE, // Inicia posicion >1, termina y sigue
SetOfText(
Sub(txtInp, 1, posIni-1),
Sub(txtInp, posIni, posEnd+lenEnd-1)) <<
TxtSplitBy2Tag(Sub(txtInp, posEnd+lenEnd, lenTxt), tagIni, tagEnd))
})
};
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna un conjunto de textos resultado de cortar el texto de entrada por un
dos tags de inicio y de fin incluyendo dichos tags al inicio y al final de
cada texto que enmarcan.
Los tags tagIni y tabEnd no han de ser nulos.
Tiene mas sentido cuando a cada tag de inicio le corresponde uno de final.
Es una funcion recursiva.
Si funciona correctamente si los tags inicial y final son iguales.
TxtSplitBy2Tag(aaa<::>bbb<--->ccc, <, >) -> [aaav, <::>, bbb, <--->, ccc].",
TxtSplitBy2Tag);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Set TxtTokenizer(Text txtInp, // Texto de entrada
Text tagBrk) // Tag por el que se corta
//////////////////////////////////////////////////////////////////////////////
{ Tokenizer(Replace(txtInp, tagBrk, Char(7)), Char(7)) };
//////////////////////////////////////////////////////////////////////////////
PutDescription(
"Retorna un conjunto de textos resultado de cortar el texto de entrada por un
unico tag tagBrk no incluyendo el tag tagBrk dentro de los textos.
Se soporta en la funcion Tol Tokenizer() que rompe por un unico caracter.
Usa como caracter interno de corte el 7 (bell), esperando que no aparezca.",
TxtTokenizer);
//////////////////////////////////////////////////////////////////////////////
Dct.Writer documenta programas Tol generado agendas para Html
2015 asolver.com | Aviso legal | XHTML | Δ Θ Ξ | Creative Commons | Mapa y funciones del sitio