From 9885b70b7aa8e90da930a2cab2af9318d4bede88 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Mon, 15 Jun 2020 00:19:36 +0100 Subject: 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 Reviewed-by: lukegb --- tools/cheddar/default.nix | 15 ++++++--------- tools/cheddar/src/main.rs | 36 ++++++++++++++++++++++++++++-------- 2 files changed, 34 insertions(+), 17 deletions(-) (limited to 'tools') diff --git a/tools/cheddar/default.nix b/tools/cheddar/default.nix index 5c86fec482..c65c782e6a 100644 --- a/tools/cheddar/default.nix +++ b/tools/cheddar/default.nix @@ -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"; }; } diff --git a/tools/cheddar/src/main.rs b/tools/cheddar/src/main.rs index 52e518cd82..01e6c868f7 100644 --- a/tools/cheddar/src/main.rs +++ b/tools/cheddar/src/main.rs @@ -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 = "
\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,
+
+    /// 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),
     }
 }
-- 
cgit 1.4.1