Javascript heredoc
(11)
Dependiendo de qué sabor del motor JS / JS esté ejecutando (SpiderMonkey, AS3) simplemente puede escribir XML en línea, en el que puede colocar texto en múltiples líneas, como heredoc:
var xml = <xml>
Here
is
some
multiline
text!
</xml>
console.log(xml.toXMLString())
console.log(xml.toString()) // just gets the content
Necesito algo como heredoc en JavaScript. ¿Tienes alguna idea para esto? Necesito la funcionalidad de navegador cruzado.
Encontré esto:
heredoc = ''/
<div>/
<ul>/
<li><a href="#zzz">zzz</a></li>/
</ul>/
</div>'';
Creo que funcionará para mí. :)
ES6 Template Strings tiene la función heredoc.
Puede declarar cadenas encerradas por back-tick (``) y se puede expandir a través de múltiples líneas.
var str = `This is my template string...
and is working across lines`;
También puede incluir expresiones dentro de cadenas de plantillas. Estos están indicados por el signo de dólar y llaves ( ${expression}
).
var js = "Java Script";
var des = `Template strings can now be used in ${js} with lot of additional features`;
console.log(des); //"Template strings can now be used in Java Script with lot of additional features"
De hecho, hay más características como cadenas de templo etiquetadas y cadenas crudas. Encuentre la documentación en
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings
Me siento mal escribiendo una respuesta por separado simplemente como una extensión de la respuesta de @ NateFerrero , pero no creo que la edición de su respuesta sea apropiada tampoco, así que por favor inviten @NateFerrero si esta respuesta fue útil para usted.
tl; dr-Para aquellos que desean usar comentarios de bloque dentro de su heredoc ...
Necesité principalmente Javascript heredoc para almacenar un bloque de CSS, por ejemplo
var css = heredoc(function() {/*
/**
* Nuke rounded corners.
*/
body div {
border-top-left-radius: 0 !important;
border-top-right-radius: 0 !important;
border-bottom-right-radius: 0 !important;
border-bottom-left-radius: 0 !important;
}
*/});
Sin embargo, como puede ver, me gusta comentar mi CSS y, desafortunadamente (como lo indica el resaltado de sintaxis), el primero */
finaliza el comentario general, rompiendo el heredoc.
Para este propósito específico (CSS), mi solución fue agregar
.replace(/(///*[/s/S]*?/*) ///g, ''$1/'')
a la cadena dentro de heredoc
@ NateFerrero; en forma completa:
function heredoc (f) {
return f.toString().match(////*/s*([/s/S]*?)/s*/*///m)[1].replace(/(///*[/s/S]*?/*) ///g, ''$1/'');
};
y úselo añadiendo un espacio entre los comentarios de bloque *
y /
para "interno", como sigue:
var css = heredoc(function() {/*
/**
* Nuke rounded corners.
* /
body div {
border-top-left-radius: 0 !important;
border-top-right-radius: 0 !important;
border-bottom-right-radius: 0 !important;
border-bottom-left-radius: 0 !important;
}
*/});
El replace
simplemente encuentra /* ... * /
y elimina el espacio para hacer /* ... */
, preservando así el heredoc hasta que se llame.
Por supuesto, puede eliminar los comentarios por completo con
.replace(////*[/s/S]*?/* ///g, '''')
También puede admitir //
comentarios si los agrega a la cadena:
.replace(/^/s*////.*$/mg, '''')
Además, puede hacer algo diferente al espacio simple entre *
y /
, como a -
:
/**
* Nuke rounded corners.
*-/
si solo actualiza la expresión regular de forma apropiada:
.replace(/(///*[/s/S]*?/*)-///g, ''$1/'')
^
¿O tal vez le gustaría una cantidad arbitraria de espacios en blanco en lugar de un espacio único?
.replace(/(///*[/s/S]*?/*)/s+///g, ''$1/'')
^^^
No, desafortunadamente JavaScript no admite nada como heredoc.
Podría usar CoffeeScript , un lenguaje que compila hasta JavaScript. El código compila uno-a-uno en el JS equivalente, y no hay interpretación en tiempo de ejecución.
Y, por supuesto, tiene heredocs :)
Pruebe ES6 String Template , puede hacer algo como
var hereDoc = `
This
is
a
Multiple
Line
String
`.trim()
hereDoc == ''This/nis/na/nMultiply/nLine/nString''
=> true
Puede usar esta gran característica hoy con 6to5 o TypeScript
Puedes usar Sweet.js Macros para agregarlo como tal, tal como lo creó Tim Disney en esta publicación
Tenga en cuenta que este enfoque utiliza los trazos inversos como los delimitadores de cadena en su lugar:
let str = macro {
case {_ $template } => {
var temp = #{$template}[0];
var tempString = temp.token.value.raw;
letstx $newTemp = [makeValue(tempString, #{here})];
return #{$newTemp}
}
}
str `foo bar baz`
Qué tal esto:
function MyHereDoc(){
/*HERE
<div>
<p>
This is written in the HEREDOC, notice the multilines :D.
</p>
<p>
HERE
</p>
<p>
And Here
</p>
</div>
HERE*/
var here = "HERE";
var reobj = new RegExp("///*"+here+"//n[//s//S]*?//n"+here+"//*/", "m");
str = reobj.exec(MyHereDoc).toString();
str = str.replace(new RegExp("///*"+here+"//n",''m''),'''').toString();
return str.replace(new RegExp("//n"+here+"//*/",''m''),'''').toString();
}
//Usage
document.write(MyHereDoc());
Simplemente reemplace "/ * AQUÍ" y "AQUÍ * /" con la palabra de elección.
Si tiene algunos html y jQuery disponibles y la cadena es HTML válido, esto puede ser útil:
<div id="heredoc"><!--heredoc content
with multiple lines, even ''quotes'' or "double quotes",
beware not to leave any tag open--></div>
<script>
var str = (function() {
var div = jQuery(''#heredoc'');
var str = div.html();
str = str.replace(/^</!--/, "").toString();
str = str.replace(/-->$/, "").toString();
return str;
})();
</script>
Si el texto tiene comentarios "<! - ->" en el medio, también funciona, pero una parte del texto puede estar visible. Aquí está el violín: https://jsfiddle.net/hr6ar152/1/
Sobre la base de la respuesta de Zv_oDD, creé una función similar para facilitar la reutilización.
Advertencia: Esta es una característica no estándar de muchos intérpretes de JS, y probablemente se elimine en algún momento, pero como estoy creando un script para usar solo en Chrome, ¡lo estoy usando! ¡ Nunca confíe en esto para los sitios web orientados al cliente!
// Multiline Function String - Nate Ferrero - Public Domain
function heredoc(fn) {
return fn.toString().match(////*/s*([/s/S]*?)/s*/*///m)[1];
};
Utilizar:
var txt = heredoc(function () {/*
A test of horrible
Multi-line strings!
*/});
Devoluciones:
"A test of horrible
Multi-line strings!"
Notas:
- El texto está recortado en ambos extremos, por lo que cualquier espacio en blanco adicional en cualquier extremo está bien.
Ediciones:
2/2/2014 - cambiado para no meterse con el prototipo de Function y usar el nombre heredoc en su lugar.
26/05/2017 - espacio en blanco actualizado para reflejar los estándares de codificación modernos.
// js heredoc - http://.com/a/32915549/466363
// a function with comment with eval-able string, use it just like regular string
function extractFuncCommentString(func,comments) {
var matches = func.toString().match(/function/s*/(/)/s*/{/s*///*/!?/s*([/s/S]+?)/s*/*///s*/}/);
if (!matches) return undefined;
var str=matches[1];
// i have made few flavors of comment removal add yours if you need something special, copy replacement lines from examples below, mix them
if(comments===1 )
{
// keep comments, in order to keep comments you need to convert /**/ to / * * / to be able to put them inside /**/ like /* / * * / */
return (
str
.replace(////s/*([/s/S]*?)/*/s///g,"/*$1*/") // change / * text * / to /* text */
)
}
else if(comments===2)
{
// keep comments and replace singleline comment to multiline comment
return (
str
.replace(////s/*([/s/S]*?)/*/s///g,"/*$1*/") // change / * text * / to /* text */
.replace(/////(.*)/g,"/*$1*/") // change //abc to /*abc*/
)
}
else if(comments===3)
{
// remove comments
return (
str
.replace(////s/*([/s/S]*?)/*/s///g,"") // match / * abc * /
.replace(/////(.*)/g,"") // match //abc
)
}
else if(comments===4)
{
// remove comments and trim and replace new lines with escape codes
return (
str
.replace(////s/*([/s/S]*?)/*/s///g,"") // match / * abc * /
.replace(/////(.*)/g,"") // match //abc
.trim() // after removing comments trim and:
.replace(//n/g,''//n'').replace(//r/g,''//r'') // replace new lines with escape codes. allows further eval() of the string, you put in the comment function: a quoted text but with new lines
)
}
else if(comments===5)
{
// keep comments comments and replace strings, might not suit when there are spaces or comments before and after quotes
// no comments allowed before quotes of the string
return (
str
.replace(////s/*([/s/S]*?)/*/s///g,"/*$1*/") // change / * text * / to /* text */
.replace(/////(.*)/g,"/*$1*/") // change //abc to /*abc*/
.trim() // trim space around quotes to not escape it and:
.replace(//n/g,''//n'').replace(//r/g,''//r'') // replace new lines with escape codes. allows further eval() of the string, you put in the comment function: a quoted text but with new lines
)
}
else
return str
}
ejemplo
var week=true,b=123;
var q = eval(extractFuncCommentString(function(){/*!
// this is a comment
''select
/ * this
is a multiline
comment * /
a
,b // this is a comment
,c
from `table`
where b=''+b+'' and monthweek="''+(week?''w'':''m'')+''"
//+'' where a=124
order by a asc
''
*/},4));
con caché: - crea una función de plantilla simple y guarda la función: (la segunda vez funciona rápido)
var myfunction_sql1;
function myfunction(week,a){
if(!myfunction_sql1) eval(''myfunction_sql1=function(week,a){return (''+extractFuncCommentString(function(){/*!
''select
/ * this
is a multiline
comment * /
a
,b // this is a comment
,c
from `table`
where b=''+b+'' and monthweek="''+(week?''w'':''m'')+''"
//+'' where a=124
order by a asc
''*/},4)+'')}'');
q=myfunction_sql1(week,a);
console.log(q)
}
myfunction(true,1234)