J'ai besoin de quelque chose comme heredoc en JavaScript. Avez-vous des idées pour cela? J'ai besoin de fonctionnalités multi-navigateurs.
J'ai trouvé ça:
heredoc = '\
<div>\
<ul>\
<li><a href="#zzz">zzz</a></li>\
</ul>\
</div>';
Je pense que cela fonctionnera pour moi. :)
Non, malheureusement, JavaScript ne supporte rien comme heredoc.
Essayez ES6 String Template, vous pouvez faire quelque chose comme
var hereDoc = `
This
is
a
Multiple
Line
String
`.trim()
hereDoc == 'This\nis\na\nMultiply\nLine\nString'
=> true
Vous pouvez utiliser cette fonctionnalité intéressante aujourd'hui avec 6to5 ou TypeScript
Que dis-tu de ça:
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());
Il suffit de remplacer "/ * ICI" et "ICI * /" par le mot de votre choix.
En me basant sur la réponse de Zv_oDD, j'ai créé une fonction similaire pour une réutilisation plus facile.
Attention: Il s'agit d'une fonctionnalité non standard de nombreux interpréteurs JS. Elle sera probablement supprimée à un moment donné. Toutefois, comme je suis en train de créer un script destiné uniquement à Chrome, je l'utilise! Ne comptez pas sur jamais pour les sites Web destinés aux clients!
// Multiline Function String - Nate Ferrero - Public Domain
function heredoc(fn) {
return fn.toString().match(/\/\*\s*([\s\S]*?)\s*\*\//m)[1];
};
Utilisation:
var txt = heredoc(function () {/*
A test of horrible
Multi-line strings!
*/});
Résultats:
"A test of horrible
Multi-line strings!"
Remarques:
Modifications:
02/02/2014 - changé pour ne pas jouer avec le prototype de fonction et utiliser le nom heredoc à la place.
26/05/2017 - espaces mis à jour pour refléter les normes de codage modernes.
Selon le type de moteur JS/JS que vous utilisez (SpiderMonkey, AS3), vous pouvez simplement écrire du code XML en ligne dans lequel vous pouvez placer du texte sur plusieurs lignes, comme heredoc:
var xml = <xml>
Here
is
some
multiline
text!
</xml>
console.log(xml.toXMLString())
console.log(xml.toString()) // just gets the content
ES6 Template Strings a une fonctionnalité heredoc.
Vous pouvez déclarer des chaînes entourées par back-tick (``) et être étendues sur plusieurs lignes.
var str = `This is my template string...
and is working across lines`;
Vous pouvez également inclure des expressions dans les chaînes de modèles. Celles-ci sont indiquées par le signe dollar et les accolades (${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"
Il contient en fait davantage de fonctionnalités telles que Tagged Temple Strings et Raw Strings. Veuillez trouver la documentation sur
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings
Je me sens mal d’écrire une réponse distincte pour une simple extension de @ NateFerrero's , mais je ne pense pas que l’édition de sa réponse soit appropriée non plus, veuillez donc voter @ @ NateFerrero si cette réponse vous était utile.
J'avais surtout besoin de Javascript heredocs pour stocker un bloc de CSS, p.
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;
}
*/});
Comme vous pouvez le constater, j’aime commenter mes CSS et, malheureusement (comme le suggère la coloration syntaxique en surbrillance), le premier */
termine le commentaire général, cassant ainsi l’hérédoc.
Dans ce but spécifique (CSS), ma solution de contournement consistait à ajouter
.replace(/(\/\*[\s\S]*?\*) \//g, '$1/')
à la chaîne à l'intérieur de la variable heredoc
de @ NateFerrero; sous forme complète:
function heredoc (f) {
return f.toString().match(/\/\*\s*([\s\S]*?)\s*\*\//m)[1].replace(/(\/\*[\s\S]*?\*) \//g, '$1/');
};
et l'utiliser en ajoutant un espace entre les *
et /
pour les commentaires de bloc "internes", comme suit:
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;
}
*/});
La replace
trouve simplement /* ... * /
et supprime l'espace pour créer /* ... */
, préservant ainsi le heredoc jusqu'à ce qu'il soit appelé.
Vous pouvez bien sûr supprimer complètement les commentaires en utilisant
.replace(/\/\*[\s\S]*?\* \//g, '')
Vous pouvez également prendre en charge les commentaires //
si vous les ajoutez à la chaîne:
.replace(/^\s*\/\/.*$/mg, '')
De plus, vous pouvez faire autre chose que l'espace unique entre *
et /
, comme un -
:
/**
* Nuke rounded corners.
*-/
si vous venez de mettre à jour le regex de manière appropriée:
.replace(/(\/\*[\s\S]*?\*)-\//g, '$1/')
^
Ou peut-être préférez-vous une quantité arbitraire d'espaces blancs au lieu d'un seul espace?
.replace(/(\/\*[\s\S]*?\*)\s+\//g, '$1/')
^^^
Vous pouvez utiliser CoffeeScript , un langage qui compile jusqu'à JavaScript. Le code est compilé un par un dans le JS équivalent et il n'y a pas d'interprétation à l'exécution.
Et bien sûr, il a heredocs :)
Vous pouvez utiliser les macros Sweet.js pour l’ajouter comme suit, créé par Tim Disney dans cet article
Notez que cette approche utilise des backticks comme délimiteurs de chaîne:
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`
ES5 et versions antérieures
(function(){/** some random multi line text here **/}).toString().slice(15,-5);
ES6 et versions ultérieures
`some random multi line text here`
résultat
some random multi line text here
Je poste cette version car elle évite l'utilisation de regex pour quelque chose d'aussi trivial.
IMHO regex est une obfuscation qui a été créée comme une blague entre développeurs. le reste de la communauté les a pris au sérieux et nous en payons maintenant le prix, des décennies plus tard. n'utilisez pas de regex, sauf pour des raisons de compatibilité avec le code hérité. De nos jours, il n'y a aucune excuse pour écrire un code qui ne soit pas immédiatement lisible et compréhensible par l'homme. regex viole ce principe à tous les niveaux.
J'ai également ajouté un moyen d'ajouter le résultat à la page en cours, même si cela n'a pas été demandé.
function pretty_css () {
/*
pre { color: blue; }
*/
}
function css_src (css_fn) {
var css = css_fn.toString();
css = css.substr(css.indexOf("/*")+2);
return css.substr(0,css.lastIndexOf("*/")).trim();
}
function addCss(rule) {
let css = document.createElement('style');
css.type = 'text/css';
if (css.styleSheet) css.styleSheet.cssText = rule; // Support for IE
else css.appendChild(document.createTextNode(rule)); // Support for the rest
document.getElementsByTagName("head")[0].appendChild(css);
}
addCss(css_src(pretty_css));
document.querySelector("pre").innerHTML=css_src(pretty_css);
<pre></pre>
Si vous avez du HTML et de jQuery sous la main et que la chaîne est valide HTML, cela peut être utile:
<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 le texte contient des commentaires "<! - ->", cela fonctionne aussi, mais une partie du texte peut être visible . Voici le violon: https://jsfiddle.net/hr6ar152/ 1/
// js heredoc - http://stackoverflow.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
}
exemple
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));
avec cache: - crée une fonction de modèle simple et enregistre la fonction: (la deuxième fois, ça marche vite)
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)
Comme d'autres l'ont dit, les chaînes de modèles ES6 vous donnent la plupart de ce que fournissent les hérédocs traditionnels.
Si vous voulez aller plus loin et utiliser une chaîne de modèle étiquetée, theredoc
est une fonction utilitaire de Nice qui vous permet de faire ceci:
if (yourCodeIsIndented) {
console.log(theredoc`
Theredoc will strip the
same amount of indentation
from each line.
You can still indent
further if you want.
It will also chop off the
whitespace-only first and
last lines.
`)
}