commit 79236ea87082ff76badfc09257a037b72b9c8655
parent 04ac4016e6cc410962e332aa9e3a5f830e41440b
Author: Jan Pobrislo <ccx@te2000.cz>
Date: Sun, 11 May 2025 23:38:24 +0000
Pygments lexer altered to match syntax used in Prolog files.
Diffstat:
1 file changed, 92 insertions(+), 0 deletions(-)
diff --git a/doc/swiprolog_lexer.py b/doc/swiprolog_lexer.py
@@ -0,0 +1,92 @@
+"""
+ pygments.lexers.prolog
+ ~~~~~~~~~~~~~~~~~~~~~~
+
+ Lexers for Prolog and Prolog-like languages.
+
+ :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+import re
+
+from pygments.lexer import RegexLexer, bygroups
+from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
+ Number, Punctuation
+
+__all__ = ['SWIPrologLexer']
+
+T_ATOM = Name.Constant
+T_BACKTICK = String.Char
+
+class SWIPrologLexer(RegexLexer):
+ """
+ Lexer for Prolog files.
+ """
+ name = 'Prolog'
+ aliases = ['prolog']
+ filenames = ['*.ecl', '*.prolog', '*.pro', '*.pl']
+ mimetypes = ['text/x-prolog']
+ url = 'https://en.wikipedia.org/wiki/Prolog'
+ version_added = ''
+
+ tokens = {
+ 'root': [
+ (r'/\*', Comment.Multiline, 'nested-comment'),
+ (r'%.*', Comment.Single),
+ # character literal
+ (r'0\'.', String.Char),
+ (r'0b[01]+', Number.Bin),
+ (r'0o[0-7]+', Number.Oct),
+ (r'0x[0-9a-fA-F]+', Number.Hex),
+ # literal with prepended base
+ (r'\d\d?\'[a-zA-Z0-9]+', Number.Integer),
+ (r'(\d+\.\d*|\d*\.\d+)([eE][+-]?[0-9]+)?', Number.Float),
+ (r'\d+', Number.Integer),
+ (r'[\[\](){}|.,;!]', Punctuation),
+ (r':-|-->', Punctuation),
+ (r'"(?:\\x[0-9a-fA-F]+\\|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}|'
+ r'\\[0-7]+\\|\\["\\abcefnrstv]|[^\\"])*"', String.Double),
+ (r'`(?:\\x[0-9a-fA-F]+\\|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}|'
+ r'\\[0-7]+\\|\\[`\\abcefnrstv]|[^\\`])*`', T_BACKTICK),
+ (r"'(?:''|[^'])*'", T_ATOM), # quoted atom
+ # Needs to not be followed by an atom.
+ # (r'=(?=\s|[a-zA-Z\[])', Operator),
+ (r'is\b', Operator),
+ (r'(<|>|=<|>=|==|=:=|=|/|//|\*|\+|-|~)(?=\s|[a-zA-Z0-9\[])',
+ Operator),
+ (r'(mod|div|not|will_be)\b', Operator),
+ (r'_', Keyword), # The don't-care variable
+ (r'([a-z]+)(:)', bygroups(Name.Namespace, Punctuation)),
+ (r'([a-z\u00c0-\u1fff\u3040-\ud7ff\ue000-\uffef]'
+ r'[\w$\u00c0-\u1fff\u3040-\ud7ff\ue000-\uffef]*)'
+ r'(\s*)(:-|-->)',
+ bygroups(Name.Function, Text, Operator)), # function defn
+ (r'([a-z\u00c0-\u1fff\u3040-\ud7ff\ue000-\uffef]'
+ r'[\w$\u00c0-\u1fff\u3040-\ud7ff\ue000-\uffef]*)'
+ r'(\s*)(\()',
+ bygroups(Name.Function, Text, Punctuation)),
+ (r'[a-z\u00c0-\u1fff\u3040-\ud7ff\ue000-\uffef]'
+ r'[\w$\u00c0-\u1fff\u3040-\ud7ff\ue000-\uffef]*',
+ T_ATOM), # atom, characters
+ # This one includes !
+ (r'[#&*+\-./:<=>?@\\^~\u00a1-\u00bf\u2010-\u303f]+',
+ T_ATOM), # atom, graphics
+ (r'[A-Z_]\w*', Name.Variable),
+ (r'\s+|[\u2000-\u200f\ufff0-\ufffe\uffef]', Text),
+ ],
+ 'nested-comment': [
+ (r'\*/', Comment.Multiline, '#pop'),
+ (r'/\*', Comment.Multiline, '#push'),
+ (r'[^*/]+', Comment.Multiline),
+ (r'[*/]', Comment.Multiline),
+ ],
+ }
+
+ def analyse_text(text):
+ """Competes with IDL and Visual Prolog on *.pro"""
+ if ':-' in text:
+ # Visual Prolog also uses :-
+ return 0.5
+ else:
+ return 0