Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
279 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,3 +2,5 @@ | |
/npm-debug.log | ||
test.html | ||
.tern-* | ||
*~ | ||
*.swp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
<!doctype html> | ||
<html> | ||
<head> | ||
<meta charset="utf-8"> | ||
<title>CodeMirror: Smarty mixed mode</title> | ||
<link rel="stylesheet" href="../../lib/codemirror.css"> | ||
<script src="../../lib/codemirror.js"></script> | ||
<link rel="stylesheet" href="../../doc/docs.css"> | ||
|
||
<!-- smartymixed dependencies --> | ||
<script src="../../mode/xml/xml.js"></script> | ||
<script src="../../mode/javascript/javascript.js"></script> | ||
<script src="../../mode/css/css.js"></script> | ||
<script src="../../mode/htmlmixed/htmlmixed.js"></script> | ||
<script src="../../mode/smarty/smarty.js"></script> | ||
|
||
<!-- smartymixed --> | ||
<script src="../../mode/smartymixed/smartymixed.js"></script> | ||
</head> | ||
<body> | ||
<h1>CodeMirror: Smarty mixed mode</h1> | ||
<form><textarea id="code" name="code"> | ||
{** | ||
* @brief Smarty mixed mode | ||
* @author Ruslan Osmanov | ||
* @date 29.06.2013 | ||
*} | ||
<html> | ||
<head> | ||
<title>{$title|htmlspecialchars|truncate:30}</title> | ||
</head> | ||
<body> | ||
{* Multiline smarty | ||
* comment, no {$variables} here | ||
*} | ||
{literal} | ||
{literal} is just an HTML text. | ||
<script type="text/javascript">//<![CDATA[ | ||
var a = {$just_a_normal_js_object : "value"}; | ||
var myCodeMirror = CodeMirror.fromTextArea(document.getElementById("code"), { | ||
mode : "smartymixed", | ||
tabSize : 2, | ||
indentUnit : 2, | ||
indentWithTabs : false, | ||
lineNumbers : true, | ||
smartyVersion : 3 | ||
}); | ||
// ]]> | ||
</script> | ||
<style> | ||
/* CSS content | ||
{$no_smarty} */ | ||
.some-class { font-weight: bolder; color: "orange"; } | ||
</style> | ||
{/literal} | ||
|
||
{extends file="parent.tpl"} | ||
{include file="template.tpl"} | ||
|
||
{* some example Smarty content *} | ||
{if isset($name) && $name == 'Blog'} | ||
This is a {$var}. | ||
{$integer = 4511}, {$array[] = "a"}, {$stringvar = "string"} | ||
{$integer = 4512} {$array[] = "a"} {$stringvar = "string"} | ||
{assign var='bob' value=$var.prop} | ||
{elseif $name == $foo} | ||
{function name=menu level=0} | ||
{foreach $data as $entry} | ||
{if is_array($entry)} | ||
- {$entry@key} | ||
{menu data=$entry level=$level+1} | ||
{else} | ||
{$entry} | ||
{* One | ||
* Two | ||
* Three | ||
*} | ||
{/if} | ||
{/foreach} | ||
{/function} | ||
{/if} | ||
</body> | ||
<!-- R.O. --> | ||
</html> | ||
</textarea></form> | ||
|
||
<script type="text/javascript"> | ||
var myCodeMirror = CodeMirror.fromTextArea(document.getElementById("code"), { | ||
mode : "smartymixed", | ||
tabSize : 2, | ||
indentUnit : 2, | ||
indentWithTabs : false, | ||
lineNumbers : true, | ||
smartyVersion : 3, | ||
matchBrackets : true, | ||
}); | ||
</script> | ||
|
||
<p>The Smarty mixed mode depends on the Smarty and HTML mixed modes. HTML | ||
mixed mode itself depends on XML, JavaScript, and CSS modes.</p> | ||
|
||
<p>It takes the same options, as Smarty and HTML mixed modes.</p> | ||
|
||
<p><strong>MIME types defined:</strong> <code>text/x-smarty</code>.</p> | ||
</body> | ||
</html> | ||
<!-- vim: set ft=html ts=2 sts=2 sw=2 et: --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
/** | ||
* @file smartymixed.js | ||
* @brief Smarty Mixed Codemirror mode (Smarty + Mixed HTML) | ||
* @author Ruslan Osmanov <rrosmanov at gmail dot com> | ||
* @version 3.0 | ||
* @date 05.07.2013 | ||
*/ | ||
CodeMirror.defineMode("smartymixed", function(config) { | ||
var settings, regs, helpers, parsers, | ||
htmlMixedMode = CodeMirror.getMode(config, "htmlmixed"), | ||
smartyMode = CodeMirror.getMode(config, "smarty"), | ||
|
||
settings = { | ||
rightDelimiter: '}', | ||
leftDelimiter: '{' | ||
}; | ||
|
||
if (config.hasOwnProperty("leftDelimiter")) { | ||
settings.leftDelimiter = config.leftDelimiter; | ||
} | ||
if (config.hasOwnProperty("rightDelimiter")) { | ||
settings.rightDelimiter = config.rightDelimiter; | ||
} | ||
|
||
regs = { | ||
smartyComment: new RegExp("^" + settings.leftDelimiter + "\\*"), | ||
literalOpen: new RegExp(settings.leftDelimiter + "literal" + settings.rightDelimiter), | ||
literalClose: new RegExp(settings.leftDelimiter + "\/literal" + settings.rightDelimiter), | ||
hasLeftDelimeter: new RegExp(".*" + settings.leftDelimiter), | ||
htmlHasLeftDelimeter: new RegExp("[^<>]*" + settings.leftDelimiter) | ||
}; | ||
|
||
helpers = { | ||
chain: function(stream, state, parser) { | ||
state.tokenize = parser; | ||
return parser(stream, state); | ||
}, | ||
|
||
cleanChain: function(stream, state, parser) { | ||
state.tokenize = null; | ||
state.localState = null; | ||
state.localMode = null; | ||
return (typeof parser == "string") ? (parser ? parser : null) : parser(stream, state); | ||
}, | ||
|
||
maybeBackup: function(stream, pat, style) { | ||
var cur = stream.current(); | ||
var close = cur.search(pat), | ||
m; | ||
if (close > - 1) stream.backUp(cur.length - close); | ||
else if (m = cur.match(/<\/?$/)) { | ||
stream.backUp(cur.length); | ||
if (!stream.match(pat, false)) stream.match(cur[0]); | ||
} | ||
return style; | ||
} | ||
}; | ||
|
||
parsers = { | ||
html: function(stream, state) { | ||
if (!state.inLiteral && stream.match(regs.htmlHasLeftDelimeter, false)) { | ||
state.tokenize = parsers.smarty; | ||
state.localMode = smartyMode; | ||
state.localState = smartyMode.startState(htmlMixedMode.indent(state.htmlMixedState, "")); | ||
return helpers.maybeBackup(stream, settings.leftDelimiter, smartyMode.token(stream, state.localState)); | ||
} | ||
return htmlMixedMode.token(stream, state.htmlMixedState); | ||
}, | ||
|
||
smarty: function(stream, state) { | ||
if (stream.match(settings.leftDelimiter, false)) { | ||
if (stream.match(regs.smartyComment, false)) { | ||
return helpers.chain(stream, state, parsers.inBlock("comment", "*" + settings.rightDelimiter)); | ||
} | ||
} else if (stream.match(settings.rightDelimiter, false)) { | ||
stream.eat(settings.rightDelimiter); | ||
state.tokenize = parsers.html; | ||
state.localMode = htmlMixedMode; | ||
state.localState = state.htmlMixedState; | ||
return "tag"; | ||
} | ||
|
||
return helpers.maybeBackup(stream, settings.rightDelimiter, smartyMode.token(stream, state.localState)); | ||
}, | ||
|
||
inBlock: function(style, terminator) { | ||
return function(stream, state) { | ||
while (!stream.eol()) { | ||
if (stream.match(terminator)) { | ||
helpers.cleanChain(stream, state, ""); | ||
break; | ||
} | ||
stream.next(); | ||
} | ||
return style; | ||
}; | ||
} | ||
}; | ||
|
||
return { | ||
startState: function() { | ||
var state = htmlMixedMode.startState(); | ||
return { | ||
token: parsers.html, | ||
localMode: null, | ||
localState: null, | ||
htmlMixedState: state, | ||
tokenize: null, | ||
inLiteral: false | ||
}; | ||
}, | ||
|
||
copyState: function(state) { | ||
var local = null, tok = (state.tokenize || state.token); | ||
if (state.localState) { | ||
local = CodeMirror.copyState((tok != parsers.html ? smartyMode : htmlMixedMode), state.localState); | ||
} | ||
return { | ||
token: state.token, | ||
tokenize: state.tokenize, | ||
localMode: state.localMode, | ||
localState: local, | ||
htmlMixedState: CodeMirror.copyState(htmlMixedMode, state.htmlMixedState), | ||
inLiteral: state.inLiteral | ||
}; | ||
}, | ||
|
||
token: function(stream, state) { | ||
if (stream.match(settings.leftDelimiter, false)) { | ||
if (!state.inLiteral && stream.match(regs.literalOpen, true)) { | ||
state.inLiteral = true; | ||
return "keyword"; | ||
} else if (state.inLiteral && stream.match(regs.literalClose, true)) { | ||
state.inLiteral = false; | ||
return "keyword"; | ||
} | ||
} | ||
if (state.inLiteral && state.localState != state.htmlMixedState) { | ||
state.tokenize = parsers.html; | ||
state.localMode = htmlMixedMode; | ||
state.localState = state.htmlMixedState; | ||
} | ||
|
||
var style = (state.tokenize || state.token)(stream, state); | ||
return style; | ||
}, | ||
|
||
indent: function(state, textAfter) { | ||
if (state.localMode == smartyMode | ||
|| (state.inLiteral && !state.localMode) | ||
|| regs.hasLeftDelimeter.test(textAfter)) { | ||
return CodeMirror.Pass; | ||
} | ||
return htmlMixedMode.indent(state.htmlMixedState, textAfter); | ||
}, | ||
|
||
electricChars: "/{}:", | ||
|
||
innerMode: function(state) { | ||
return { | ||
state: state.localState || state.htmlMixedState, | ||
mode: state.localMode || htmlMixedMode | ||
}; | ||
} | ||
}; | ||
}, | ||
"htmlmixed"); | ||
|
||
CodeMirror.defineMIME("text/x-smarty", "smartymixed"); | ||
// vim: et ts=2 sts=2 sw=2 |