1"""
2 pygments.lexers.openscad
3 ~~~~~~~~~~~~~~~~~~~~~~~~
4
5 Lexers for the OpenSCAD languages.
6
7 :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
8 :license: BSD, see LICENSE for details.
9"""
10
11from pygments.lexer import RegexLexer, bygroups, words, include
12from pygments.token import Text, Comment, Punctuation, Operator, Keyword, Name, Number, Whitespace, Literal, String
13
14__all__ = ['OpenScadLexer']
15
16
17class OpenScadLexer(RegexLexer):
18 """For openSCAD code.
19 """
20 name = "OpenSCAD"
21 url = "https://openscad.org/"
22 aliases = ["openscad"]
23 filenames = ["*.scad"]
24 mimetypes = ["application/x-openscad"]
25 version_added = '2.16'
26
27 tokens = {
28 "root": [
29 (r"[^\S\n]+", Whitespace),
30 (r'//', Comment.Single, 'comment-single'),
31 (r'/\*', Comment.Multiline, 'comment-multi'),
32 (r"[{}\[\]\(\),;:]", Punctuation),
33 (r"[*!#%\-+=?/]", Operator),
34 (r"<=|<|==|!=|>=|>|&&|\|\|", Operator),
35 (r"\$(f[asn]|t|vp[rtd]|children)", Operator),
36 (r"(undef|PI)\b", Keyword.Constant),
37 (
38 r"(use|include)((?:\s|\\\\s)+)",
39 bygroups(Keyword.Namespace, Text),
40 "includes",
41 ),
42 (r"(module)(\s*)([^\s\(]+)",
43 bygroups(Keyword.Namespace, Whitespace, Name.Namespace)),
44 (r"(function)(\s*)([^\s\(]+)",
45 bygroups(Keyword.Declaration, Whitespace, Name.Function)),
46 (words(("true", "false"), prefix=r"\b", suffix=r"\b"), Literal),
47 (words((
48 "function", "module", "include", "use", "for",
49 "intersection_for", "if", "else", "return"
50 ), prefix=r"\b", suffix=r"\b"), Keyword
51 ),
52 (words((
53 "circle", "square", "polygon", "text", "sphere", "cube",
54 "cylinder", "polyhedron", "translate", "rotate", "scale",
55 "resize", "mirror", "multmatrix", "color", "offset", "hull",
56 "minkowski", "union", "difference", "intersection", "abs",
57 "sign", "sin", "cos", "tan", "acos", "asin", "atan", "atan2",
58 "floor", "round", "ceil", "ln", "log", "pow", "sqrt", "exp",
59 "rands", "min", "max", "concat", "lookup", "str", "chr",
60 "search", "version", "version_num", "norm", "cross",
61 "parent_module", "echo", "import", "import_dxf",
62 "dxf_linear_extrude", "linear_extrude", "rotate_extrude",
63 "surface", "projection", "render", "dxf_cross",
64 "dxf_dim", "let", "assign", "len"
65 ), prefix=r"\b", suffix=r"\b"),
66 Name.Builtin
67 ),
68 (r"\bchildren\b", Name.Builtin.Pseudo),
69 (r'""".*?"""', String.Double),
70 (r'"(\\\\|\\[^\\]|[^"\\])*"', String.Double),
71 (r"-?\d+(\.\d+)?(e[+-]?\d+)?", Number),
72 (r"\w+", Name),
73 ],
74 "includes": [
75 (
76 r"(<)([^>]*)(>)",
77 bygroups(Punctuation, Comment.PreprocFile, Punctuation),
78 ),
79 ],
80 'comment': [
81 (r':param: [a-zA-Z_]\w*|:returns?:|(FIXME|MARK|TODO):',
82 Comment.Special)
83 ],
84 'comment-single': [
85 (r'\n', Text, '#pop'),
86 include('comment'),
87 (r'[^\n]+', Comment.Single)
88 ],
89 'comment-multi': [
90 include('comment'),
91 (r'[^*/]+', Comment.Multiline),
92 (r'/\*', Comment.Multiline, '#push'),
93 (r'\*/', Comment.Multiline, '#pop'),
94 (r'[*/]', Comment.Multiline)
95 ],
96 }