This commit is contained in:
2018-08-23 09:48:32 +08:00
parent 80e34d7c2c
commit 2e66bb8e1b
333 changed files with 66758 additions and 0 deletions

View File

@@ -0,0 +1,191 @@
<!doctype html>
<title>CodeMirror: Textile mode</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../../doc/docs.css">
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="textile.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<div id=nav>
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<ul>
<li><a href="../../index.html">Home</a>
<li><a href="../../doc/manual.html">Manual</a>
<li><a href="https://github.com/marijnh/codemirror">Code</a>
</ul>
<ul>
<li><a href="../index.html">Language modes</a>
<li><a class="active" href="#">Textile</a>
</ul>
</div>
<article>
<h2>Textile mode</h2>
<form><textarea id="code" name="code">
h1. Textile Mode
A paragraph without formatting.
p. A simple Paragraph.
h2. Phrase Modifiers
Here are some simple phrase modifiers: *strong*, _emphasis_, **bold**, and __italic__.
A ??citation??, -deleted text-, +inserted text+, some ^superscript^, and some ~subscript~.
A %span element% and @code element@
A "link":http://example.com, a "link with (alt text)":urlAlias
[urlAlias]http://example.com/
An image: !http://example.com/image.png! and an image with a link: !http://example.com/image.png!:http://example.com
A sentence with a footnote.[123]
fn123. The footnote is defined here.
Registered(r), Trademark(tm), and Copyright(c)
h2. Headers
h1. Top level
h2. Second level
h3. Third level
h4. Fourth level
h5. Fifth level
h6. Lowest level
h2. Lists
* An unordered list
** foo bar
*** foo bar
**** foo bar
** foo bar
# An ordered list
## foo bar
### foo bar
#### foo bar
## foo bar
- definition list := description
- another item := foo bar
- spanning ines :=
foo bar
foo bar =:
h2. Attributes
Layouts and phrase modifiers can be modified with various kinds of attributes: alignment, CSS ID, CSS class names, language, padding, and CSS styles.
h3. Alignment
div<. left align
div>. right align
h3. CSS ID and class name
You are a %(my-id#my-classname) rad% person.
h3. Language
p[en_CA]. Strange weather, eh?
h3. Horizontal Padding
p(())). 2em left padding, 3em right padding
h3. CSS styling
p{background: red}. Fire!
h2. Table
|_. Header 1 |_. Header 2 |
|{background:#ddd}. Cell with background| Normal |
|\2. Cell spanning 2 columns |
|/2. Cell spanning 2 rows |(cell-class). one |
| two |
|>. Right aligned cell |<. Left aligned cell |
h3. A table with attributes:
table(#prices).
|Adults|$5|
|Children|$2|
h2. Code blocks
bc.
function factorial(n) {
if (n === 0) {
return 1;
}
return n * factorial(n - 1);
}
pre..
,,,,,,
o#'9MMHb':'-,o,
.oH":HH$' "' ' -*R&o,
dMMM*""'`' .oM"HM?.
,MMM' "HLbd< ?&H\
.:MH ."\ ` MM MM&b
. "*H - &MMMMMMMMMH:
. dboo MMMMMMMMMMMM.
. dMMMMMMb *MMMMMMMMMP.
. MMMMMMMP *MMMMMP .
`#MMMMM MM6P ,
' `MMMP" HM*`,
' :MM .- ,
'. `#?.. . ..'
-. . .-
''-.oo,oo.-''
\. _(9>
\==_)
-'=
h2. Temporarily disabling textile markup
notextile. Don't __touch this!__
Surround text with double-equals to disable textile inline. Example: Use ==*asterisks*== for *strong* text.
h2. HTML
Some block layouts are simply textile versions of HTML tags with the same name, like @div@, @pre@, and @p@. HTML tags can also exist on their own line:
<section>
<h1>Title</h1>
<p>Hello!</p>
</section>
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
mode: "text/x-textile"
});
</script>
<p><strong>MIME types defined:</strong> <code>text/x-textile</code>.</p>
<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#textile_*">normal</a>, <a href="../../test/index.html#verbose,textile_*">verbose</a>.</p>
</article>

View File

@@ -0,0 +1,417 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function() {
var mode = CodeMirror.getMode({tabSize: 4}, 'textile');
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
MT('simpleParagraphs',
'Some text.',
'',
'Some more text.');
/*
* Phrase Modifiers
*/
MT('em',
'foo [em _bar_]');
MT('emBoogus',
'code_mirror');
MT('strong',
'foo [strong *bar*]');
MT('strongBogus',
'3 * 3 = 9');
MT('italic',
'foo [em __bar__]');
MT('italicBogus',
'code__mirror');
MT('bold',
'foo [strong **bar**]');
MT('boldBogus',
'3 ** 3 = 27');
MT('simpleLink',
'[link "CodeMirror":http://codemirror.net]');
MT('referenceLink',
'[link "CodeMirror":code_mirror]',
'Normal Text.',
'[link [[code_mirror]]http://codemirror.net]');
MT('footCite',
'foo bar[qualifier [[1]]]');
MT('footCiteBogus',
'foo bar[[1a2]]');
MT('special-characters',
'Registered [tag (r)], ' +
'Trademark [tag (tm)], and ' +
'Copyright [tag (c)] 2008');
MT('cite',
"A book is [keyword ??The Count of Monte Cristo??] by Dumas.");
MT('additionAndDeletion',
'The news networks declared [negative -Al Gore-] ' +
'[positive +George W. Bush+] the winner in Florida.');
MT('subAndSup',
'f(x, n) = log [builtin ~4~] x [builtin ^n^]');
MT('spanAndCode',
'A [quote %span element%] and [atom @code element@]');
MT('spanBogus',
'Percentage 25% is not a span.');
MT('citeBogus',
'Question? is not a citation.');
MT('codeBogus',
'user@example.com');
MT('subBogus',
'~username');
MT('supBogus',
'foo ^ bar');
MT('deletionBogus',
'3 - 3 = 0');
MT('additionBogus',
'3 + 3 = 6');
MT('image',
'An image: [string !http://www.example.com/image.png!]');
MT('imageWithAltText',
'An image: [string !http://www.example.com/image.png (Alt Text)!]');
MT('imageWithUrl',
'An image: [string !http://www.example.com/image.png!:http://www.example.com/]');
/*
* Headers
*/
MT('h1',
'[header&header-1 h1. foo]');
MT('h2',
'[header&header-2 h2. foo]');
MT('h3',
'[header&header-3 h3. foo]');
MT('h4',
'[header&header-4 h4. foo]');
MT('h5',
'[header&header-5 h5. foo]');
MT('h6',
'[header&header-6 h6. foo]');
MT('h7Bogus',
'h7. foo');
MT('multipleHeaders',
'[header&header-1 h1. Heading 1]',
'',
'Some text.',
'',
'[header&header-2 h2. Heading 2]',
'',
'More text.');
MT('h1inline',
'[header&header-1 h1. foo ][header&header-1&em _bar_][header&header-1 baz]');
/*
* Lists
*/
MT('ul',
'foo',
'bar',
'',
'[variable-2 * foo]',
'[variable-2 * bar]');
MT('ulNoBlank',
'foo',
'bar',
'[variable-2 * foo]',
'[variable-2 * bar]');
MT('ol',
'foo',
'bar',
'',
'[variable-2 # foo]',
'[variable-2 # bar]');
MT('olNoBlank',
'foo',
'bar',
'[variable-2 # foo]',
'[variable-2 # bar]');
MT('ulFormatting',
'[variable-2 * ][variable-2&em _foo_][variable-2 bar]',
'[variable-2 * ][variable-2&strong *][variable-2&em&strong _foo_]' +
'[variable-2&strong *][variable-2 bar]',
'[variable-2 * ][variable-2&strong *foo*][variable-2 bar]');
MT('olFormatting',
'[variable-2 # ][variable-2&em _foo_][variable-2 bar]',
'[variable-2 # ][variable-2&strong *][variable-2&em&strong _foo_]' +
'[variable-2&strong *][variable-2 bar]',
'[variable-2 # ][variable-2&strong *foo*][variable-2 bar]');
MT('ulNested',
'[variable-2 * foo]',
'[variable-3 ** bar]',
'[keyword *** bar]',
'[variable-2 **** bar]',
'[variable-3 ** bar]');
MT('olNested',
'[variable-2 # foo]',
'[variable-3 ## bar]',
'[keyword ### bar]',
'[variable-2 #### bar]',
'[variable-3 ## bar]');
MT('ulNestedWithOl',
'[variable-2 * foo]',
'[variable-3 ## bar]',
'[keyword *** bar]',
'[variable-2 #### bar]',
'[variable-3 ** bar]');
MT('olNestedWithUl',
'[variable-2 # foo]',
'[variable-3 ** bar]',
'[keyword ### bar]',
'[variable-2 **** bar]',
'[variable-3 ## bar]');
MT('definitionList',
'[number - coffee := Hot ][number&em _and_][number black]',
'',
'Normal text.');
MT('definitionListSpan',
'[number - coffee :=]',
'',
'[number Hot ][number&em _and_][number black =:]',
'',
'Normal text.');
MT('boo',
'[number - dog := woof woof]',
'[number - cat := meow meow]',
'[number - whale :=]',
'[number Whale noises.]',
'',
'[number Also, ][number&em _splashing_][number . =:]');
/*
* Attributes
*/
MT('divWithAttribute',
'[punctuation div][punctuation&attribute (#my-id)][punctuation . foo bar]');
MT('divWithAttributeAnd2emRightPadding',
'[punctuation div][punctuation&attribute (#my-id)((][punctuation . foo bar]');
MT('divWithClassAndId',
'[punctuation div][punctuation&attribute (my-class#my-id)][punctuation . foo bar]');
MT('paragraphWithCss',
'p[attribute {color:red;}]. foo bar');
MT('paragraphNestedStyles',
'p. [strong *foo ][strong&em _bar_][strong *]');
MT('paragraphWithLanguage',
'p[attribute [[fr]]]. Parlez-vous français?');
MT('paragraphLeftAlign',
'p[attribute <]. Left');
MT('paragraphRightAlign',
'p[attribute >]. Right');
MT('paragraphRightAlign',
'p[attribute =]. Center');
MT('paragraphJustified',
'p[attribute <>]. Justified');
MT('paragraphWithLeftIndent1em',
'p[attribute (]. Left');
MT('paragraphWithRightIndent1em',
'p[attribute )]. Right');
MT('paragraphWithLeftIndent2em',
'p[attribute ((]. Left');
MT('paragraphWithRightIndent2em',
'p[attribute ))]. Right');
MT('paragraphWithLeftIndent3emRightIndent2em',
'p[attribute ((())]. Right');
MT('divFormatting',
'[punctuation div. ][punctuation&strong *foo ]' +
'[punctuation&strong&em _bar_][punctuation&strong *]');
MT('phraseModifierAttributes',
'p[attribute (my-class)]. This is a paragraph that has a class and' +
' this [em _][em&attribute (#special-phrase)][em emphasized phrase_]' +
' has an id.');
MT('linkWithClass',
'[link "(my-class). This is a link with class":http://redcloth.org]');
/*
* Layouts
*/
MT('paragraphLayouts',
'p. This is one paragraph.',
'',
'p. This is another.');
MT('div',
'[punctuation div. foo bar]');
MT('pre',
'[operator pre. Text]');
MT('bq.',
'[bracket bq. foo bar]',
'',
'Normal text.');
MT('footnote',
'[variable fn123. foo ][variable&strong *bar*]');
/*
* Spanning Layouts
*/
MT('bq..ThenParagraph',
'[bracket bq.. foo bar]',
'',
'[bracket More quote.]',
'p. Normal Text');
MT('bq..ThenH1',
'[bracket bq.. foo bar]',
'',
'[bracket More quote.]',
'[header&header-1 h1. Header Text]');
MT('bc..ThenParagraph',
'[atom bc.. # Some ruby code]',
'[atom obj = {foo: :bar}]',
'[atom puts obj]',
'',
'[atom obj[[:love]] = "*love*"]',
'[atom puts obj.love.upcase]',
'',
'p. Normal text.');
MT('fn1..ThenParagraph',
'[variable fn1.. foo bar]',
'',
'[variable More.]',
'p. Normal Text');
MT('pre..ThenParagraph',
'[operator pre.. foo bar]',
'',
'[operator More.]',
'p. Normal Text');
/*
* Tables
*/
MT('table',
'[variable-3&operator |_. name |_. age|]',
'[variable-3 |][variable-3&strong *Walter*][variable-3 | 5 |]',
'[variable-3 |Florence| 6 |]',
'',
'p. Normal text.');
MT('tableWithAttributes',
'[variable-3&operator |_. name |_. age|]',
'[variable-3 |][variable-3&attribute /2.][variable-3 Jim |]',
'[variable-3 |][variable-3&attribute \\2{color: red}.][variable-3 Sam |]');
/*
* HTML
*/
MT('html',
'[comment <div id="wrapper">]',
'[comment <section id="introduction">]',
'',
'[header&header-1 h1. Welcome]',
'',
'[variable-2 * Item one]',
'[variable-2 * Item two]',
'',
'[comment <a href="http://example.com">Example</a>]',
'',
'[comment </section>]',
'[comment </div>]');
MT('inlineHtml',
'I can use HTML directly in my [comment <span class="youbetcha">Textile</span>].');
/*
* No-Textile
*/
MT('notextile',
'[string-2 notextile. *No* formatting]');
MT('notextileInline',
'Use [string-2 ==*asterisks*==] for [strong *strong*] text.');
MT('notextileWithPre',
'[operator pre. *No* formatting]');
MT('notextileWithSpanningPre',
'[operator pre.. *No* formatting]',
'',
'[operator *No* formatting]');
/* Only toggling phrases between non-word chars. */
MT('phrase-in-word',
'foo_bar_baz');
MT('phrase-non-word',
'[negative -x-] aaa-bbb ccc-ddd [negative -eee-] fff [negative -ggg-]');
MT('phrase-lone-dash',
'foo - bar - baz');
})();

View File

@@ -0,0 +1,469 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") { // CommonJS
mod(require("../../lib/codemirror"));
} else if (typeof define == "function" && define.amd) { // AMD
define(["../../lib/codemirror"], mod);
} else { // Plain browser env
mod(CodeMirror);
}
})(function(CodeMirror) {
"use strict";
var TOKEN_STYLES = {
addition: "positive",
attributes: "attribute",
bold: "strong",
cite: "keyword",
code: "atom",
definitionList: "number",
deletion: "negative",
div: "punctuation",
em: "em",
footnote: "variable",
footCite: "qualifier",
header: "header",
html: "comment",
image: "string",
italic: "em",
link: "link",
linkDefinition: "link",
list1: "variable-2",
list2: "variable-3",
list3: "keyword",
notextile: "string-2",
pre: "operator",
p: "property",
quote: "bracket",
span: "quote",
specialChar: "tag",
strong: "strong",
sub: "builtin",
sup: "builtin",
table: "variable-3",
tableHeading: "operator"
};
function startNewLine(stream, state) {
state.mode = Modes.newLayout;
state.tableHeading = false;
if (state.layoutType === "definitionList" && state.spanningLayout &&
stream.match(RE("definitionListEnd"), false))
state.spanningLayout = false;
}
function handlePhraseModifier(stream, state, ch) {
if (ch === "_") {
if (stream.eat("_"))
return togglePhraseModifier(stream, state, "italic", /__/, 2);
else
return togglePhraseModifier(stream, state, "em", /_/, 1);
}
if (ch === "*") {
if (stream.eat("*")) {
return togglePhraseModifier(stream, state, "bold", /\*\*/, 2);
}
return togglePhraseModifier(stream, state, "strong", /\*/, 1);
}
if (ch === "[") {
if (stream.match(/\d+\]/)) state.footCite = true;
return tokenStyles(state);
}
if (ch === "(") {
var spec = stream.match(/^(r|tm|c)\)/);
if (spec)
return tokenStylesWith(state, TOKEN_STYLES.specialChar);
}
if (ch === "<" && stream.match(/(\w+)[^>]+>[^<]+<\/\1>/))
return tokenStylesWith(state, TOKEN_STYLES.html);
if (ch === "?" && stream.eat("?"))
return togglePhraseModifier(stream, state, "cite", /\?\?/, 2);
if (ch === "=" && stream.eat("="))
return togglePhraseModifier(stream, state, "notextile", /==/, 2);
if (ch === "-" && !stream.eat("-"))
return togglePhraseModifier(stream, state, "deletion", /-/, 1);
if (ch === "+")
return togglePhraseModifier(stream, state, "addition", /\+/, 1);
if (ch === "~")
return togglePhraseModifier(stream, state, "sub", /~/, 1);
if (ch === "^")
return togglePhraseModifier(stream, state, "sup", /\^/, 1);
if (ch === "%")
return togglePhraseModifier(stream, state, "span", /%/, 1);
if (ch === "@")
return togglePhraseModifier(stream, state, "code", /@/, 1);
if (ch === "!") {
var type = togglePhraseModifier(stream, state, "image", /(?:\([^\)]+\))?!/, 1);
stream.match(/^:\S+/); // optional Url portion
return type;
}
return tokenStyles(state);
}
function togglePhraseModifier(stream, state, phraseModifier, closeRE, openSize) {
var charBefore = stream.pos > openSize ? stream.string.charAt(stream.pos - openSize - 1) : null;
var charAfter = stream.peek();
if (state[phraseModifier]) {
if ((!charAfter || /\W/.test(charAfter)) && charBefore && /\S/.test(charBefore)) {
var type = tokenStyles(state);
state[phraseModifier] = false;
return type;
}
} else if ((!charBefore || /\W/.test(charBefore)) && charAfter && /\S/.test(charAfter) &&
stream.match(new RegExp("^.*\\S" + closeRE.source + "(?:\\W|$)"), false)) {
state[phraseModifier] = true;
state.mode = Modes.attributes;
}
return tokenStyles(state);
};
function tokenStyles(state) {
var disabled = textileDisabled(state);
if (disabled) return disabled;
var styles = [];
if (state.layoutType) styles.push(TOKEN_STYLES[state.layoutType]);
styles = styles.concat(activeStyles(
state, "addition", "bold", "cite", "code", "deletion", "em", "footCite",
"image", "italic", "link", "span", "strong", "sub", "sup", "table", "tableHeading"));
if (state.layoutType === "header")
styles.push(TOKEN_STYLES.header + "-" + state.header);
return styles.length ? styles.join(" ") : null;
}
function textileDisabled(state) {
var type = state.layoutType;
switch(type) {
case "notextile":
case "code":
case "pre":
return TOKEN_STYLES[type];
default:
if (state.notextile)
return TOKEN_STYLES.notextile + (type ? (" " + TOKEN_STYLES[type]) : "");
return null;
}
}
function tokenStylesWith(state, extraStyles) {
var disabled = textileDisabled(state);
if (disabled) return disabled;
var type = tokenStyles(state);
if (extraStyles)
return type ? (type + " " + extraStyles) : extraStyles;
else
return type;
}
function activeStyles(state) {
var styles = [];
for (var i = 1; i < arguments.length; ++i) {
if (state[arguments[i]])
styles.push(TOKEN_STYLES[arguments[i]]);
}
return styles;
}
function blankLine(state) {
var spanningLayout = state.spanningLayout, type = state.layoutType;
for (var key in state) if (state.hasOwnProperty(key))
delete state[key];
state.mode = Modes.newLayout;
if (spanningLayout) {
state.layoutType = type;
state.spanningLayout = true;
}
}
var REs = {
cache: {},
single: {
bc: "bc",
bq: "bq",
definitionList: /- [^(?::=)]+:=+/,
definitionListEnd: /.*=:\s*$/,
div: "div",
drawTable: /\|.*\|/,
foot: /fn\d+/,
header: /h[1-6]/,
html: /\s*<(?:\/)?(\w+)(?:[^>]+)?>(?:[^<]+<\/\1>)?/,
link: /[^"]+":\S/,
linkDefinition: /\[[^\s\]]+\]\S+/,
list: /(?:#+|\*+)/,
notextile: "notextile",
para: "p",
pre: "pre",
table: "table",
tableCellAttributes: /[\/\\]\d+/,
tableHeading: /\|_\./,
tableText: /[^"_\*\[\(\?\+~\^%@|-]+/,
text: /[^!"_=\*\[\(<\?\+~\^%@-]+/
},
attributes: {
align: /(?:<>|<|>|=)/,
selector: /\([^\(][^\)]+\)/,
lang: /\[[^\[\]]+\]/,
pad: /(?:\(+|\)+){1,2}/,
css: /\{[^\}]+\}/
},
createRe: function(name) {
switch (name) {
case "drawTable":
return REs.makeRe("^", REs.single.drawTable, "$");
case "html":
return REs.makeRe("^", REs.single.html, "(?:", REs.single.html, ")*", "$");
case "linkDefinition":
return REs.makeRe("^", REs.single.linkDefinition, "$");
case "listLayout":
return REs.makeRe("^", REs.single.list, RE("allAttributes"), "*\\s+");
case "tableCellAttributes":
return REs.makeRe("^", REs.choiceRe(REs.single.tableCellAttributes,
RE("allAttributes")), "+\\.");
case "type":
return REs.makeRe("^", RE("allTypes"));
case "typeLayout":
return REs.makeRe("^", RE("allTypes"), RE("allAttributes"),
"*\\.\\.?", "(\\s+|$)");
case "attributes":
return REs.makeRe("^", RE("allAttributes"), "+");
case "allTypes":
return REs.choiceRe(REs.single.div, REs.single.foot,
REs.single.header, REs.single.bc, REs.single.bq,
REs.single.notextile, REs.single.pre, REs.single.table,
REs.single.para);
case "allAttributes":
return REs.choiceRe(REs.attributes.selector, REs.attributes.css,
REs.attributes.lang, REs.attributes.align, REs.attributes.pad);
default:
return REs.makeRe("^", REs.single[name]);
}
},
makeRe: function() {
var pattern = "";
for (var i = 0; i < arguments.length; ++i) {
var arg = arguments[i];
pattern += (typeof arg === "string") ? arg : arg.source;
}
return new RegExp(pattern);
},
choiceRe: function() {
var parts = [arguments[0]];
for (var i = 1; i < arguments.length; ++i) {
parts[i * 2 - 1] = "|";
parts[i * 2] = arguments[i];
}
parts.unshift("(?:");
parts.push(")");
return REs.makeRe.apply(null, parts);
}
};
function RE(name) {
return (REs.cache[name] || (REs.cache[name] = REs.createRe(name)));
}
var Modes = {
newLayout: function(stream, state) {
if (stream.match(RE("typeLayout"), false)) {
state.spanningLayout = false;
return (state.mode = Modes.blockType)(stream, state);
}
var newMode;
if (!textileDisabled(state)) {
if (stream.match(RE("listLayout"), false))
newMode = Modes.list;
else if (stream.match(RE("drawTable"), false))
newMode = Modes.table;
else if (stream.match(RE("linkDefinition"), false))
newMode = Modes.linkDefinition;
else if (stream.match(RE("definitionList")))
newMode = Modes.definitionList;
else if (stream.match(RE("html"), false))
newMode = Modes.html;
}
return (state.mode = (newMode || Modes.text))(stream, state);
},
blockType: function(stream, state) {
var match, type;
state.layoutType = null;
if (match = stream.match(RE("type")))
type = match[0];
else
return (state.mode = Modes.text)(stream, state);
if (match = type.match(RE("header"))) {
state.layoutType = "header";
state.header = parseInt(match[0][1]);
} else if (type.match(RE("bq"))) {
state.layoutType = "quote";
} else if (type.match(RE("bc"))) {
state.layoutType = "code";
} else if (type.match(RE("foot"))) {
state.layoutType = "footnote";
} else if (type.match(RE("notextile"))) {
state.layoutType = "notextile";
} else if (type.match(RE("pre"))) {
state.layoutType = "pre";
} else if (type.match(RE("div"))) {
state.layoutType = "div";
} else if (type.match(RE("table"))) {
state.layoutType = "table";
}
state.mode = Modes.attributes;
return tokenStyles(state);
},
text: function(stream, state) {
if (stream.match(RE("text"))) return tokenStyles(state);
var ch = stream.next();
if (ch === '"')
return (state.mode = Modes.link)(stream, state);
return handlePhraseModifier(stream, state, ch);
},
attributes: function(stream, state) {
state.mode = Modes.layoutLength;
if (stream.match(RE("attributes")))
return tokenStylesWith(state, TOKEN_STYLES.attributes);
else
return tokenStyles(state);
},
layoutLength: function(stream, state) {
if (stream.eat(".") && stream.eat("."))
state.spanningLayout = true;
state.mode = Modes.text;
return tokenStyles(state);
},
list: function(stream, state) {
var match = stream.match(RE("list"));
state.listDepth = match[0].length;
var listMod = (state.listDepth - 1) % 3;
if (!listMod)
state.layoutType = "list1";
else if (listMod === 1)
state.layoutType = "list2";
else
state.layoutType = "list3";
state.mode = Modes.attributes;
return tokenStyles(state);
},
link: function(stream, state) {
state.mode = Modes.text;
if (stream.match(RE("link"))) {
stream.match(/\S+/);
return tokenStylesWith(state, TOKEN_STYLES.link);
}
return tokenStyles(state);
},
linkDefinition: function(stream, state) {
stream.skipToEnd();
return tokenStylesWith(state, TOKEN_STYLES.linkDefinition);
},
definitionList: function(stream, state) {
stream.match(RE("definitionList"));
state.layoutType = "definitionList";
if (stream.match(/\s*$/))
state.spanningLayout = true;
else
state.mode = Modes.attributes;
return tokenStyles(state);
},
html: function(stream, state) {
stream.skipToEnd();
return tokenStylesWith(state, TOKEN_STYLES.html);
},
table: function(stream, state) {
state.layoutType = "table";
return (state.mode = Modes.tableCell)(stream, state);
},
tableCell: function(stream, state) {
if (stream.match(RE("tableHeading")))
state.tableHeading = true;
else
stream.eat("|");
state.mode = Modes.tableCellAttributes;
return tokenStyles(state);
},
tableCellAttributes: function(stream, state) {
state.mode = Modes.tableText;
if (stream.match(RE("tableCellAttributes")))
return tokenStylesWith(state, TOKEN_STYLES.attributes);
else
return tokenStyles(state);
},
tableText: function(stream, state) {
if (stream.match(RE("tableText")))
return tokenStyles(state);
if (stream.peek() === "|") { // end of cell
state.mode = Modes.tableCell;
return tokenStyles(state);
}
return handlePhraseModifier(stream, state, stream.next());
}
};
CodeMirror.defineMode("textile", function() {
return {
startState: function() {
return { mode: Modes.newLayout };
},
token: function(stream, state) {
if (stream.sol()) startNewLine(stream, state);
return state.mode(stream, state);
},
blankLine: blankLine
};
});
CodeMirror.defineMIME("text/x-textile", "textile");
});