diff --git a/BBCode.sublime-syntax b/BBCode.sublime-syntax index 5ddd8d3..10882c7 100644 --- a/BBCode.sublime-syntax +++ b/BBCode.sublime-syntax @@ -1,23 +1,35 @@ %YAML 1.2 --- # http://www.sublimetext.com/docs/3/syntax.html -name: BBCode -file_extensions: - - bbcode - - bb -scope: text.bbcode -contexts: +name : BBCode +file_extensions : [bbcode, bb] +scope : text.bbcode +version : 2 +contexts: # Naming Conventions # http://manual.macromates.com/en/language_grammars#naming_conventions.html main: - - include: languages + - include: embedded - include: anchors - - include: general_tags + - include: general-tags + embedded: + - include: embedded-pawn + - include: embedded-ruby + - include: embedded-html + - include: embedded-rhtml + - include: embedded-js + - include: embedded-css + - include: embedded-php + - include: embedded-python + - include: embedded-perl + - include: embedded-sql + - include: embedded-java + - include: embedded-c + - include: embedded-yaml anchors: - - match: '\[anchor\]' scope: meta.tag.any.bbcode push: @@ -26,180 +38,251 @@ contexts: scope: meta.tag.any.bbcode pop: true + general-tags: + - include: emphasis + - include: other-tags - general_tags: + emphasis: + - include: bold + - include: italic + - include: underline + - include: strikethrough - - match: '(\[[B|b]\])(.*?)(\[/[B|b]\])' - captures: - 1: meta.tag.any.bbcode - 2: markup.bold - 3: meta.tag.any.bbcode + other-tags: + - include: url + - include: value-tag - - match: '(\[[I|i]\])(.*?)(\[/[I|i]\])' - captures: - 1: meta.tag.any.bbcode - 2: markup.italic - 3: meta.tag.any.bbcode - - match: '(\[url=?(.*?)\])(.*?)(\[/url\])' + + bold: + - meta_include_prototype: false + - match: '\[[B|b]\]' + scope: meta.tag.any.bbcode + push : bold-body + bold-body: + - meta_scope: markup.bold + - match : '\[/[B|b]\]' + scope : meta.tag.any.bbcode + pop : 1 + - include: emphasis + + italic: + - meta_include_prototype: false + - match: '\[[I|i]\]' + scope: meta.tag.any.bbcode + push : italic-body + italic-body: + - meta_scope: markup.italic + - match : '\[/[I|i]\]' + scope : meta.tag.any.bbcode + pop : 1 + - include: emphasis + + underline: + - meta_include_prototype: false + - match: '\[[U|u]\]' + scope: meta.tag.any.bbcode + push : underline-body + underline-body: + - meta_scope: markup.underline + - match : '\[/[U|u]\]' + scope : meta.tag.any.bbcode + pop : 1 + - include: emphasis + + strikethrough: + - meta_include_prototype: false + - match: '\[[S|s]\]' + scope: meta.tag.any.bbcode + push : strikethrough-body + strikethrough-body: + - meta_scope: markup.strikethrough + - match : '\[/[S|s]\]' + scope : meta.tag.any.bbcode + pop : 1 + - include: emphasis + + + url: + - meta_include_prototype: false + - match: '\[url=?(.*?)\]' captures: 1: meta.tag.any.bbcode 2: meta.tag.value.bbcode - 3: markup.underline - 4: meta.tag.any.bbcode + push : url-body + url-body: + - meta_scope: markup.underline + - match : '\[/url\]' + scope : meta.tag.any.bbcode + pop : 1 - - match: '\[/?[^\]=]*\]' - scope: meta.tag.any.bbcode + value-tag: + - meta_include_prototype: false - match: '\[.*?=(.*?)\]' - captures: + captures : 0: meta.tag.any.bbcode 1: meta.tag.value.bbcode + push : value-tag-body + value-tag-body: + - match : '\[/?[^\]=]*\]' + scope: meta.tag.any.bbcode + pop : 1 - languages: + embedded-pawn: + - meta_include_prototype: false - match: '(?i)\[(pawn|html|code|php)\]' captures: 0: meta.tag.code.pawn.bbcode - push: - - meta_scope: source.pawn.embedded.bbcode - - match: '(?i)\[/(pawn|html|code|php)\]' - captures: - 0: meta.tag.code.pawn.bbcode - pop: true - - include: scope:source.AmxxPawn source.sma - + embed: scope:source.AmxxPawn source.sma + embed_scope: + source.pawn.embedded.bbcode + source.pawn + escape: '(?i)\[/(pawn|html|code|php)\]' + escape_captures: + 0: meta.tag.code.pawn.bbcode + embedded-ruby: + - meta_include_prototype: false - match: '\[code=ruby\]' captures: 0: meta.tag.code.ruby.bbcode - push: - - meta_scope: source.ruby.embedded.bbcode - - match: '\[/code\]' - captures: - 0: meta.tag.code.ruby.bbcode - pop: true - - include: scope:source.ruby - + embed: scope:source.ruby + embed_scope: + source.ruby.embedded.bbcode + source.ruby + escape: '\[/code\]' + escape_captures: + 0: meta.tag.code.ruby.bbcode + embedded-html: + - meta_include_prototype: false - match: '\[code=html\]' captures: 0: meta.tag.code.html.bbcode - push: - - meta_scope: text.html.embedded.bbcode - - match: '\[/code\]' - captures: - 0: meta.tag.code.html.bbcode - pop: true - - include: scope:text.html.basic - + embed: scope:text.html.basic + embed_scope: + text.html.embedded.bbcode + text.html.basic + escape: '\[/code\]' + escape_captures: + 0: meta.tag.code.html.bbcode + embedded-rhtml: + - meta_include_prototype: false - match: '\[code=rhtml\]' captures: 0: meta.tag.code.rhtml.bbcode - push: - - meta_scope: text.rhtml.embedded.bbcode - - match: '\[/code\]' - captures: - 0: meta.tag.code.rhtml.bbcode - pop: true - - include: scope:text.html.ruby - + embed: scope:text.html.ruby + embed_scope: + text.rhtml.embedded.bbcode + text.html.ruby + escape: '\[/code\]' + escape_captures: + 0: meta.tag.code.rhtml.bbcode + embedded-js: + - meta_include_prototype: false - match: '\[code=(js|javascript)\]' captures: 0: meta.tag.code.js.bbcode - push: - - meta_scope: source.js.embedded.bbcode - - match: '\[/code\]' - captures: - 0: meta.tag.code.js.bbcode - pop: true - - include: scope:source.js - + embed: scope:source.js + embed_scope: + source.js.embedded.bbcode + source.js + escape: '\[/code\]' + escape_captures: + 0: meta.tag.code.js.bbcode + embedded-css: + - meta_include_prototype: false - match: '\[code=(css|stylesheet)\]' captures: 0: meta.tag.code.css.bbcode - push: - - meta_scope: source.css.embedded.bbcode - - match: '\[/code\]' - captures: - 0: meta.tag.code.css.bbcode - pop: true - - include: scope:source.css - + embed: scope:source.css + embed_scope: + source.css.embedded.bbcode + source.css + escape: '\[/code\]' + escape_captures: + 0: meta.tag.code.css.bbcode + embedded-php: + - meta_include_prototype: false - match: '\[code=php\]' captures: 0: meta.tag.code.php.bbcode - push: - - meta_scope: source.php.embedded.bbcode - - match: '\[/code\]' - captures: - 0: meta.tag.code.php.bbcode - pop: true - - include: scope:source.php - + embed: scope:source.php + embed_scope: + source.php.embedded.bbcode + source.php + escape: '\[/code\]' + escape_captures: + 0: meta.tag.code.php.bbcode + embedded-python: + - meta_include_prototype: false - match: '\[code=python\]' captures: 0: meta.tag.code.python.bbcode - push: - - meta_scope: source.python.embedded.bbcode - - match: '\[/code\]' - captures: - 0: meta.tag.code.python.bbcode - pop: true - - include: scope:source.python - + embed: scope:source.python + embed_scope: + source.python.embedded.bbcode + source.python + escape: '\[/code\]' + escape_captures: + 0: meta.tag.code.python.bbcode + embedded-perl: + - meta_include_prototype: false - match: '\[code=perl\]' captures: 0: meta.tag.code.perl.bbcode - push: - - meta_scope: source.perl.embedded.bbcode - - match: '\[/code\]' - captures: - 0: meta.tag.code.perl.bbcode - pop: true - - include: scope:source.perl - + embed: scope:source.perl + embed_scope: + source.perl.embedded.bbcode + source.perl + escape: '\[/code\]' + escape_captures: + 0: meta.tag.code.perl.bbcode + embedded-sql: + - meta_include_prototype: false - match: '\[code=sql\]' captures: 0: meta.tag.code.sql.bbcode - push: - - meta_scope: source.sql.embedded.bbcode - - match: '\[/code\]' - captures: - 0: meta.tag.code.sql.bbcode - pop: true - - include: scope:source.sql - + embed: scope:source.sql + embed_scope: + source.sql.embedded.bbcode + source.sql + escape: '\[/code\]' + escape_captures: + 0: meta.tag.code.sql.bbcode + embedded-java: + - meta_include_prototype: false - match: '\[code=java\]' captures: 0: meta.tag.code.java.bbcode - push: - - meta_scope: source.java.embedded.bbcode - - match: '\[/code\]' - captures: - 0: meta.tag.code.java.bbcode - pop: true - - include: scope:source.java - + embed: scope:source.java + embed_scope: + source.java.embedded.bbcode + source.java + escape: '\[/code\]' + escape_captures: + 0: meta.tag.code.java.bbcode + embedded-c: + - meta_include_prototype: false - match: '\[code=c\]' captures: 0: meta.tag.code.c.bbcode - push: - - meta_scope: source.c.embedded.bbcode - - match: '\[/code\]' - captures: - 0: meta.tag.code.c.bbcode - pop: true - - include: scope:source.c - + embed: scope:source.c + embed_scope: + source.c.embedded.bbcode + source.c + escape: '\[/code\]' + escape_captures: + 0: meta.tag.code.c.bbcode + embedded-yaml: + - meta_include_prototype: false - match: '\[code=yaml\]' captures: 0: meta.tag.code.yaml.bbcode - push: - - meta_scope: source.yaml.embedded.bbcode - - match: '\[/code\]' - captures: - 0: meta.tag.code.yaml.bbcode - pop: true - - include: scope:source.yaml - - - + embed: scope:source.yaml + embed_scope: + source.yaml.embedded.bbcode + source.yaml + escape: '\[/code\]' + escape_captures: + 0: meta.tag.code.yaml.bbcode diff --git a/Default (OSX).sublime-keymap b/Default (OSX).sublime-keymap index 7f0cd90..8f10949 100644 --- a/Default (OSX).sublime-keymap +++ b/Default (OSX).sublime-keymap @@ -1,7 +1,114 @@ [ - { "keys": ["super+ctrl+b"], "command": "insert_snippet", "args": {"name": "Packages/BBCode Syntax/Bold.sublime-snippet"} }, - { "keys": ["super+ctrl+c"], "command": "insert_snippet", "args": {"name": "Packages/BBCode Syntax/Color.sublime-snippet"} }, - { "keys": ["super+ctrl+i"], "command": "insert_snippet", "args": {"name": "Packages/BBCode Syntax/Italic.sublime-snippet"} }, - { "keys": ["super+ctrl+2"], "command": "insert_snippet", "args": {"name": "Packages/BBCode Syntax/Size.sublime-snippet"} }, - { "keys": ["super+ctrl+w"], "command": "insert_snippet", "args": {"name": "Packages/BBCode Syntax/Wrap.sublime-snippet"} } +// BUG: preceding_text/following_text selectors fail since 'selection' is included, so can't reliably parse @ the start/end + // https://github.com/sublimehq/sublime_text/issues/4042 +// // [BBCode] Text Formatting Bold +// // auto-pair if not within a word +// {"keys":["super+b"], "command":"insert_snippet","args":{"name":"Packages/BBCode/Bold.sublime-snippet"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - markup.bold - markup.bold_italic - meta.tag.any.bbcode", "match_all":true }, +// {"key":"selection_empty", "operator":"equal", "operand":true, "match_all":true }, +// {"key":"eol_selector", "operator":"not_equal", "operand":"string.quoted.single", "match_all":true }, +// {"key":"preceding_text", "operator":"not_regex_contains", "operand":"['a-zA-Z0-9_*]$", "match_all":true }, +// {"key":"following_text", "operator":"regex_contains", "operand":"^(?:\t| |\\)|]|\\}|$)", "match_all":true } ]}, +// // Bold on Cmd + B (if caret is at the beginning, in the middle of or at the end of a word) +// {"keys":["super+b"], "command":"run_macro_file","args":{"file":"Packages/BBCode/macro/Transform Word - Bold.sublime-macro"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - markup.bold - markup.bold_italic - meta.tag.any.bbcode", "match_all":true }, +// {"key":"selection_empty", "operator":"equal", "operand":true, "match_all":true }, +// {"key":"preceding_text", "operator":"regex_contains", "operand":"\\w$", "match_all":true } ]}, +// {"keys":["super+b"], "command":"run_macro_file","args":{"file":"Packages/BBCode/macro/Transform Word - Bold.sublime-macro"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - markup.bold - markup.bold_italic - meta.tag.any.bbcode", "match_all":true }, +// {"key":"selection_empty", "operator":"equal", "operand":true, "match_all":true }, +// {"key":"following_text", "operator":"regex_contains", "operand":"^\\w", "match_all":true } ]}, +// // Transform selection to bold +// {"keys":["super+b"], "command":"insert_snippet","args":{"name":"Packages/BBCode/Bold.sublime-snippet"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - markup.bold - markup.bold_italic - meta.tag.any.bbcode", "match_all":true }, +// {"key":"selection_empty", "operator":"equal", "operand":false, "match_all":true }, +// {"key":"preceding_text", "operator":"not_regex_contains", "operand":"\\[b\\]$", "match_all":true }, +// {"key":"following_text", "operator":"not_regex_contains", "operand":"^\\[\\/b\\]", "match_all":true } ]}, +// // Unbold on Cmd + B if already bold +// {"keys":["super+b"], "command":"run_macro_file","args":{"file":"Packages/BBCode/macro/Transform Word - UnBold.sublime-macro"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode markup.bold - punctuation, text.bbcode markup.bold_italic - punctuation", "match_all":true } ]}, + +// // [BBCode] Text Formatting Italic +// // auto-pair if not within a word +// {"keys":["super+i"], "command":"insert_snippet","args":{"name":"Packages/BBCode/Italic.sublime-snippet"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - markup.italic - markup.bold_italic - meta.tag.any.bbcode", "match_all":true }, +// {"key":"selection_empty", "operator":"equal", "operand":true, "match_all":true }, +// {"key":"eol_selector", "operator":"not_equal", "operand":"string.quoted.single", "match_all":true }, +// {"key":"preceding_text", "operator":"not_regex_contains", "operand":"['a-zA-Z0-9_*]$", "match_all":true }, +// {"key":"following_text", "operator":"regex_contains", "operand":"^(?:\t| |\\)|]|\\}|$)", "match_all":true } ]}, +// // Italics on Cmd + I (if caret is at the beginning, in the middle of or at the end of a word) +// {"keys":["super+i"], "command":"run_macro_file","args":{"file":"Packages/BBCode/macro/Transform Word - Italic.sublime-macro"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - markup.italic - markup.bold_italic - meta.tag.any.bbcode", "match_all":true }, +// {"key":"selection_empty", "operator":"equal", "operand":true, "match_all":true }, +// {"key":"preceding_text", "operator":"regex_contains", "operand":"\\w$", "match_all":true } ]}, +// {"keys":["super+i"], "command":"run_macro_file","args":{"file":"Packages/BBCode/macro/Transform Word - Italic.sublime-macro"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - markup.italic - markup.bold_italic - meta.tag.any.bbcode", "match_all":true }, +// {"key":"selection_empty", "operator":"equal", "operand":true, "match_all":true }, +// {"key":"following_text", "operator":"regex_contains", "operand":"^\\w", "match_all":true } ]}, +// // Unitalicize on Cmd + I if already italic +// {"keys":["super+i"], "command":"insert_snippet","args":{"name":"Packages/BBCode/Italic.sublime-snippet"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - markup.italic - markup.bold_italic - meta.tag.any.bbcode", "match_all":true }, +// {"key":"selection_empty", "operator":"equal", "operand":false, "match_all":true }, +// {"key":"preceding_text", "operator":"not_regex_contains", "operand":"\\[i\\]$", "match_all":true }, +// {"key":"following_text", "operator":"not_regex_contains", "operand":"^\\[\\/i\\]", "match_all":true } ]}, +// {"keys":["super+i"], "command":"run_macro_file","args":{"file":"Packages/BBCode/macro/Transform Word - UnItalicize.sublime-macro"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode markup.italic - punctuation, text.bbcode markup.bold_italic - punctuation", "match_all":true } ]}, + +// // [BBCode] Text Formatting Other: wrap, color, size tags +// // Wrap: auto-pair if outside a word +// {"keys":["super+ctrl+w"], "command":"insert_snippet","args":{"name":"Packages/BBCode/Wrap.sublime-snippet"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - meta.tag.any.bbcode", "match_all":true}, +// {"key":"selection_empty", "operator":"equal", "operand":true, "match_all":true}, +// {"key":"eol_selector", "operator":"not_equal", "operand":"string.quoted.single", "match_all":true}, +// {"key":"preceding_text", "operator":"not_regex_contains", "operand":"['a-zA-Z0-9_*]$", "match_all":true}, +// {"key":"following_text", "operator":"regex_contains", "operand":"^(?:\t| |\\)|]|\\}|$)", "match_all":true} ]}, +// // Wrap if caret is @ word's beginning/middle/end +// {"keys":["super+ctrl+w"], "command":"run_macro_file","args":{"file":"Packages/BBCode/macro/Transform Word - Wrap.sublime-macro"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - meta.tag.any.bbcode", "match_all":true}, +// {"key":"selection_empty", "operator":"equal", "operand":true, "match_all":true}, +// {"key":"preceding_text", "operator":"regex_contains", "operand":"\\w$", "match_all":true} ]}, +// // Wrap selection +// {"keys":["super+ctrl+b"], "command":"insert_snippet","args":{"name":"Packages/BBCode/Wrap.sublime-snippet"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - meta.tag.any.bbcode", "match_all":true}, +// {"key":"selection_empty", "operator":"equal", "operand":false, "match_all":true}, +// {"key":"preceding_text", "operator":"not_regex_contains", "operand":"\\[\\w\\]$", "match_all":true}, +// {"key":"following_text", "operator":"not_regex_contains", "operand":"^\\[\\/\\w\\]", "match_all":true} ]}, + +// // Color: auto-pair if outside a word +// {"keys":["super+ctrl+c"], "command":"insert_snippet","args":{"name":"Packages/BBCode/Color.sublime-snippet"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - meta.tag.any.bbcode", "match_all":true}, +// {"key":"selection_empty", "operator":"equal", "operand":true, "match_all":true}, +// {"key":"eol_selector", "operator":"not_equal", "operand":"string.quoted.single", "match_all":true}, +// {"key":"preceding_text", "operator":"not_regex_contains", "operand":"['a-zA-Z0-9_*]$", "match_all":true}, +// {"key":"following_text", "operator":"regex_contains", "operand":"^(?:\t| |\\)|]|\\}|$)", "match_all":true} ]}, +// // Color if caret is @ word's beginning/middle/end +// {"keys":["super+ctrl+c"], "command":"run_macro_file","args":{"file":"Packages/BBCode/macro/Transform Word - Color.sublime-macro"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - meta.tag.any.bbcode", "match_all":true}, +// {"key":"selection_empty", "operator":"equal", "operand":true, "match_all":true}, +// {"key":"preceding_text", "operator":"regex_contains", "operand":"\\w$", "match_all":true} ]}, +// // Color selection +// {"keys":["super+ctrl+c"], "command":"insert_snippet","args":{"name":"Packages/BBCode/Color.sublime-snippet"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - meta.tag.any.bbcode", "match_all":true}, +// {"key":"selection_empty", "operator":"equal", "operand":false, "match_all":true}, +// {"key":"preceding_text", "operator":"not_regex_contains", "operand":"\\[\\w\\]$", "match_all":true}, +// {"key":"following_text", "operator":"not_regex_contains", "operand":"^\\[\\/\\w\\]", "match_all":true} ]}, + +// // Size: auto-pair if outside a word +// {"keys":["super+ctrl+2"], "command":"insert_snippet","args":{"name":"Packages/BBCode/Size.sublime-snippet"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - meta.tag.any.bbcode", "match_all":true}, +// {"key":"selection_empty", "operator":"equal", "operand":true, "match_all":true}, +// {"key":"eol_selector", "operator":"not_equal", "operand":"string.quoted.single", "match_all":true}, +// {"key":"preceding_text", "operator":"not_regex_contains", "operand":"['a-zA-Z0-9_*]$", "match_all":true}, +// {"key":"following_text", "operator":"regex_contains", "operand":"^(?:\t| |\\)|]|\\}|$)", "match_all":true} ]}, +// // Size if caret is @ word's beginning/middle/end +// {"keys":["super+ctrl+2"], "command":"run_macro_file","args":{"file":"Packages/BBCode/macro/Transform Word - Size.sublime-macro"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - meta.tag.any.bbcode", "match_all":true}, +// {"key":"selection_empty", "operator":"equal", "operand":true, "match_all":true}, +// {"key":"preceding_text", "operator":"regex_contains", "operand":"\\w$", "match_all":true} ]}, +// // Size selection +// {"keys":["super+ctrl+2"], "command":"insert_snippet","args":{"name":"Packages/BBCode/Size.sublime-snippet"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - meta.tag.any.bbcode", "match_all":true}, +// {"key":"selection_empty", "operator":"equal", "operand":false, "match_all":true}, +// {"key":"preceding_text", "operator":"not_regex_contains", "operand":"\\[\\w\\]$", "match_all":true}, +// {"key":"following_text", "operator":"not_regex_contains", "operand":"^\\[\\/\\w\\]", "match_all":true} ]}, ] diff --git a/Default (Windows).sublime-keymap b/Default (Windows).sublime-keymap index 4c9fa8c..838b0f5 100644 --- a/Default (Windows).sublime-keymap +++ b/Default (Windows).sublime-keymap @@ -1,7 +1,114 @@ [ - // { "keys": ["ctrl+shift+b"], "command": "insert_snippet", "args": {"name": "Packages/BBCode/Bold.sublime-snippet"} }, - // { "keys": ["ctrl+shift+c"], "command": "insert_snippet", "args": {"name": "Packages/BBCode/Color.sublime-snippet"} }, - // { "keys": ["ctrl+shift+i"], "command": "insert_snippet", "args": {"name": "Packages/BBCode/Italic.sublime-snippet"} }, - // { "keys": ["ctrl+shift+2"], "command": "insert_snippet", "args": {"name": "Packages/BBCode/Size.sublime-snippet"} }, - // { "keys": ["ctrl+shift+w"], "command": "insert_snippet", "args": {"name": "Packages/BBCode/Wrap.sublime-snippet"} } +// BUG: preceding_text/following_text selectors fail since 'selection' is included, so can't reliably parse @ the start/end + // https://github.com/sublimehq/sublime_text/issues/4042 +// // [BBCode] Text Formatting Bold +// // auto-pair if not within a word +// {"keys":["ctrl+b"], "command":"insert_snippet","args":{"name":"Packages/BBCode/Bold.sublime-snippet"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - markup.bold - markup.bold_italic - meta.tag.any.bbcode", "match_all":true }, +// {"key":"selection_empty", "operator":"equal", "operand":true, "match_all":true }, +// {"key":"eol_selector", "operator":"not_equal", "operand":"string.quoted.single", "match_all":true }, +// {"key":"preceding_text", "operator":"not_regex_contains", "operand":"['a-zA-Z0-9_*]$", "match_all":true }, +// {"key":"following_text", "operator":"regex_contains", "operand":"^(?:\t| |\\)|]|\\}|$)", "match_all":true } ]}, +// // Bold on Ctrl + B (if caret is at the beginning, in the middle of or at the end of a word) +// {"keys":["ctrl+b"], "command":"run_macro_file","args":{"file":"Packages/BBCode/macro/Transform Word - Bold.sublime-macro"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - markup.bold - markup.bold_italic - meta.tag.any.bbcode", "match_all":true }, +// {"key":"selection_empty", "operator":"equal", "operand":true, "match_all":true }, +// {"key":"preceding_text", "operator":"regex_contains", "operand":"\\w$", "match_all":true } ]}, +// {"keys":["ctrl+b"], "command":"run_macro_file","args":{"file":"Packages/BBCode/macro/Transform Word - Bold.sublime-macro"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - markup.bold - markup.bold_italic - meta.tag.any.bbcode", "match_all":true }, +// {"key":"selection_empty", "operator":"equal", "operand":true, "match_all":true }, +// {"key":"following_text", "operator":"regex_contains", "operand":"^\\w", "match_all":true } ]}, +// // Transform selection to bold +// {"keys":["ctrl+b"], "command":"insert_snippet","args":{"name":"Packages/BBCode/Bold.sublime-snippet"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - markup.bold - markup.bold_italic - meta.tag.any.bbcode", "match_all":true }, +// {"key":"selection_empty", "operator":"equal", "operand":false, "match_all":true }, +// {"key":"preceding_text", "operator":"not_regex_contains", "operand":"\\[b\\]$", "match_all":true }, +// {"key":"following_text", "operator":"not_regex_contains", "operand":"^\\[\\/b\\]", "match_all":true } ]}, +// // Unbold on Ctrl + B if already bold +// {"keys":["ctrl+b"], "command":"run_macro_file","args":{"file":"Packages/BBCode/macro/Transform Word - UnBold.sublime-macro"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode markup.bold - punctuation, text.bbcode markup.bold_italic - punctuation", "match_all":true } ]}, + +// // [BBCode] Text Formatting Italic +// // auto-pair if not within a word +// {"keys":["ctrl+i"], "command":"insert_snippet","args":{"name":"Packages/BBCode/Italic.sublime-snippet"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - markup.italic - markup.bold_italic - meta.tag.any.bbcode", "match_all":true }, +// {"key":"selection_empty", "operator":"equal", "operand":true, "match_all":true }, +// {"key":"eol_selector", "operator":"not_equal", "operand":"string.quoted.single", "match_all":true }, +// {"key":"preceding_text", "operator":"not_regex_contains", "operand":"['a-zA-Z0-9_*]$", "match_all":true }, +// {"key":"following_text", "operator":"regex_contains", "operand":"^(?:\t| |\\)|]|\\}|$)", "match_all":true } ]}, +// // Italics on Ctrl + I (if caret is at the beginning, in the middle of or at the end of a word) +// {"keys":["ctrl+i"], "command":"run_macro_file","args":{"file":"Packages/BBCode/macro/Transform Word - Italic.sublime-macro"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - markup.italic - markup.bold_italic - meta.tag.any.bbcode", "match_all":true }, +// {"key":"selection_empty", "operator":"equal", "operand":true, "match_all":true }, +// {"key":"preceding_text", "operator":"regex_contains", "operand":"\\w$", "match_all":true } ]}, +// {"keys":["ctrl+i"], "command":"run_macro_file","args":{"file":"Packages/BBCode/macro/Transform Word - Italic.sublime-macro"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - markup.italic - markup.bold_italic - meta.tag.any.bbcode", "match_all":true }, +// {"key":"selection_empty", "operator":"equal", "operand":true, "match_all":true }, +// {"key":"following_text", "operator":"regex_contains", "operand":"^\\w", "match_all":true } ]}, +// // Unitalicize on Ctrl + I if already italic +// {"keys":["ctrl+i"], "command":"insert_snippet","args":{"name":"Packages/BBCode/Italic.sublime-snippet"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - markup.italic - markup.bold_italic - meta.tag.any.bbcode", "match_all":true }, +// {"key":"selection_empty", "operator":"equal", "operand":false, "match_all":true }, +// {"key":"preceding_text", "operator":"not_regex_contains", "operand":"\\[i\\]$", "match_all":true }, +// {"key":"following_text", "operator":"not_regex_contains", "operand":"^\\[\\/i\\]", "match_all":true } ]}, +// {"keys":["ctrl+i"], "command":"run_macro_file","args":{"file":"Packages/BBCode/macro/Transform Word - UnItalicize.sublime-macro"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode markup.italic - punctuation, text.bbcode markup.bold_italic - punctuation", "match_all":true } ]}, + +// // [BBCode] Text Formatting Other: wrap, color, size tags +// // Wrap: auto-pair if outside a word +// {"keys":["shift+ctrl+w"], "command":"insert_snippet","args":{"name":"Packages/BBCode/Wrap.sublime-snippet"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - meta.tag.any.bbcode", "match_all":true}, +// {"key":"selection_empty", "operator":"equal", "operand":true, "match_all":true}, +// {"key":"eol_selector", "operator":"not_equal", "operand":"string.quoted.single", "match_all":true}, +// {"key":"preceding_text", "operator":"not_regex_contains", "operand":"['a-zA-Z0-9_*]$", "match_all":true}, +// {"key":"following_text", "operator":"regex_contains", "operand":"^(?:\t| |\\)|]|\\}|$)", "match_all":true} ]}, +// // Wrap if caret is @ word's beginning/middle/end +// {"keys":["shift+ctrl+w"], "command":"run_macro_file","args":{"file":"Packages/BBCode/macro/Transform Word - Wrap.sublime-macro"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - meta.tag.any.bbcode", "match_all":true}, +// {"key":"selection_empty", "operator":"equal", "operand":true, "match_all":true}, +// {"key":"preceding_text", "operator":"regex_contains", "operand":"\\w$", "match_all":true} ]}, +// // Wrap selection +// {"keys":["shift+ctrl+b"], "command":"insert_snippet","args":{"name":"Packages/BBCode/Wrap.sublime-snippet"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - meta.tag.any.bbcode", "match_all":true}, +// {"key":"selection_empty", "operator":"equal", "operand":false, "match_all":true}, +// {"key":"preceding_text", "operator":"not_regex_contains", "operand":"\\[\\w\\]$", "match_all":true}, +// {"key":"following_text", "operator":"not_regex_contains", "operand":"^\\[\\/\\w\\]", "match_all":true} ]}, + +// // Color: auto-pair if outside a word +// {"keys":["shift+ctrl+c"], "command":"insert_snippet","args":{"name":"Packages/BBCode/Color.sublime-snippet"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - meta.tag.any.bbcode", "match_all":true}, +// {"key":"selection_empty", "operator":"equal", "operand":true, "match_all":true}, +// {"key":"eol_selector", "operator":"not_equal", "operand":"string.quoted.single", "match_all":true}, +// {"key":"preceding_text", "operator":"not_regex_contains", "operand":"['a-zA-Z0-9_*]$", "match_all":true}, +// {"key":"following_text", "operator":"regex_contains", "operand":"^(?:\t| |\\)|]|\\}|$)", "match_all":true} ]}, +// // Color if caret is @ word's beginning/middle/end +// {"keys":["shift+ctrl+c"], "command":"run_macro_file","args":{"file":"Packages/BBCode/macro/Transform Word - Color.sublime-macro"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - meta.tag.any.bbcode", "match_all":true}, +// {"key":"selection_empty", "operator":"equal", "operand":true, "match_all":true}, +// {"key":"preceding_text", "operator":"regex_contains", "operand":"\\w$", "match_all":true} ]}, +// // Color selection +// {"keys":["shift+ctrl+c"], "command":"insert_snippet","args":{"name":"Packages/BBCode/Color.sublime-snippet"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - meta.tag.any.bbcode", "match_all":true}, +// {"key":"selection_empty", "operator":"equal", "operand":false, "match_all":true}, +// {"key":"preceding_text", "operator":"not_regex_contains", "operand":"\\[\\w\\]$", "match_all":true}, +// {"key":"following_text", "operator":"not_regex_contains", "operand":"^\\[\\/\\w\\]", "match_all":true} ]}, + +// // Size: auto-pair if outside a word +// {"keys":["shift+ctrl+2"], "command":"insert_snippet","args":{"name":"Packages/BBCode/Size.sublime-snippet"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - meta.tag.any.bbcode", "match_all":true}, +// {"key":"selection_empty", "operator":"equal", "operand":true, "match_all":true}, +// {"key":"eol_selector", "operator":"not_equal", "operand":"string.quoted.single", "match_all":true}, +// {"key":"preceding_text", "operator":"not_regex_contains", "operand":"['a-zA-Z0-9_*]$", "match_all":true}, +// {"key":"following_text", "operator":"regex_contains", "operand":"^(?:\t| |\\)|]|\\}|$)", "match_all":true} ]}, +// // Size if caret is @ word's beginning/middle/end +// {"keys":["shift+ctrl+2"], "command":"run_macro_file","args":{"file":"Packages/BBCode/macro/Transform Word - Size.sublime-macro"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - meta.tag.any.bbcode", "match_all":true}, +// {"key":"selection_empty", "operator":"equal", "operand":true, "match_all":true}, +// {"key":"preceding_text", "operator":"regex_contains", "operand":"\\w$", "match_all":true} ]}, +// // Size selection +// {"keys":["shift+ctrl+2"], "command":"insert_snippet","args":{"name":"Packages/BBCode/Size.sublime-snippet"},"context":[ +// {"key":"selector", "operator":"equal", "operand":"text.bbcode - meta.tag.any.bbcode", "match_all":true}, +// {"key":"selection_empty", "operator":"equal", "operand":false, "match_all":true}, +// {"key":"preceding_text", "operator":"not_regex_contains", "operand":"\\[\\w\\]$", "match_all":true}, +// {"key":"following_text", "operator":"not_regex_contains", "operand":"^\\[\\/\\w\\]", "match_all":true} ]}, ] diff --git a/README.md b/README.md index 79acc8d..f01c6d4 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,15 @@ This is a fork of the [TextMate BBCode Bundle][1] by [Ryan Bates][2], Michael Di ## Snippet Keybindings +Keybindings are disabled by default, copy&uncomment the keybinds you need from the [Default (Windows).sublime-keymap](<./Default (Windows).sublime-keymap>) and [Default (OSX).sublime-keymap](<./Default (OSX).sublime-keymap>) files to your own keymap + +Use `Cmd` on OS X and `Ctrl` on other platforms. + + B Bold/UnBold + I Italic/UnItalicize + Use `Cmd+Ctrl` on OS X and `Ctrl+Shift` on other platforms. - B Bold - I Italic C Color @ Size W Wrap (in arbitrary tag) @@ -23,3 +28,23 @@ Use `Cmd+Ctrl` on OS X and `Ctrl+Shift` on other platforms. 1 ordered list block * unordered list block - list item + +## Color scheme + +You might want to add the settings below to your `.sublime-color-scheme` file to correctly highlight nested emphasized scopes (change the colors to whatever fits your theme) + +```json +"variables" :{ + "black3" : "hsl( 0, 0%, 3%)", + "grey_base" : "hsl( 0, 0%, 50%)", +} +"rules" : [ + {"name":"||<-- Language: BBCode -->||" }, + {"name":"BBCode: Punctuation Separator (B/I/U/S)" ,"foreground":"color(var(grey_base) alpha(5))","font_style":"regular" ,"scope":"meta.tag.any.bbcode" }, + {"name":"BBCode: Bold+Italic" ,"foreground":"var(black3)" ,"font_style":"italic bold" ,"scope":"markup.bold && markup.italic" }, + {"name":"BBCode: Bold+ +Underline" ,"foreground":"var(black3)" ,"font_style":" bold underline" ,"scope":"markup.bold && markup.underline" }, + {"name":"BBCode: Italic+Underline" ,"foreground":"var(black3)" ,"font_style":"italic underline" ,"scope":" markup.italic && markup.underline" }, + {"name":"BBCode: Bold+Italic+Underline" ,"foreground":"var(black3)" ,"font_style":"italic bold underline" ,"scope":"markup.bold && markup.italic && markup.underline" }, + {"name":"BBCode: Bold+Italic+Underline+Strikethrough" ,"foreground":"var(black3)" ,"font_style":"italic bold underline strikethrough" ,"scope":"markup.bold && markup.italic && markup.underline && markup.strikethrough" }, +] +``` diff --git a/Size.sublime-snippet b/Size.sublime-snippet index f1d2668..338839b 100644 --- a/Size.sublime-snippet +++ b/Size.sublime-snippet @@ -1,5 +1,5 @@ - + Size text.bbcode diff --git a/macro/Transform Word - Bold.sublime-macro b/macro/Transform Word - Bold.sublime-macro new file mode 100644 index 0000000..0f818c5 --- /dev/null +++ b/macro/Transform Word - Bold.sublime-macro @@ -0,0 +1,5 @@ +[ +{"command":"expand_selection" ,"args":{"to":"word"}}, +{"command":"insert_snippet" ,"args":{"contents":"[b]${1:$SELECTION}[/b]"}}, +// [­b]BOLD TEXT[­/b] will display BOLD TEXT can escape with unprintable char (soft hyphen here after [) +] diff --git a/macro/Transform Word - Color.sublime-macro b/macro/Transform Word - Color.sublime-macro new file mode 100644 index 0000000..3313e67 --- /dev/null +++ b/macro/Transform Word - Color.sublime-macro @@ -0,0 +1,4 @@ +[ +{"command":"expand_selection" ,"args":{"to":"word"}}, +{"command":"insert_snippet" ,"args":{"name":"Packages/BBCode/Color.sublime-snippet"}}, +] diff --git a/macro/Transform Word - Italic.sublime-macro b/macro/Transform Word - Italic.sublime-macro new file mode 100644 index 0000000..2341bd0 --- /dev/null +++ b/macro/Transform Word - Italic.sublime-macro @@ -0,0 +1,5 @@ +[ +{"command":"expand_selection" ,"args":{"to":"word"}}, +{"command":"insert_snippet" ,"args":{"contents":"[i]${1:$SELECTION}[/i]"}}, +// [­i]ITALIC TEXT[­/i] will display ITALIC TEXT can escape with unprintable char (soft hyphen here after [) +] diff --git a/macro/Transform Word - Size.sublime-macro b/macro/Transform Word - Size.sublime-macro new file mode 100644 index 0000000..699eabb --- /dev/null +++ b/macro/Transform Word - Size.sublime-macro @@ -0,0 +1,4 @@ +[ +{"command":"expand_selection" ,"args":{"to":"word"}}, +{"command":"insert_snippet" ,"args":{"name":"Packages/BBCode/Size.sublime-snippet"}}, +] diff --git a/macro/Transform Word - UnBold.sublime-macro b/macro/Transform Word - UnBold.sublime-macro new file mode 100644 index 0000000..ab510b3 --- /dev/null +++ b/macro/Transform Word - UnBold.sublime-macro @@ -0,0 +1,4 @@ +[ +{"command":"expand_selection" ,"args":{"to":"scope"}}, +{"command":"insert_snippet" ,"args":{"contents":"${SELECTION/^\\[b\\]|\\[\\/b\\]$//g}"}}, +] diff --git a/macro/Transform Word - UnItalicize.sublime-macro b/macro/Transform Word - UnItalicize.sublime-macro new file mode 100644 index 0000000..235b3a9 --- /dev/null +++ b/macro/Transform Word - UnItalicize.sublime-macro @@ -0,0 +1,4 @@ +[ +{"command":"expand_selection" ,"args":{"to":"scope"}}, +{"command":"insert_snippet" ,"args":{"contents":"${SELECTION/^\\[i\\]|\\[\\/i\\]$//g}"}}, +] diff --git a/macro/Transform Word - Wrap.sublime-macro b/macro/Transform Word - Wrap.sublime-macro new file mode 100644 index 0000000..a3f6b3a --- /dev/null +++ b/macro/Transform Word - Wrap.sublime-macro @@ -0,0 +1,4 @@ +[ +{"command":"expand_selection" ,"args":{"to":"word"}}, +{"command":"insert_snippet" ,"args":{"name":"Packages/BBCode/Wrap.sublime-snippet"}}, +] diff --git a/test/syntax_test_BBCode.bb b/test/syntax_test_BBCode.bb new file mode 100644 index 0000000..a10e487 --- /dev/null +++ b/test/syntax_test_BBCode.bb @@ -0,0 +1,97 @@ +# SYNTAX TEST "Packages/BBCode/BBCode.sublime-syntax" + +# 1 Test overall source match +#^^^^^^^^^^^^^^^^^^^^^^^^^^^ text.bbcode + +# 2 Test emphases +[b]bold[/b] # +# <- meta.tag.any.bbcode +#^^ meta.tag.any.bbcode +# ^^^^ meta.tag.any.bbcode +# ^^^^ markup.bold +[i]italic[/i] # +# <- meta.tag.any.bbcode +#^^ meta.tag.any.bbcode +# ^^^^ meta.tag.any.bbcode +# ^^^^^^ markup.italic +[b][i]bolditalic[/i][/b] # nested emphasis +# <- meta.tag.any.bbcode +#^^^^^ meta.tag.any.bbcode +# ^^^^^^^^ meta.tag.any.bbcode +# ^^^^^^^^^^ markup.bold markup.italic +[i][b]italicbold[/b][/i] # nested emphasis +# <- meta.tag.any.bbcode +#^^^^ meta.tag.any.bbcode +# ^^^^^^^^ meta.tag.any.bbcode +# ^^^^^^^^^^ markup.italic markup.bold +[b]bold[i]bolditalic[/i]bold[/b] # nested emphasis +# <- meta.tag.any.bbcode +#^^ meta.tag.any.bbcode +# ^^^ meta.tag.any.bbcode +# ^^^^ meta.tag.any.bbcode +# ^^^^ meta.tag.any.bbcode +# ^^^^ markup.bold +# ^^^^ markup.bold +# ^^^^^^^^^^ markup.bold markup.italic +[i]italic[b]italicbold[/b]italic[/i] # nested emphasis +# <- meta.tag.any.bbcode +#^^ meta.tag.any.bbcode +# ^^^ meta.tag.any.bbcode +# ^^^^ meta.tag.any.bbcode +# ^^^^ meta.tag.any.bbcode +# ^^^^^^ markup.italic +# ^^^^^^ markup.italic +# ^^^^^^^^^^ markup.italic markup.bold +[i]i[b]ib[u]ibu[s]ibus[/s]ibu[/u]ib[/b]i[/i] # nested emphasis +# <- meta.tag.any.bbcode +#^^ meta.tag.any.bbcode +# ^^^ meta.tag.any.bbcode +# ^^^ meta.tag.any.bbcode +# ^^^ meta.tag.any.bbcode +# ^^^^ meta.tag.any.bbcode +# ^^^^ meta.tag.any.bbcode +# ^^^^ meta.tag.any.bbcode +# ^^^^ meta.tag.any.bbcode +# ^ markup.italic +# ^ markup.italic +# ^^ markup.italic markup.bold +# ^^ markup.italic markup.bold +# ^^^ markup.italic markup.bold markup.underline +# ^^^ markup.italic markup.bold markup.underline +# ^^^^ markup.italic markup.bold markup.underline markup.strikethrough + + +# 3 Test other tags +[color="red"] # Color tag +# <- meta.tag.any.bbcode +#^^^^^^ meta.tag.any.bbcode +# ^ meta.tag.any.bbcode +# ^^^^^ meta.tag.value.bbcode +red text # +# <- text.bbcode +#^^^^^^^ text.bbcode +[/color] # +# <- meta.tag.any.bbcode +#^^^^^^^ meta.tag.any.bbcode + + +# 4 Test embedded languages +[code=python] +# <- meta.tag.code.python.bbcode +#^^^^^^^^^^^^ meta.tag.code.python.bbcode +# ^ source.python.embedded.bbcode source.python +import sys +#^^^^^^^^^ source.python.embedded.bbcode source.python +#^^^^^ keyword.control.import.python +sys.path.append('./') +#^^^^^^^^^^^^^^^^^^^^ source.python.embedded.bbcode source.python +# ^^^^^^ variable.function.python +def func(language): +#^^^^^^^^^^^^^^^^^^ source.python.embedded.bbcode source.python +# ^^^^ entity.name.function.python + t = 1 +# ^^^^^ source.python.embedded.bbcode source.python +# ^ keyword.operator.assignment.python +[/code] +# <- meta.tag.code.python.bbcode +#^^^^^^ meta.tag.code.python.bbcode