summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax <maxschillinger@web.de>2020-05-24 14:14:02 +0200
committerGitHub <noreply@github.com>2020-05-24 14:14:02 +0200
commit7c46c9112b34d2fb1c31cef5001e60f5e3bb93f3 (patch)
tree42d13964af5198456e284954491cb7e5c6299064
parentc191192fe0f34ab255ae4c26881bddb66ff26c26 (diff)
downloadpygments-git-7c46c9112b34d2fb1c31cef5001e60f5e3bb93f3.tar.gz
Add support for .tid files (TiddlyWiki5) (#1390)
* add support for .tid files (TiddlyWiki5) * add lexers/_mapping.py * markup.py: change versionadded of TiddlyWiki5Lexer to 2.7 * markup.py, TiddlyWiki5Lexer: use non-greedy matcher for table headers, footers, captions and classes * markup.py, TiddlyWiki5Lexer: make timestamps of type Number.Integer
-rw-r--r--pygments/lexers/_mapping.py1
-rw-r--r--pygments/lexers/markup.py161
-rw-r--r--tests/examplefiles/TiddlyWiki5.tid72
3 files changed, 233 insertions, 1 deletions
diff --git a/pygments/lexers/_mapping.py b/pygments/lexers/_mapping.py
index 8596c928..8a725b4f 100644
--- a/pygments/lexers/_mapping.py
+++ b/pygments/lexers/_mapping.py
@@ -444,6 +444,7 @@ LEXERS = {
'TexLexer': ('pygments.lexers.markup', 'TeX', ('tex', 'latex'), ('*.tex', '*.aux', '*.toc'), ('text/x-tex', 'text/x-latex')),
'TextLexer': ('pygments.lexers.special', 'Text only', ('text',), ('*.txt',), ('text/plain',)),
'ThriftLexer': ('pygments.lexers.dsls', 'Thrift', ('thrift',), ('*.thrift',), ('application/x-thrift',)),
+ 'TiddlyWiki5Lexer': ('pygments.lexers.markup', 'tiddler', ('tid',), ('*.tid',), ('text/vnd.tiddlywiki',)),
'TodotxtLexer': ('pygments.lexers.textfmts', 'Todotxt', ('todotxt',), ('todo.txt', '*.todotxt'), ('text/x-todo',)),
'TransactSqlLexer': ('pygments.lexers.sql', 'Transact-SQL', ('tsql', 't-sql'), ('*.sql',), ('text/x-tsql',)),
'TreetopLexer': ('pygments.lexers.parsers', 'Treetop', ('treetop',), ('*.treetop', '*.tt'), ()),
diff --git a/pygments/lexers/markup.py b/pygments/lexers/markup.py
index ad2491ad..8c03d0cd 100644
--- a/pygments/lexers/markup.py
+++ b/pygments/lexers/markup.py
@@ -24,7 +24,7 @@ from pygments.util import get_bool_opt, ClassNotFound
__all__ = ['BBCodeLexer', 'MoinWikiLexer', 'RstLexer', 'TexLexer', 'GroffLexer',
'MozPreprocHashLexer', 'MozPreprocPercentLexer',
'MozPreprocXulLexer', 'MozPreprocJavascriptLexer',
- 'MozPreprocCssLexer', 'MarkdownLexer']
+ 'MozPreprocCssLexer', 'MarkdownLexer', 'TiddlyWiki5Lexer']
class BBCodeLexer(RegexLexer):
@@ -596,3 +596,162 @@ class MarkdownLexer(RegexLexer):
def __init__(self, **options):
self.handlecodeblocks = get_bool_opt(options, 'handlecodeblocks', True)
RegexLexer.__init__(self, **options)
+
+class TiddlyWiki5Lexer(RegexLexer):
+ """
+ For `TiddlyWiki5 <https://tiddlywiki.com/#TiddlerFiles>`_ markup.
+
+ .. versionadded:: 2.7
+ """
+ name = 'tiddler'
+ aliases = ['tid']
+ filenames = ['*.tid']
+ mimetypes = ["text/vnd.tiddlywiki"]
+ flags = re.MULTILINE
+
+ def _handle_codeblock(self, match):
+ """
+ match args: 1:backticks, 2:lang_name, 3:newline, 4:code, 5:backticks
+ """
+ from pygments.lexers import get_lexer_by_name
+
+ # section header
+ yield match.start(1), String , match.group(1)
+ yield match.start(2), String , match.group(2)
+ yield match.start(3), Text , match.group(3)
+
+ # lookup lexer if wanted and existing
+ lexer = None
+ if self.handlecodeblocks:
+ try:
+ lexer = get_lexer_by_name( match.group(2).strip() )
+ except ClassNotFound:
+ pass
+ code = match.group(4)
+
+ # no lexer for this language. handle it like it was a code block
+ if lexer is None:
+ yield match.start(4), String, code
+ return
+
+ for item in do_insertions([], lexer.get_tokens_unprocessed(code)):
+ yield item
+
+ yield match.start(5), String , match.group(5)
+
+ def _handle_cssblock(self, match):
+ """
+ match args: 1:style tag 2:newline, 3:code, 4:closing style tag
+ """
+ from pygments.lexers import get_lexer_by_name
+
+ # section header
+ yield match.start(1), String , match.group(1)
+ yield match.start(2), String , match.group(2)
+
+ lexer = None
+ if self.handlecodeblocks:
+ try:
+ lexer = get_lexer_by_name( 'css' )
+ except ClassNotFound:
+ pass
+ code = match.group(3)
+
+ # no lexer for this language. handle it like it was a code block
+ if lexer is None:
+ yield match.start(3), String, code
+ return
+
+ for item in do_insertions([], lexer.get_tokens_unprocessed(code)):
+ yield item
+
+ yield match.start(4), String , match.group(4)
+
+ tokens = {
+ 'root': [
+ # title in metadata section
+ (r'^(title)(:\s)(.+\n)', bygroups(Keyword, Text, Generic.Heading)),
+ # headings
+ (r'^(!)([^!].+\n)', bygroups(Generic.Heading, Text)),
+ (r'^(!{2,6})(.+\n)', bygroups(Generic.Subheading, Text)),
+ # bulleted or numbered lists or single-line block quotes
+ # (can be mixed)
+ (r'^(\s*)([*#>]+)(\s*)(.+\n)',
+ bygroups(Text, Keyword, Text, using(this, state='inline'))),
+ # multi-line block quotes
+ (r'^(<<<.*\n)([\w\W]*?)(^<<<.*$)', bygroups(String, Text, String)),
+ # table header
+ (r'^(\|.*?\|h)$', bygroups(Generic.Strong)),
+ # table footer or caption
+ (r'^(\|.*?\|[cf])$', bygroups(Generic.Emph)),
+ # table class
+ (r'^(\|.*?\|k)$', bygroups(Name.Tag)),
+ # definitions
+ (r'^(;.*)$', bygroups(Generic.Strong)),
+ # text block
+ (r'^(```\n)([\w\W]*?)(^```$)', bygroups(String, Text, String)),
+ # code block with language
+ (r'^(```)(\w+)(\n)([\w\W]*?)(^```$)', _handle_codeblock),
+ # CSS style block
+ (r'^(<style>)(\n)([\w\W]*?)(^</style>$)', _handle_cssblock),
+
+ include('keywords'),
+ include('inline'),
+ ],
+ 'keywords': [
+ (words((
+ '\\define', '\\end', 'caption', 'created', 'modified', 'tags',
+ 'title', 'type'), prefix=r'^', suffix=r'\b'),
+ Keyword),
+ ],
+ 'inline': [
+ # escape
+ (r'\\.', Text),
+ # created or modified date
+ (r'\d{17}', Number.Integer),
+ # italics
+ (r'(\s)(//[^/]+//)((?=\W|\n))',
+ bygroups(Text, Generic.Emph, Text)),
+ # superscript
+ (r'(\s)(\^\^[^\^]+\^\^)', bygroups(Text, Generic.Emph)),
+ # subscript
+ (r'(\s)(,,[^,]+,,)', bygroups(Text, Generic.Emph)),
+ # underscore
+ (r'(\s)(__[^_]+__)', bygroups(Text, Generic.Strong)),
+ # bold
+ (r"(\s)(''[^']+'')((?=\W|\n))",
+ bygroups(Text, Generic.Strong, Text)),
+ # strikethrough
+ (r'(\s)(~~[^~]+~~)((?=\W|\n))',
+ bygroups(Text, Generic.Deleted, Text)),
+ # TiddlyWiki variables
+ (r'<<[^>]+>>', Name.Tag),
+ (r'\$\$[^\$]+\$\$', Name.Tag),
+ (r'\$\([^)]+\)\$', Name.Tag),
+ # TiddlyWiki style or class
+ (r'^@@.*$', Name.Tag),
+ # HTML tags
+ (r'</?[^>]+>', Name.Tag),
+ # inline code
+ (r'`[^`]+`', String.Backtick),
+ # HTML escaped symbols
+ (r'&\S*?;', String.Regex),
+ # Wiki links
+ (r'(\[{2})([^]\|]+)(\]{2})', bygroups(Text, Name.Tag, Text)),
+ # External links
+ (r'(\[{2})([^]\|]+)(\|)([^]\|]+)(\]{2})',
+ bygroups(Text, Name.Tag, Text, Name.Attribute, Text)),
+ # Transclusion
+ (r'(\{{2})([^}]+)(\}{2})', bygroups(Text, Name.Tag, Text)),
+ # URLs
+ (r'(\b.?.?tps?://[^\s"]+)', bygroups(Name.Attribute)),
+
+ # general text, must come last!
+ (r'[\w]+', Text),
+ (r'.', Text)
+ ],
+ }
+
+ def __init__(self, **options):
+ self.handlecodeblocks = get_bool_opt(options, 'handlecodeblocks', True)
+ RegexLexer.__init__(self, **options)
diff --git a/tests/examplefiles/TiddlyWiki5.tid b/tests/examplefiles/TiddlyWiki5.tid
new file mode 100644
index 00000000..8b998b68
--- /dev/null
+++ b/tests/examplefiles/TiddlyWiki5.tid
@@ -0,0 +1,72 @@
+caption: Formatting
+created: 20131205155959399
+modified: 20200201075357846
+tags: TiddlyWiki WikiText
+title: TiddlyWiki5
+type: text/vnd.tiddlywiki
+
+\define pos() <div class="cell positive">+</div>
+\define neg() <div class="cell negative">-</div>
+
+\define say-hi-using-variables()
+Hi, I'm $(name)$ and I live in $(address)$.
+\end
+
+<style>
+/* compensating the cell padding */
+.cell { margin:-1px -7px; padding:1px 7px; }
+.positive { background-color:#afa; }
+.negative { background-color:#faa; }
+</style>
+
+!Main Header
+
+Available character formatting includes:
+
+* <code>&#96;backticks&#96;</code> for `code`
+** Alternatively, <code>&#96;&#96;double backticks allows &#96;embedded&#96; backticks&#96;&#96;</code>
+ * `''bold''` for ''bold text''
+*`//italic//` for //italic text// ({{$:/core/images/italic}})
+*# `__underscore__` for __underscored text__
+
+Ordered list:
+
+# `^^superscript^^` for ^^superscripted^^ text ({{$:/core/images/superscript}})
+# `,,subscript,,` for ,,subscripted,, text ({{$:/core/images/subscript}})
+#* `~~strikethrough~~` for ~~strikethrough~~ text ({{$:/core/images/strikethrough}})
+
+<span style="font-style: italic;">''bold'' &#96;&amp;</span>
+
+!!Links
+
+Internal link: [[Code Blocks in WikiText]]
+
+External link: [[TiddlyWiki Homepage|https://tiddlywiki.com]]
+
+Image via transclusion: {{$:/core/images/underline}}
+
+Just a link: ftp://ftp.halifax.rwth-aachen.de/
+
+!!!Code
+
+```bash
+cd "$HOME/workspace"
+```
+
+!!!Table
+
+|myclass anotherClass|k
+|This is a caption |c
+|Header|Header|h
+|''Cell1'' |<<neg>> |
+|//Cell2// |<<pos>> |
+|Footer|Footer|f
+
+!Block quote
+
+<<<
+Computers are like a bicycle for our minds
+<<< Steve Jobs
+
+; Term being defined
+: Definition of that term