feat(cheddar): Override syntax highlighting for 'rules.pl' to Prolog

Adds a mechanism for per-filename overrides of the chosen language
syntax and configures it for Gerrit's submit rule file.

This also switches the syntax set used to the one from
//third_party/bat_syntaxes, which contains custom additions such as
Prolog support.

Change-Id: I2023dbad5b326305ef2ef0ecf34ef66a3f7575ab
Reviewed-on: https://cl.tvl.fyi/c/depot/+/349
Reviewed-by: riking <rikingcoding@gmail.com>
Reviewed-by: lukegb <lukegb@tvl.fyi>
This commit is contained in:
Vincent Ambo 2020-06-15 00:19:36 +01:00 committed by tazjin
parent 0b95b8632d
commit 9885b70b7a
2 changed files with 34 additions and 17 deletions

View file

@ -1,20 +1,17 @@
{ depot, ... }:
{ pkgs, ... }:
with depot.third_party;
naersk.buildPackage {
pkgs.naersk.buildPackage {
src = ./.;
doDoc = false;
doCheck = false;
override = x: {
# bat contains syntax highlighting packages for a lot more
# languages than what ships with syntect, and we can make use of
# them!
BAT_SYNTAXES = "${bat.src}/assets/syntaxes.bin";
# Use our custom bat syntax set, which is everything from upstream,
# plus additional languages we care about.
BAT_SYNTAXES = "${pkgs.bat_syntaxes}";
# LLVM packages (why are they even required?) are not found
# automatically if added to buildInputs, hence this ...
LIBCLANG_PATH = "${llvmPackages.libclang}/lib/libclang.so.10";
LIBCLANG_PATH = "${pkgs.llvmPackages.libclang}/lib/libclang.so.10";
};
}

View file

@ -3,6 +3,7 @@ use comrak::nodes::{Ast, AstNode, NodeValue, NodeCodeBlock, NodeHtmlBlock};
use comrak::{Arena, parse_document, format_html, ComrakOptions};
use lazy_static::lazy_static;
use std::cell::RefCell;
use std::collections::HashMap;
use std::env;
use std::ffi::OsStr;
use std::io::BufRead;
@ -42,12 +43,23 @@ lazy_static! {
unsafe_: true, // required for tagfilter
..ComrakOptions::default()
};
// Configures a map of specific filenames to languages, for cases
// where the detection by extension or other heuristics fails.
static ref FILENAME_OVERRIDES: HashMap<&'static str, &'static str> = {
let mut map = HashMap::new();
// rules.pl is the canonical name of the submit rule file in
// Gerrit, which is written in Prolog.
map.insert("rules.pl", "Prolog");
map
};
}
// HTML fragment used when rendering inline blocks in Markdown documents.
// Emulates the GitHub style (subtle background hue and padding).
const BLOCK_PRE: &str = "<pre style=\"background-color:#f6f8fa;padding:16px;\">\n";
#[derive(Debug, Default)]
struct Args {
/// Should Cheddar run as an about filter? (i.e. give special
/// rendering treatment to Markdown documents)
@ -55,16 +67,16 @@ struct Args {
/// What file extension has been supplied (if any)?
extension: Option<String>,
/// Which language to override the detection to (if any)?
lang_override: Option<&'static str>,
}
/// Parse the command-line flags passed to cheddar to determine
/// whether it is running in about-filter mode (`--about-filter`) and
/// what file extension has been supplied.
fn parse_args() -> Args {
let mut args = Args {
about_filter: false,
extension: None,
};
let mut args = Args::default();
for (i, arg) in env::args().enumerate() {
if i == 0 {
@ -76,6 +88,10 @@ fn parse_args() -> Args {
continue;
}
if let Some(lang) = (*FILENAME_OVERRIDES).get(arg.as_str()) {
args.lang_override = Some(lang);
}
args.extension = Path::new(&arg)
.extension()
.and_then(OsStr::to_str)
@ -244,7 +260,7 @@ fn format_markdown() {
.expect("Markdown rendering failed");
}
fn format_code(extension: Option<&str>) {
fn format_code(args: &Args) {
let stdin = io::stdin();
let mut stdin = stdin.lock();
let mut linebuf = String::new();
@ -255,8 +271,12 @@ fn format_code(extension: Option<&str>) {
// Set up the highlighter
let theme = &THEMES.themes["InspiredGitHub"];
let syntax = extension
.and_then(|e| SYNTAXES.find_syntax_by_extension(e))
let syntax = args.lang_override
.and_then(|l| SYNTAXES.find_syntax_by_name(l))
.or_else(|| match args.extension {
Some(ref ext) => SYNTAXES.find_syntax_by_extension(ext),
None => None,
})
.or_else(|| SYNTAXES.find_syntax_by_first_line(&linebuf))
.unwrap_or_else(|| SYNTAXES.find_syntax_plain_text());
@ -296,6 +316,6 @@ fn main() {
match args.extension.as_ref().map(String::as_str) {
Some("md") if args.about_filter => format_markdown(),
extension => format_code(extension),
_ => format_code(&args),
}
}