Skip to content

Commit c2d5179

Browse files
committed
Add lexer for HercScript language highlight
this is a basic highlight based on Pygments C one, from my tests it gives a satisfatory result and should be good enough for our current docs. it may be improved later as we find places where it doesn't work very well. Docs can format hercules scripts using "```HercScript" to get proper highlight
1 parent d5571a0 commit c2d5179

File tree

6 files changed

+157
-2
lines changed

6 files changed

+157
-2
lines changed

.github/workflows/docs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ jobs:
1313
- uses: actions/checkout@v3
1414
- run: python -m pip install --upgrade pip
1515
- run: pip install mkdocs mkdocs-material
16+
- run: pip install -e ./hercscript-lexer
1617
- run: cd docs
1718
- run: mkdocs build -f mkdocs.yml
1819
- name: Upload GitHub Pages artifact

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
/.venv
22
/site/
3+
/hercscript-lexer/hercscript_lexers.egg-info
4+
/hercscript-lexer/hercscript_lexers/__pycache__

docs/contributing/editing-the-docs.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,15 @@ submit a [Pull request](./creating-pull-requests.md) to the [Hercules-docs repos
1515
## Setup
1616
Hercules docs uses mkdocs-material.
1717

18-
You will need to have Python3 installed and install `mkdocs-material` package.
18+
You will need to have Python3 installed, and install `mkdocs-material` and our lexer packages.
1919

20-
You can install it with `pip install mkdocs-material` or `pip3 install mkdocs-material`.
20+
You can install it with:
21+
```SH
22+
pip install mkdocs-material
23+
pip install -e ./hercscript-lexer # Optional, required for HercScript highlighting
24+
```
25+
26+
or perform the same commands with `pip3`.
2127

2228
For more information about installing mkdocs-material, and other alternatives,
2329
see [Mkdocs Material's getting started](https://squidfunk.github.io/mkdocs-material/getting-started/#installation)
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
from pygments.lexer import RegexLexer, include, bygroups, using, \
2+
this, default, words
3+
from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
4+
Number, Punctuation, Whitespace
5+
6+
__all__ = ['HercScriptLexer']
7+
8+
9+
class HercScriptLexer(RegexLexer):
10+
"""
11+
Hercules Script (a.k.a. Athena Script) lexer.
12+
13+
Based on Pygments official C grammar
14+
"""
15+
16+
name = 'hercscript'
17+
aliases = ['hercscript', 'athenascript']
18+
url = ''
19+
version_added = ''
20+
priority = 0.1
21+
22+
# Hexadecimal part in an hexadecimal integer literal.
23+
# This includes separators matching.
24+
_hexpart = r'[0-9a-fA-F](_?[0-9a-fA-F])*'
25+
# Decimal part in an decimal integer literal.
26+
# This includes separators matching.
27+
_decpart = r'\d(\_?\d)*'
28+
29+
# Identifier regex with C and C++ Universal Character Name (UCN) support.
30+
_ident = r'(?!\d)(?:[\w$]|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8})+'
31+
32+
# Single and multiline comment regexes
33+
# Beware not to use *? for the inner content! When these regexes
34+
# are embedded in larger regexes, that can cause the stuff*? to
35+
# match more than it would have if the regex had been used in
36+
# a standalone way ...
37+
_comment_single = r'//(?:.|(?<=\\)\n)*\n'
38+
_comment_multiline = r'/(?:\\\n)?[*](?:[^*]|[*](?!(?:\\\n)?/))*[*](?:\\\n)?/'
39+
40+
tokens = {
41+
'whitespace': [
42+
# Labels:
43+
# Line start and possible indentation.
44+
(r'(^[ \t]*)'
45+
# Not followed by keywords which can be mistaken as labels.
46+
r'(?!(?:default)\b)'
47+
# Actual label, followed by a single colon.
48+
r'(' + _ident + r')(\s*)(:)(?!:)',
49+
bygroups(Whitespace, Name.Label, Whitespace, Punctuation)
50+
),
51+
(r'\n', Whitespace),
52+
(r'[^\S\n]+', Whitespace),
53+
(_comment_single, Comment.Single),
54+
(_comment_multiline, Comment.Multiline),
55+
# Open until EOF, so no ending delimiter
56+
(r'/(\\\n)?[*][\w\W]*', Comment.Multiline),
57+
],
58+
'statements': [
59+
include('keywords'),
60+
(r'(-)?0[xX]' + _hexpart , Number.Hex),
61+
(r'(-)?0[bB][01](_?[01])*', Number.Bin),
62+
(r'(-)?0(_?[0-7])+', Number.Oct),
63+
(r'(-)?' + _decpart, Number.Integer),
64+
(r'[~!%^&*+=|?:<>/-]', Operator),
65+
(r'[()\[\],.]', Punctuation),
66+
(r'(true|false)\b', Name.Builtin),
67+
('"', String, 'string'),
68+
(r'(\w+)(\s*\()', bygroups(Name.Function, using(this))), # function call
69+
(r'[\.#\$]?#?@?\w+\$?', Name.Variable),
70+
(_ident, Name)
71+
],
72+
'keywords': [
73+
(r'case\b', Keyword, 'case-value'),
74+
(
75+
words(
76+
('break', 'continue', 'default',
77+
'do', 'else', 'for', 'goto', 'if',
78+
'return', 'switch', 'while',
79+
'end', 'function', 'script', 'trader'
80+
),
81+
suffix=r'\b'), Keyword
82+
)
83+
],
84+
'root': [
85+
include('whitespace'),
86+
include('keywords'),
87+
default('statement'),
88+
],
89+
'statement': [
90+
include('whitespace'),
91+
include('statements'),
92+
(r'\}', Punctuation),
93+
(r'[{;]', Punctuation, '#pop'),
94+
],
95+
'string': [
96+
(r'"', String, '#pop'),
97+
(r'\\([\\abfnrtv"\']|x[a-fA-F0-9]{2,4}|'
98+
r'u[a-fA-F0-9]{4}|U[a-fA-F0-9]{8}|[0-7]{1,3})', String.Escape),
99+
(r'[^\\"\n]+', String), # all other characters
100+
(r'\\\n', String), # line continuation
101+
(r'\\', String), # stray backslash
102+
],
103+
# Mark identifiers preceded by `case` keyword as constants.
104+
'case-value': [
105+
(r'(?<!:)(:)(?!:)', Punctuation, '#pop'),
106+
(_ident, Name.Constant),
107+
include('whitespace'),
108+
include('statements'),
109+
]
110+
}
111+
112+
def __init__(self, **options):
113+
RegexLexer.__init__(self, **options)
114+
115+
def get_tokens_unprocessed(self, text, stack=('root',)):
116+
for index, token, value in \
117+
RegexLexer.get_tokens_unprocessed(self, text, stack):
118+
yield index, token, value
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from .HercScriptLexer import HercScriptLexer
2+
3+
__all__ = ("HercScriptLexer")

hercscript-lexer/setup.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/usr/bin/env python
2+
"""Setup hercscript-lexers."""
3+
from setuptools import setup, find_packages
4+
5+
entry_points = '''
6+
[pygments.lexers]
7+
hercscript=hercscript_lexers:HercScriptLexer
8+
'''
9+
10+
setup(
11+
name='hercscript-lexers',
12+
version='1.0.0',
13+
description='Pygments lexer package for hercscript.',
14+
author='Hercules Team',
15+
author_email='',
16+
url='',
17+
packages=find_packages(),
18+
entry_points=entry_points,
19+
install_requires=[
20+
'Pygments>=2.0.1'
21+
],
22+
zip_safe=True,
23+
license='MIT License',
24+
classifiers=[]
25+
)

0 commit comments

Comments
 (0)