tiny.syn.language
Defined in tiny.syn.
Forty languages the package can mark up, and mappings from a file path or a short name to one of them.
API (4)
Actions
Public operations.
fromName: A caller turns a short name, such aszigin the README example orbash, into a tag.fromPath: A caller that opens a file picks the language from its path.name: A caller that shows or stores a language uses this short name, andfromNamereads it back.
Types and contracts
Public types and contracts.
Language: A caller passes one tag tohighlightorhighlightLineto choose the scanner for a line.
Source
Source: lib/syn/src/language.zig
zig
//! Forty languages the package can mark up, and mappings from a file path or a short name to one of//! them. A caller often knows a language only from a file path or from a short name such as `py` or//! `bash`, and one language often goes by more than one name.//!//! Matching ignores letter case and surrounding blank space, so `Python`, `PY ` and `py` all name//! Python. Some files carry no extension, such as `Makefile`, `Dockerfile` or `.bashrc`, so their//! whole name has to decide.//!//! - *Chiclet*: this repository's own Lisp-shaped programming languageconst std = @import("std");/// A caller passes one tag to `highlight` or `highlightLine` to choose the scanner for a line. The/// enum has one tag per language the scanners know, forty in all. Each tag is named after its/// language, and `name` gives its short text form. A tag can stand for a family: `shell` covers sh,/// bash, zsh and fish, and `lisp` covers Scheme, Racket, Common Lisp and Emacs Lisp. Tags share/// scanners: `lisp`, `clojure` and `chiclet` use the Lisp scanner, and every language without a/// scanner of its own uses a generic scanner for C-like syntax.pub const Language = enum { zig, /// This repository's own programming language, which `lib/chic` parses and compiles. Its lines /// go through the same scanner as Lisp and Clojure. `fromName` accepts `chiclet` and `chic`, /// and `fromPath` accepts the `.chic` extension and a file named `.chic`. chiclet, lisp, json, shell, diff, markdown, python, yaml, toml, c, cpp, csharp, java, javascript, typescript, go, rust, ruby, php, swift, kotlin, scala, sql, html, css, xml, nix, lua, haskell, elixir, erlang, clojure, ocaml, r, make, perl, dart, vue, svelte,};/// A caller that shows or stores a language uses this short name, and `fromName` reads it back. The/// call returns a short lowercase name for the tag. The name equals the tag's own name, except that/// `shell` gives `sh`. `fromName` maps every returned name back to the same tag. The returned text/// is static and needs no freeing.pub fn name(language: Language) []const u8 { return switch (language) { .zig => "zig", .chiclet => "chiclet", .lisp => "lisp", .json => "json", .shell => "sh", .diff => "diff", .markdown => "markdown", .python => "python", .yaml => "yaml", .toml => "toml", .c => "c", .cpp => "cpp", .csharp => "csharp", .java => "java", .javascript => "javascript", .typescript => "typescript", .go => "go", .rust => "rust", .ruby => "ruby", .php => "php", .swift => "swift", .kotlin => "kotlin", .scala => "scala", .sql => "sql", .html => "html", .css => "css", .xml => "xml", .nix => "nix", .lua => "lua", .haskell => "haskell", .elixir => "elixir", .erlang => "erlang", .clojure => "clojure", .ocaml => "ocaml", .r => "r", .make => "make", .perl => "perl", .dart => "dart", .vue => "vue", .svelte => "svelte", };}/// A caller turns a short name, such as `zig` in the README example or `bash`, into a tag. The call/// returns the tag whose name or alias matches `raw`, or null when none does. Matching ignores/// letter case, and trims spaces, tabs, carriage returns and newlines from both ends. An empty or/// blank `raw` gives null. The lookup accepts common aliases, for example `zon` for Zig, `js`,/// `jsx` and `node` for JavaScript, `c++` and `cc` for C++, `c#` for C#, `yml` for YAML, and/// `makefile` for Make.pub fn fromName(raw: []const u8) ?Language { const value = std.mem.trim(u8, raw, " \t\r\n"); if (value.len == 0) return null; if (eq(value, "zig") or eq(value, "zon")) return .zig; if (eq(value, "chiclet") or eq(value, "chic")) return .chiclet; if (eq(value, "lisp") or eq(value, "scheme") or eq(value, "racket") or eq(value, "common-lisp") or eq(value, "elisp")) return .lisp; if (eq(value, "json") or eq(value, "jsonl")) return .json; if (eq(value, "sh") or eq(value, "shell") or eq(value, "bash") or eq(value, "zsh") or eq(value, "fish")) return .shell; if (eq(value, "diff") or eq(value, "patch")) return .diff; if (eq(value, "markdown") or eq(value, "md") or eq(value, "mdx")) return .markdown; if (eq(value, "python") or eq(value, "py")) return .python; if (eq(value, "yaml") or eq(value, "yml")) return .yaml; if (eq(value, "toml")) return .toml; if (eq(value, "c")) return .c; if (eq(value, "cpp") or eq(value, "c++") or eq(value, "cxx") or eq(value, "cc")) return .cpp; if (eq(value, "csharp") or eq(value, "c#") or eq(value, "cs")) return .csharp; if (eq(value, "java")) return .java; if (eq(value, "javascript") or eq(value, "js") or eq(value, "jsx") or eq(value, "node")) return .javascript; if (eq(value, "typescript") or eq(value, "ts") or eq(value, "tsx")) return .typescript; if (eq(value, "go") or eq(value, "golang")) return .go; if (eq(value, "rust") or eq(value, "rs")) return .rust; if (eq(value, "ruby") or eq(value, "rb")) return .ruby; if (eq(value, "php")) return .php; if (eq(value, "swift")) return .swift; if (eq(value, "kotlin") or eq(value, "kt") or eq(value, "kts")) return .kotlin; if (eq(value, "scala")) return .scala; if (eq(value, "sql") or eq(value, "mysql") or eq(value, "postgres") or eq(value, "postgresql") or eq(value, "sqlite")) return .sql; if (eq(value, "html") or eq(value, "htm")) return .html; if (eq(value, "css") or eq(value, "scss") or eq(value, "sass") or eq(value, "less")) return .css; if (eq(value, "xml") or eq(value, "svg")) return .xml; if (eq(value, "nix")) return .nix; if (eq(value, "lua")) return .lua; if (eq(value, "haskell") or eq(value, "hs")) return .haskell; if (eq(value, "elixir") or eq(value, "ex") or eq(value, "exs")) return .elixir; if (eq(value, "erlang") or eq(value, "erl")) return .erlang; if (eq(value, "clojure") or eq(value, "clj") or eq(value, "cljs") or eq(value, "cljc") or eq(value, "edn")) return .clojure; if (eq(value, "ocaml") or eq(value, "ml") or eq(value, "mli")) return .ocaml; if (eq(value, "r")) return .r; if (eq(value, "make") or eq(value, "makefile")) return .make; if (eq(value, "perl") or eq(value, "pl") or eq(value, "pm")) return .perl; if (eq(value, "dart")) return .dart; if (eq(value, "vue")) return .vue; if (eq(value, "svelte")) return .svelte; return null;}/// A caller that opens a file picks the language from its path. The call returns the language for a/// file path, or null when neither its extension nor its file name is known. The lookup tries the/// extension first, ignoring letter case, so `src/main.rs` gives Rust and `src/app.tsx` gives/// TypeScript. A file named `.chic` counts as Chiclet. Without a known extension the lookup tries/// the whole file name through `fromName`, so a file called `Makefile` gives Make. It then knows a/// few names with no extension: `Dockerfile` as shell, `GNUmakefile` and `BSDmakefile` as Make, and/// shell start-up files such as `.bashrc`, `.zshrc` and `.profile` as shell. The lookup reads only/// the path text and never opens the file.pub fn fromPath(path: []const u8) ?Language { const extension = std.fs.path.extension(path); const basename = std.fs.path.basename(path); if (extension.len > 1) { if (fromExtension(extension[1..])) |language| return language; } if (eq(basename, ".chic")) return .chiclet; if (fromName(basename)) |language| return language; if (eq(basename, "Dockerfile")) return .shell; if (eq(basename, "Makefile") or eq(basename, "GNUmakefile") or eq(basename, "BSDmakefile")) return .make; if (eq(basename, ".bashrc") or eq(basename, ".zshrc") or eq(basename, ".profile") or eq(basename, ".bash_profile") or eq(basename, ".zprofile")) return .shell; if (eq(basename, "flake.nix")) return .nix; return null;}fn fromExtension(extension: []const u8) ?Language { if (eq(extension, "zig") or eq(extension, "zon")) return .zig; if (eq(extension, "chic")) return .chiclet; if (eq(extension, "lisp") or eq(extension, "lsp") or eq(extension, "scm") or eq(extension, "rkt") or eq(extension, "el")) return .lisp; if (eq(extension, "json") or eq(extension, "jsonl")) return .json; if (eq(extension, "sh") or eq(extension, "bash") or eq(extension, "zsh") or eq(extension, "fish")) return .shell; if (eq(extension, "diff") or eq(extension, "patch")) return .diff; if (eq(extension, "md") or eq(extension, "markdown") or eq(extension, "mdx")) return .markdown; if (eq(extension, "py") or eq(extension, "pyw")) return .python; if (eq(extension, "yaml") or eq(extension, "yml")) return .yaml; if (eq(extension, "toml")) return .toml; if (eq(extension, "c") or eq(extension, "h")) return .c; if (eq(extension, "cc") or eq(extension, "cpp") or eq(extension, "cxx") or eq(extension, "hpp") or eq(extension, "hh") or eq(extension, "hxx")) return .cpp; if (eq(extension, "cs")) return .csharp; if (eq(extension, "java")) return .java; if (eq(extension, "js") or eq(extension, "mjs") or eq(extension, "cjs") or eq(extension, "jsx")) return .javascript; if (eq(extension, "ts") or eq(extension, "mts") or eq(extension, "cts") or eq(extension, "tsx")) return .typescript; if (eq(extension, "go")) return .go; if (eq(extension, "rs")) return .rust; if (eq(extension, "rb") or eq(extension, "rake") or eq(extension, "gemspec")) return .ruby; if (eq(extension, "php") or eq(extension, "phtml")) return .php; if (eq(extension, "swift")) return .swift; if (eq(extension, "kt") or eq(extension, "kts")) return .kotlin; if (eq(extension, "scala") or eq(extension, "sc")) return .scala; if (eq(extension, "sql")) return .sql; if (eq(extension, "html") or eq(extension, "htm")) return .html; if (eq(extension, "css") or eq(extension, "scss") or eq(extension, "sass") or eq(extension, "less")) return .css; if (eq(extension, "xml") or eq(extension, "svg") or eq(extension, "xhtml")) return .xml; if (eq(extension, "nix")) return .nix; if (eq(extension, "lua")) return .lua; if (eq(extension, "hs") or eq(extension, "lhs")) return .haskell; if (eq(extension, "ex") or eq(extension, "exs")) return .elixir; if (eq(extension, "erl") or eq(extension, "hrl")) return .erlang; if (eq(extension, "clj") or eq(extension, "cljs") or eq(extension, "cljc") or eq(extension, "edn")) return .clojure; if (eq(extension, "ml") or eq(extension, "mli")) return .ocaml; if (eq(extension, "r") or eq(extension, "R")) return .r; if (eq(extension, "mk") or eq(extension, "mak")) return .make; if (eq(extension, "pl") or eq(extension, "pm") or eq(extension, "t")) return .perl; if (eq(extension, "dart")) return .dart; if (eq(extension, "vue")) return .vue; if (eq(extension, "svelte")) return .svelte; return null;}fn eq(a: []const u8, b: []const u8) bool { return std.ascii.eqlIgnoreCase(a, b);}test "language names and paths cover common source files" { try std.testing.expectEqual(Language.zig, fromName("zig").?); try std.testing.expectEqual(Language.shell, fromName("bash").?); try std.testing.expectEqual(Language.javascript, fromName("jsx").?); try std.testing.expectEqual(Language.typescript, fromName("tsx").?); try std.testing.expectEqual(Language.cpp, fromName("c++").?); try std.testing.expectEqual(Language.csharp, fromName("c#").?); try std.testing.expectEqual(Language.rust, fromPath("src/main.rs").?); try std.testing.expectEqual(Language.typescript, fromPath("src/app.tsx").?); try std.testing.expectEqual(Language.chiclet, fromName("chiclet").?); try std.testing.expectEqual(Language.lisp, fromName("lisp").?); try std.testing.expectEqual(Language.chiclet, fromPath("src/program.chic").?); try std.testing.expectEqual(Language.chiclet, fromPath(".chic").?); try std.testing.expectEqual(Language.shell, fromPath("/home/me/.zshrc").?); try std.testing.expectEqualStrings("sh", name(.shell));}Source: lib/syn/src/root.zig:38
zig
pub const language = @import("language.zig");Audit
| Definitions | 1 |
|---|---|
| Public names | 1 |
| Members | 0 |
| Version | 26.7.0 |
| Revision | daab053ee433 |