JavaScriptのヒアドキュメントのようなものが必要です。これについて何かアイデアはありますか?クロスブラウザ機能が必要です。
私はこれを見つけました:
heredoc = '\
<div>\
<ul>\
<li><a href="#zzz">zzz</a></li>\
</ul>\
</div>';
うまくいくと思います。:)
JavaScriptのヒアドキュメントのようなものが必要です。これについて何かアイデアはありますか?クロスブラウザ機能が必要です。
私はこれを見つけました:
heredoc = '\
<div>\
<ul>\
<li><a href="#zzz">zzz</a></li>\
</ul>\
</div>';
うまくいくと思います。:)
回答:
ES6文字列テンプレートをお試しください。次のようなことができます
var hereDoc = `
This
is
a
Multiple
Line
String
`.trim()
hereDoc == 'This\nis\na\nMultiple\nLine\nString'
=> true
6to5またはTypeScriptを使用して、この優れた機能を今日使用できます
これはどう:
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());
"/ * HERE"と "HERE * /"を選択した単語に置き換えるだけです。
*/
ヒアドキュメントに終了コメントがある場合は機能しません。
Zv_oDDの答えに基づいて、再利用を容易にするために同様の関数を作成しました。
警告:これは多くのJSインタープリターの非標準機能であり、おそらくいつかは削除されるでしょうが、私はChromeでのみ使用されるスクリプトを作成しているので、それを使用しています!クライアント向けWebサイトでこれに依存しないでください。
// Multiline Function String - Nate Ferrero - Public Domain
function heredoc(fn) {
return fn.toString().match(/\/\*\s*([\s\S]*?)\s*\*\//m)[1];
};
使用する:
var txt = heredoc(function () {/*
A test of horrible
Multi-line strings!
*/});
戻り値:
"A test of horrible
Multi-line strings!"
ノート:
編集:
2014年2月2日-Functionプロトタイプをまったく使用しないように変更され、代わりにheredocという名前を使用。
2017年5月26日-最新のコーディング標準を反映するように空白を更新
実行しているJS / JSエンジンの種類(SpiderMonkey、AS3)に応じて、ヒアドキュメントのように、テキストを複数行に配置できるインラインXMLを簡単に記述できます。
var xml = <xml>
Here
is
some
multiline
text!
</xml>
console.log(xml.toXMLString())
console.log(xml.toString()) // just gets the content
ES6 テンプレート文字列には、ヒアドキュメント機能があります。
バックティック( ``)で囲まれた文字列を宣言し、複数行で展開できます。
var str = `This is my template string...
and is working across lines`;
テンプレート文字列内に式を含めることもできます。これらは、ドル記号と中括弧(${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"
実際には、タグ付きのテンプル文字列や生の文字列など、より多くの機能があります。ドキュメントは次の場所にあります
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings
@NateFerreroの回答を単に拡張しただけで別の回答を書くのは気分が悪いですが、彼の回答を編集するのも適切だとは思いません。
私は主にCSSのブロックを保存するためにJavaScriptのヒアドキュメントを必要としました、例えば
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;
}
*/});
ただし、ご覧のとおり、私はCSSにコメントを付けたいのですが、残念ながら(構文の強調表示が示唆するように)最初の*/
コメントはコメント全体を終了させて、ヒアドキュメントを壊します。
この特定の目的(CSS)の場合、私の回避策は
.replace(/(\/\*[\s\S]*?\*) \//g, '$1/')
@NateFerrero内のチェーンにheredoc
; 完全な形で:
function heredoc (f) {
return f.toString().match(/\/\*\s*([\s\S]*?)\s*\*\//m)[1].replace(/(\/\*[\s\S]*?\*) \//g, '$1/');
};
そして、の間のスペース追加することによって、それを使用*
し、/
そのような「インナー」ブロックコメント、のために:
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;
}
*/});
はmakeするスペースをreplace
見つけ/* ... * /
て削除するだけで/* ... */
、呼び出されるまでヘレドックを保持します。
もちろん、コメントを完全に削除することができます
.replace(/\/\*[\s\S]*?\* \//g, '')
//
チェーンにコメントを追加すると、コメントをサポートすることもできます。
.replace(/^\s*\/\/.*$/mg, '')
また、次のように、*
との間の単一のスペース以外のものを実行できます。/
-
/**
* Nuke rounded corners.
*-/
正規表現を適切に更新するだけの場合:
.replace(/(\/\*[\s\S]*?\*)-\//g, '$1/')
^
それとも、単一のスペースではなく、任意の量の空白が必要ですか?
.replace(/(\/\*[\s\S]*?\*)\s+\//g, '$1/')
^^^
JavaScriptにコンパイルされる言語であるCoffeeScriptを使用できます。コードは1対1で同等のJSにコンパイルされ、実行時には解釈されません。
そしてもちろん、それはヒアドキュメントを持っています:)
この投稿でTim Disneyが作成したように、Sweet.jsマクロを使用して追加できます。
このアプローチでは、代わりに文字列区切り文字としてバックティックを使用しています。
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`
他の人が言ったように、ES6テンプレート文字列は、従来のヒアドキュメントが提供するもののほとんどを提供します。
さらに一歩進んでタグ付きテンプレート文字列theredoc
を使用したい場合は、これを実行できる便利なユーティリティ関数です。
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.
`)
}
手元にhtmlとjQueryがあり、文字列が有効なHTMLである場合、これは便利です。
<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>
テキストの間にコメント「<!-->」が含まれている場合も同様に機能しますが、テキストの一部が表示される場合があります。これがフィドルです: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
}
例
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));
キャッシュ付き:-単純なテンプレート関数を作成し、関数を保存します(2回目は高速に動作します)。
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)
私はこのバージョンを投稿しています。これは、非常に些細なことに対する正規表現の使用を回避するためです。
IMHO regexは、perl開発者の間の実用的な冗談として作成された難読化です。コミュニティの残りの人々はそれらを真剣に受け止め、数十年後、私たちは現在代価を払っています。レガシーコードとの後方互換性を除いて、正規表現を使用しないでください。最近では、すぐには人間が読めない、理解できないコードを書く言い訳はありません。正規表現は、すべてのレベルでこの原則に違反しています。
結果を現在のページに追加する方法も追加しました。これは要求されたものではありません。
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>