Spezifikation Specification
Monochromator
Syntax-Highlighting mit einem Akzent statt einem Dutzend Farben. Diese Seite ist die Referenz: so soll Monochromator in jedem Editor aussehen. Syntax highlighting with one accent instead of a dozen colors. This page is the reference: this is how Monochromator should look, in every editor.
MIT-LizenzMIT license · Downloads · offene Issuesopen issues
// Palette bundles the color values of a single mode (dark/light).
type Palette struct {
BG string `json:"bg"`
FG string `json:"fg"`
Accent string `json:"accent"`
}
// Pick returns the dark or light value depending on the mode.
func Pick(mode, dark, light string) string {
if mode == "dark" {
return dark
}
return light
}
func (p Palette) Color(name string) (string, error) {
switch name {
case "blue":
return p.Blue, nil
case "magenta":
return p.Magenta, nil
default:
return "", fmt.Errorf("unknown color %q", name)
}
}
func Load(dir string) (*Config, error) {
data, err := os.ReadFile(filepath.Join(dir, "base.json"))
if err != nil {
return nil, fmt.Errorf("loading base palette: %w", err)
}
var palettes map[string]Palette
if err := json.Unmarshal(data, &palettes); err != nil {
return nil, fmt.Errorf("parsing base palette: %w", err)
}
return &Config{Palettes: palettes}, nil
}#[derive(Debug, Clone, PartialEq)]
pub struct Token {
pub text: String,
pub pos: usize,
}
/// A lexer over the beta-code apparatus.
pub struct Lexer<'a> {
input: &'a str,
pos: usize,
}
impl<'a> Lexer<'a> {
pub fn new(input: &'a str) -> Self {
Self { input, pos: 0 }
}
/// Converts a beta-code letter with its diacritics into Unicode.
pub fn convert(&mut self, c: char) -> Result<char, ParseError> {
self.pos += 1;
match c {
'a'..='z' => Ok(BASE[(c as u8 - b'a') as usize]),
')' => Ok('\u{0313}'),
'(' => Ok('\u{0314}'),
_ => Err(ParseError::new(
self.pos,
format!("unknown character {c:?}"),
)),
}
}
pub fn words(&self) -> impl Iterator<Item = &str> + '_ {
self.input.split_whitespace().filter(|w| !w.is_empty())
}
}type Mode = "dark" | "light"
interface Verse {
v: number
t: string
}
interface Chapter {
book: string
vs: Verse[]
}
const CACHE = new Map<string, Chapter>()
/**
* Loads a chapter from the static data store.
* @param ref Canonical reference, e.g. "MT/5"
*/
export async function loadChapter(ref: string): Promise<Chapter | null> {
const cached = CACHE.get(ref)
if (cached !== undefined) return cached
const res = await fetch(`/data/ntg/text/${ref}.json`)
if (!res.ok) return null
const data: Chapter = await res.json()
CACHE.set(ref, data)
return data
}
export function wordCount(ch: Chapter): number {
return ch.vs
.filter((verse) => verse.t !== "")
.reduce((sum, verse) => sum + verse.t.split(/\s+/).length, 0)
}_CV_RE = re.compile(r"\\c\s+(\d+)|\\v\s+(\d+)(?:-\d+)?\s?")
@dataclass
class Chapter:
"""A chapter with the authoritative Greek verse numbering."""
number: int
verses: dict[int, str]
@property
def is_empty(self) -> bool:
return not any(self.verses.values())
def parse_usfm(book_text):
"""Return {chapter -> {verse -> clean_text}} for one USFM book."""
chapters = {}
cur_ch = None
for i, m in enumerate(_CV_RE.finditer(book_text)):
if m.group(1) is not None: # \c
cur_ch = int(m.group(1))
chapters.setdefault(cur_ch, {})
elif cur_ch is not None: # \v
v = int(m.group(2))
chapters[cur_ch][v] = strip_markup(m.string[m.end():])
return chapters
def report(chapters: list[Chapter]) -> bool:
empty = [c.number for c in chapters if c.is_empty]
if empty:
print(f"empty: {len(empty)} chapters, e.g. {empty[0]}")
return len(empty) == 0#include <errno.h>
#include <stdio.h>
#include <string.h>
#define KEY_LEN 32
enum key_state { KEY_EMPTY = 0, KEY_LOADED, KEY_WIPED };
struct key {
unsigned char bytes[KEY_LEN];
enum key_state state;
};
int read_key(struct key *k, FILE *fp);
/* Zeroes the buffer before key material is released. */
static void bzero_explicit(unsigned char *buf, size_t len) {
volatile unsigned char *p = buf;
while (len--)
*p++ = 0;
}
int main(void) {
struct key k = { .state = KEY_EMPTY };
if (read_key(&k, stdin) != 0) {
fprintf(stderr, "no key: %s\n", strerror(errno));
return 1;
}
printf("loaded: %d bytes\n", KEY_LEN);
bzero_explicit(k.bytes, sizeof k.bytes);
k.state = KEY_WIPED;
return 0;
}#include <algorithm>
#include <string>
#include <string_view>
#include <vector>
namespace ntg {
// A hit in the apparatus: position plus reading.
struct Hit {
std::size_t pos;
std::string reading;
};
template <typename Pred>
std::vector<Hit> collect(std::string_view text, Pred keep) {
std::vector<Hit> hits;
for (std::size_t i = 0; i < text.size(); ++i) {
if (keep(text[i])) {
hits.push_back({i, std::string{text[i]}});
}
}
return hits;
}
constexpr auto is_sigla = [](char c) { return c == '*' || c == '#'; };
int count_sigla(std::string_view text) {
auto hits = collect(text, is_sigla);
std::sort(hits.begin(), hits.end(),
[](const Hit& a, const Hit& b) { return a.pos < b.pos; });
return static_cast<int>(hits.size());
}
} // namespace ntg# Monochromator
Distraction-free **monochrome** theme for VS Code and Zed.
## Installation
1. Open the Extensions view (`Ctrl+Shift+X`)
2. Search for *Monochromator*
3. Or install directly via [Open VSX](https://open-vsx.org/extension/beem/monochromator)
> For 100 % correct behavior, set `editor.bracketPairColorization.enabled`
> to `false`.
## Variants
| Variant | Accent |
|---------|--------|
| Default | Blue |
| Ruby | Red |
Use \* to write a literal asterisk, ~~struck~~ works too.% Minimal article: one lemma, one equation.
\documentclass[11pt]{article}
\usepackage{amsmath}
\usepackage{amsthm}
\newtheorem{lemma}{Lemma}
\title{On the Grating Equation}
\author{J. Beem}
\begin{document}
\maketitle
\section{Setup}
The wavelength follows from $m\lambda = d\sin\theta_m$, where $m$
is the diffraction order.
\begin{lemma}
For the sodium D line, $\lambda = 589.3\,\mathrm{nm}$.
\end{lemma}
\begin{equation}
E = h\nu = \frac{hc}{\lambda}
\end{equation}
\end{document}