2012-01-25 6 views
1

私はInterwebsの高低を検索して、が実際に awesomeの構文がハイライト表示され、インデントされていることなどが見つかりましたが、どれもまだSmartyテンプレートタグのサポートを受けていないようです。Smartyテンプレートタグをサポートする構文を強調したブラウザ内のJavaScriptコードエディタ?

CodeMirrorの新しいSmartyモードが最適ですが、必要な場合は別のエディタを使用します。

私はthis blog postを見つけましたが、それは非常に簡単で、CodeMirrorのPHPモードのように、HTML/CSS/JSの混在をサポートしたいと思います。

私はちょうど自分のCodeMirrorモードを起動する前にSOの頭脳をチェックすると思っていました。私が新しいモードを作って(それを持ってどこにいても)私はここに投稿します。

ありがとうございます!

答えて

1

これが役立ちます。私はこの週末CodeMirror2のSmartyモードを書いた。参照: http://www.benjaminkeen.com/misc/CodeMirror2/mode/smarty/

を、私もここで私の変化にCodeMirrorプロジェクトをフォークしました: https://github.com/benkeen/CodeMirror2

すべてのベスト -

ベン

[EDIT:これは今、メインの一部でありますスクリプト。まもなくSmarty/HTML/CSS/JSモードを追加します]。

+0

甘い、コアのSmartyモードがうまくいくようです。私はあなたのフォークで混合smartyモードを試してみましたが、しかし、いくつかのトラブルがあった。私は更新情報に気をつけます。ありがとう! – thaddeusmt

+0

彼はここに投稿したolivierの混合スマイリーモードを試してみました。あなたがそれを見てコアにロールインしたいと思えばうまくいくようです。 – thaddeusmt

2

私はスマートで混在モードにしようといくつか試みましたが、私の仕事は完璧ではありませんが、それまでは十分に機能していました。唯一のSmartyのモードにスイッチがトークン機能で作られて

CodeMirror.defineMode("smartymixed", function(config, parserConfig) { 
    var htmlMode = CodeMirror.getMode(config, {name: "xml", htmlMode: true}); 
    var smartyMode = CodeMirror.getMode(config, "smarty"); 
    var jsMode = CodeMirror.getMode(config, "javascript"); 
    var cssMode = CodeMirror.getMode(config, "css"); 



    function html(stream, state) { 
    var style = htmlMode.token(stream, state.htmlState); 
    if (style == "tag" && stream.current() == ">" && state.htmlState.context) { 
     if (/^script$/i.test(state.htmlState.context.tagName)) { 
     state.token = javascript; 
     state.localState = jsMode.startState(htmlMode.indent(state.htmlState, "")); 
     state.mode = "javascript"; 
     } 
     else if (/^style$/i.test(state.htmlState.context.tagName)) { 
     state.token = css; 
     state.localState = cssMode.startState(htmlMode.indent(state.htmlState, "")); 
     state.mode = "css"; 
     } 
    } 

    return style; 
    } 
    function maybeBackup(stream, pat, style) { 
    var cur = stream.current(); 
    var close = cur.search(pat); 
    if (close > -1) stream.backUp(cur.length - close); 
    return style; 
    } 
    function javascript(stream, state) { 
    if (stream.match(/^<\/\s*script\s*>/i, false)) { 
     state.token = html; 
     state.localState = null; 
     state.mode = "html"; 
     return html(stream, state); 
    } 
    return maybeBackup(stream, /<\/\s*script\s*>/, 
         jsMode.token(stream, state.localState)); 
    } 
    function css(stream, state) { 
    if (stream.match(/^<\/\s*style\s*>/i, false)) { 
     state.token = html; 
     state.localState = null; 
     state.mode = "html"; 
     return html(stream, state); 
    } 
    return maybeBackup(stream, /<\/\s*style\s*>/, 
         cssMode.token(stream, state.localState)); 
    } 

    function smarty(stream, state) { 
    style = smartyMode.token(stream, state.localState); 
    if (state.localState.tokenize == null) 
      { // back to anything from smarty 
      state.token = state.htmlState.tokens.pop(); 
      state.mode = state.htmlState.modes.pop(); 
      state.localState = state.htmlState.states.pop(); // state.htmlState; 
      } 
     return(style); 
     } 

    return { 

    startState: function() { 
     var state = htmlMode.startState(); 
     state.modes = []; 
     state.tokens = []; 
     state.states = []; 
     return {token: html, localState: null, mode: "html", htmlState: state}; 
    }, 

    copyState: function(state) { 
     if (state.localState) 
     var local = CodeMirror.copyState( 
      (state.token == css) ? cssMode : ((state.token == javascript) ? jsMode : smartyMode), 
      state.localState); 
     return {token: state.token, localState: local, mode: state.mode, 
       htmlState: CodeMirror.copyState(htmlMode, state.htmlState)}; 
    }, 

    token: function(stream, state) { 

     if (stream.match(/^{[^ ]{1}/,false)) 
      { // leaving anything to smarty 
      state.htmlState.states.push(state.localState); 
      state.htmlState.tokens.push(state.token); 
      state.htmlState.modes.push(state.mode); 
      state.token = smarty; 
       state.localState = smartyMode.startState(); 
       state.mode = "smarty"; 
      } 

     return state.token(stream, state); 
    }, 


    compareStates: function(a, b) { 
     if (a.mode != b.mode) return false; 
     if (a.localState) return CodeMirror.Pass; 
     return htmlMode.compareStates(a.htmlState, b.htmlState); 
    }, 

    electricChars: "/{}:" 
    } 
}, "xml", "javascript", "css", "smarty"); 

CodeMirror.defineMIME("text/html", "smartymixed"); 

けど... あなたはまた、他の基本的なモード(CSS、JavaScriptの& XML)をパッチを適用する必要があります。私はSmartyのモードを追加するデhtmlmixedmodeから開始しましたそれらを{文字で止めるには、トークン関数に戻ってregexp({に続けて空白でない文字)を指定してテストしてください。

+0

次回は、モデレータフラグを使用してください。答えの下にある「旗」のリンクを見てください。答え以外は何も使わないでください。回答が投稿されたときに通知を受けるのは、質問所有者だけです。 –

+0

混在モードはこれまでのところうまくいきました。感謝と歓声 – thaddeusmt

1

答えの2番目の部分:それを残してsmartymixedmodeに戻ることができるベンジャミンスマイリーファイルのパッチ。だから我々はsmartymixedモードとテストによって呼び出された場合、ここでモード/ Smartyの/ smarty.js

CodeMirror.defineMode("smarty", function(config, parserConfig) { 
    var breakOnSmarty = (config.mode == "smartymixed") ? true : false; // we are called in a "smartymixed" context 
    var keyFuncs = ["debug", "extends", "function", "include", "literal"]; 
    var last; 
    var regs = { 
    operatorChars: /[+\-*&%=<>!?]/, 
    validIdentifier: /[a-zA-Z0-9\_]/, 
    stringChar: /[\'\"]/ 
    } 
    var leftDelim = (typeof config.mode.leftDelimiter != 'undefined') ? config.mode.leftDelimiter : "{"; 
    var rightDelim = (typeof config.mode.rightDelimiter != 'undefined') ? config.mode.rightDelimiter : "}"; 
    function ret(style, lst) { last = lst; return style; } 


    function tokenizer(stream, state) { 
    function chain(parser) { 
     state.tokenize = parser; 
     return parser(stream, state); 
    } 

    if (stream.match(leftDelim, true)) { 
     if (stream.eat("*")) { 
     return chain(inBlock("comment", "*" + rightDelim)); 
     } 
     else { 
     state.tokenize = inSmarty; 
     return (breakOnSmarty == true) ? "bracket" : "tag"; 
     } 
    } 
    else { 
     // I'd like to do an eatWhile() here, but I can't get it to eat only up to the rightDelim string/char 
     stream.next(); 
     return null; 
    } 
    } 

    function inSmarty(stream, state) { 
    if (stream.match(rightDelim, true)) { 
     state.tokenize = (breakOnSmarty) ? null : tokenizer; 
     return (breakOnSmarty == true) ? ret("bracket", null) : ret("tag", null); 
    } 

    var ch = stream.next(); 
    if (ch == "$") { 
     stream.eatWhile(regs.validIdentifier); 
     return ret("variable-2", "variable"); 
    } 
    else if (ch == ".") { 
     return ret("operator", "property"); 
    } 
    else if (regs.stringChar.test(ch)) { 
     state.tokenize = inAttribute(ch); 
     return ret("string", "string"); 
    } 
    else if (regs.operatorChars.test(ch)) { 
     stream.eatWhile(regs.operatorChars); 
     return ret("operator", "operator"); 
    } 
    else if (ch == "[" || ch == "]") { 
     return ret("bracket", "bracket"); 
    } 
    else if (/\d/.test(ch)) { 
     stream.eatWhile(/\d/); 
     return ret("number", "number"); 
    } 
    else { 
     if (state.last == "variable") { 
     if (ch == "@") { 
      stream.eatWhile(regs.validIdentifier); 
      return ret("property", "property"); 
     } 
     else if (ch == "|") { 
      stream.eatWhile(regs.validIdentifier); 
      return ret("qualifier", "modifier"); 
     } 
     } 
     else if (state.last == "whitespace") { 
     stream.eatWhile(regs.validIdentifier); 
     return ret("attribute", "modifier"); 
     } 
     else if (state.last == "property") { 
     stream.eatWhile(regs.validIdentifier); 
     return ret("property", null); 
     } 
     else if (/\s/.test(ch)) { 
     last = "whitespace"; 
     return null; 
     } 

     var str = ""; 
     if (ch != "/") { 
     str += ch; 
     } 
     var c = ""; 
     while ((c = stream.eat(regs.validIdentifier))) { 
     str += c; 
     } 
     var i, j; 
     for (i=0, j=keyFuncs.length; i<j; i++) { 
     if (keyFuncs[i] == str) { 
      return ret("keyword", "keyword"); 
     } 
     } 
     if (/\s/.test(ch)) { 
     return null; 
     } 
     return ret("tag", "tag"); 
    } 
    } 

    function inAttribute(quote) { 
    return function(stream, state) { 
     while (!stream.eol()) { 
     if (stream.next() == quote) { 
      state.tokenize = inSmarty; 
      break; 
     } 
     } 
     return "string"; 
    }; 
    } 

    function inBlock(style, terminator) { 
    return function(stream, state) { 
     while (!stream.eol()) { 
     if (stream.match(terminator)) { 
      state.tokenize = (breakOnSmarty == true) ? null : tokenizer; 
      break; 
     } 
     stream.next(); 
     } 
     return style; 
    }; 
    } 

    return { 
    startState: function() { 
     return { tokenize: tokenizer, mode: "smarty", last: null }; 
    }, 
    token: function(stream, state) { 
     var style = state.tokenize(stream, state); 
     state.last = last; 
     return style; 
    }, 
    electricChars: "" 
    } 
}); 

CodeMirror.defineMIME("text/x-smarty", "smarty"); 

のパッチを適用しversonは、1行目のチェックでは、以前のように実行するためにSmartyのモードを許可する、このcontitionに作られています。

関連する問題