Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/git/vole.git

Write over SSH with a registered key:

git clone ssh://git@0.0.0.0:2222/vole.git

A free and open-source forge that lives in your Git repo.

Blame · server/web/highlight.go

Line attribution on main · 154 line(s)

f09ef39e
Keenan Nemetz
15d ago
1 package web
2
306f36fc
Keenan Nemetz
12d ago
3 // The code browser does not highlight; it names a blob's language and the
4 // browser tokenises it (static/prism-worker.js). So the server carries no lexer
5 // and does no lexing work per blob, and a file whose language is not in the
6 // table below is served as plain text with its line numbers — the honest result
7 // for a file we cannot classify.
1b8675b1
Keenan Nemetz
8d ago
8 //
9 // The worker loads a grammar when a blob first names it (static/prism-manifest.js
10 // and static/prism-languages/), so the table is also what decides which of
11 // Prism's grammars a page ever reads.
f09ef39e
Keenan Nemetz
15d ago
12
13 import (
306f36fc
Keenan Nemetz
12d ago
14 "path"
15 "strings"
f09ef39e
Keenan Nemetz
15d ago
16 )
17
306f36fc
Keenan Nemetz
12d ago
18 // prismLanguages maps a lower-case file extension (without the dot) or a whole
19 // lower-case file name to the Prism language that colours it. Prism has no file
20 // extension table of its own, so this is the work its grammars cannot do: every
1b8675b1
Keenan Nemetz
8d ago
21 // language the manifest can load is reachable from here, and a name this table
22 // does not claim stays plain.
306f36fc
Keenan Nemetz
12d ago
23 //
24 // Names are matched before extensions because a Dockerfile has no extension and
25 // nginx.conf would otherwise be read as an ini file. Where two languages want
26 // the same extension the more common one on a forge wins: `.v` is Verilog,
27 // `.m` is Objective-C, `.h` is C, `.pp` is Puppet, `.cls` is LaTeX.
28 var prismLanguages = map[string]string{
29 // Systems and compiled languages.
30 "go": "go",
31 "c": "c", "h": "c",
32 "cc": "cpp", "cpp": "cpp", "cxx": "cpp", "hpp": "cpp", "hh": "cpp", "hxx": "cpp", "ino": "cpp",
33 "cs": "csharp",
34 "m": "objectivec", "mm": "objectivec",
35 "java": "java", "kt": "kotlin", "kts": "kotlin", "scala": "scala", "sc": "scala",
36 "groovy": "groovy", "gvy": "groovy", "gradle": "gradle",
37 "rs": "rust", "zig": "zig", "swift": "swift", "nix": "nix",
38 "d": "d", "nim": "nim", "nims": "nim", "odin": "odin", "cr": "crystal",
39 "ada": "ada", "adb": "ada", "ads": "ada",
40 "pas": "pascal", "p": "pascal", "dpr": "pascal", "pp": "puppet",
41 "f": "fortran", "for": "fortran", "f77": "fortran", "f90": "fortran", "f95": "fortran", "f03": "fortran",
42 "fs": "fsharp", "fsx": "fsharp", "fsi": "fsharp",
43 "ml": "ocaml", "mli": "ocaml",
44 "hs": "haskell", "lhs": "haskell",
45 "vala": "vala", "vapi": "vala",
46 "cobol": "cobol", "cbl": "cobol", "cpy": "cobol",
47 "eiffel": "eiffel", "e": "eiffel",
48 "dart": "dart", "elm": "elm", "purs": "purescript", "pure": "purebasic",
49 "hx": "haxe", "v": "verilog", "sv": "verilog", "svh": "verilog",
50 "vhd": "vhdl", "vhdl": "vhdl",
51 "wat": "wasm", "wasm": "wasm", "ll": "llvm", "cl": "opencl",
52 "glsl": "glsl", "vert": "glsl", "frag": "glsl", "geom": "glsl", "comp": "glsl",
53 "hlsl": "hlsl", "wgsl": "wgsl", "sol": "solidity",
54 "s": "armasm", "asm": "nasm", "nasm": "nasm",
55 "basic": "basic", "bb": "bbj", "vba": "vba", "bas": "visual-basic",
56
57 // Scripting and dynamic languages.
58 "js": "javascript", "mjs": "javascript", "cjs": "javascript", "jsx": "javascript",
59 "ts": "typescript", "tsx": "typescript", "mts": "typescript", "cts": "typescript",
60 "py": "python", "pyw": "python", "pyi": "python", "py3": "python",
61 "rb": "ruby", "rake": "ruby", "gemspec": "ruby",
62 "php": "php", "phtml": "php", "php3": "php", "php4": "php", "php5": "php", "php7": "php", "php8": "php",
63 "pl": "perl", "pm": "perl", "t": "perl",
64 "lua": "lua", "tcl": "tcl", "tm": "tcl",
65 "sh": "bash", "bash": "bash", "zsh": "bash", "ksh": "bash",
66 "fish": "bash", "bat": "batch", "cmd": "batch",
67 "ps1": "powershell", "psm1": "powershell", "psd1": "powershell",
68 "ex": "elixir", "exs": "elixir", "erl": "erlang", "hrl": "erlang",
69 "clj": "clojure", "cljs": "clojure", "cljc": "clojure", "edn": "clojure",
70 "scm": "scheme", "ss": "scheme", "rkt": "racket",
71 "lisp": "lisp", "lsp": "lisp", "el": "elisp",
72 "jl": "julia", "r": "r", "mata": "stata", "do": "stata", "ado": "stata", "sas": "sas",
73 "awk": "awk", "gawk": "awk", "coffee": "coffeescript", "ls": "livescript",
74 "vim": "vim", "sml": "sml", "sig": "sml", "fun": "sml",
75 "re": "reason", "rei": "reason", "res": "rescript", "resi": "rescript",
76 "robot": "robot", "rpy": "renpy", "gd": "gdscript", "nut": "squirrel",
77 "ahk": "autohotkey", "au3": "autoit", "applescript": "applescript", "scpt": "applescript",
78 "pro": "prolog", "prolog": "prolog", "rego": "rego", "dhall": "dhall",
79 "agda": "agda", "idr": "idris", "miz": "mizar", "oz": "oz", "factor": "factor",
80 "jolie": "jolie", "ol": "jolie", "iol": "jolie", "bbj": "bbj",
81 "bsl": "bsl", "os": "oscript", "jq": "jq", "gml": "gml",
82 "monkey": "monkey", "moon": "moonscript", "lol": "lolcode",
83 "bf": "brainfuck", "bqn": "bqn", "cook": "cooklang",
84 "inform7": "inform7", "ni": "inform7", "gcode": "gcode", "nc": "gcode",
85 "cue": "cue", "bicep": "bicep", "as": "actionscript",
86
87 // Markup, data, and configuration.
88 "html": "markup", "htm": "markup", "xhtml": "markup", "svg": "markup",
89 "xml": "markup", "xsl": "markup", "xslt": "markup", "xsd": "markup",
90 "rss": "markup", "atom": "markup", "plist": "markup", "mathml": "markup", "ssml": "markup",
91 "csproj": "markup", "fsproj": "markup", "vbproj": "markup", "props": "markup", "targets": "markup",
92 "nuspec": "markup", "rdf": "markup",
93 "css": "css", "scss": "scss", "sass": "sass", "less": "less", "styl": "stylus",
94 "graphql": "graphql", "gql": "graphql", "http": "http", "rest": "rest",
95 "json": "json", "json5": "json5", "jsonp": "jsonp", "webmanifest": "webmanifest",
96 "yaml": "yaml", "yml": "yaml", "toml": "toml",
97 "ini": "ini", "cfg": "ini", "conf": "ini", "properties": "properties",
98 "editorconfig": "editorconfig", "env": "ini",
99 "hcl": "hcl", "tf": "hcl", "tfvars": "hcl",
100 "proto": "protobuf", "avdl": "avdl", "yang": "yang",
101 "csv": "csv", "tsv": "csv", "po": "gettext", "pot": "gettext",
102 "diff": "diff", "patch": "diff",
103 "sql": "sql", "plsql": "plsql", "pks": "plsql", "pkb": "plsql",
104 "cypher": "cypher", "sparql": "sparql", "rq": "sparql", "ttl": "turtle",
105 "dns": "dns-zone-file", "zone": "dns-zone-file",
106 "md": "markdown", "markdown": "markdown", "mdown": "markdown", "mkd": "markdown",
107 "rst": "rest", "adoc": "asciidoc", "asciidoc": "asciidoc", "textile": "textile", "wiki": "wiki",
108 "tex": "latex", "latex": "latex", "sty": "latex", "cls": "latex",
109 "puml": "plant-uml", "plantuml": "plant-uml", "iuml": "plant-uml", "mmd": "mermaid",
110 "dot": "dot", "gv": "dot", "feature": "gherkin", "sln": "sln",
111 "tt": "t4", "tt2": "tt2", "tpl": "smarty",
112 "ejs": "ejs", "hbs": "handlebars", "mustache": "mustache", "pug": "pug", "jade": "pug",
113 "haml": "haml", "erb": "erb", "twig": "twig", "liquid": "liquid",
114 "jinja": "jinja2", "jinja2": "jinja2", "j2": "jinja2",
115 "cshtml": "cshtml", "razor": "razor",
116 "vm": "velocity", "vtl": "velocity", "soy": "soy", "ftl": "ftl",
117 "xq": "xquery", "xquery": "xquery", "xqy": "xquery",
118 "uri": "uri", "url": "uri", "regex": "regex", "webidl": "webidl", "idl": "webidl",
119 "log": "log", "spl": "splunk-spl", "promql": "promql", "kql": "kusto",
120
121 // Build, packaging, and tool configuration.
122 "mk": "makefile", "mak": "makefile", "cmake": "cmake",
123 "nsi": "nsis", "nsh": "nsis", "phpdoc": "phpdoc", "javadoc": "javadoc",
124 "gitignore": "gitignore", "npmignore": "npmignore", "hgignore": "hgignore",
125 "service": "systemd", "socket": "systemd", "timer": "systemd",
126
127 // Whole names, matched before the extension.
128 "dockerfile": "docker", "containerfile": "docker",
129 "makefile": "makefile", "gnumakefile": "makefile", "bsdmakefile": "makefile", "makefile.am": "makefile",
130 "justfile": "makefile", "pkgbuild": "bash",
131 "cmakelists.txt": "cmake",
132 "gemfile": "ruby", "rakefile": "ruby", "vagrantfile": "ruby", "brewfile": "ruby",
133 "podfile": "ruby", "fastfile": "ruby", "jenkinsfile": "groovy",
134 "go.mod": "go-module", "go.sum": "go-module",
135 "cargo.lock": "toml", "poetry.lock": "toml", "pipfile": "toml",
136 "nginx.conf": "nginx", "httpd.conf": "apacheconf", ".htaccess": "apacheconf",
137 ".gitignore": "gitignore", ".npmignore": "npmignore", ".hgignore": "hgignore",
138 ".dockerignore": "ignore", ".eslintignore": "ignore",
139 ".editorconfig": "editorconfig", ".env": "ini",
140 ".babelrc": "json", ".eslintrc": "json", ".prettierrc": "json",
141 }
142
143 // prismLanguage returns the Prism language for a path, or "" when the file is
144 // one the highlighter does not know.
145 func prismLanguage(name string) string {
146 base := strings.ToLower(path.Base(name))
147 if lang, ok := prismLanguages[base]; ok {
148 return lang
f09ef39e
Keenan Nemetz
15d ago
149 }
306f36fc
Keenan Nemetz
12d ago
150 if lang, ok := prismLanguages[strings.TrimPrefix(path.Ext(base), ".")]; ok {
151 return lang
f09ef39e
Keenan Nemetz
15d ago
152 }
306f36fc
Keenan Nemetz
12d ago
153 return ""
f09ef39e
Keenan Nemetz
15d ago
154 }