circumscribe
v0.3.1
Published
A ligthweight macro system.
Maintainers
Readme
Circumscribe
A general-purpose macro processing tool in ~1.000 lines of TS.
Introduction
Circrumscribe is a tool that traverses the directory it's run from, searching for “cicumscribed“ files, and substitutes all expressions within them. A file is considered circumscribed if its basename is surrounded by a pair of angle brackets (<example>.txt).
A circumscribed file contains the literal source together with an arbitrary amount of substitutions. A substitution is an expression surrounded by the same pair of angle brackets (foo <(expr)> bar). All such expressions are processed by circumscribed and replaced with their result.
// <foo>.json
{
"name": "<name>",
"age": <age>
}[!NOTE] When initially designing Circumscribe, the idea of having a dedicated file extension was considered. However, I found that by having the extention intact, we keep tooling support at its highest, while providing a convention that's unique enough to not trigger unwillingly. ...And gain a whole bunch of personality!
.circumscribe
Similarly to (hopefully) most macroing tools, circumscribe ships a dedicated macro language that allows you to achieve quite a lot despite its simplicity. At its core lies a philosophy of "everything is a snippet". Indeed, the only type present in circumscribe are snippets.
The .circumscribe file consists of an arbitrary number of macro definitions. Each definition describes a name-replacement pair. Once defined, the macro may be called by its name. To define a macro, begin with def, followed by a name, : and the replacement:
def version: |0.1.0|The right-hand side of the definition is an expression. The most basic type of an expression is a so-called snippet.
A snippet is marked by two vertical bars (|) surrounding it and acts as a multiline string in most programming languages. Anything in-between the bars is taken literally from the source, similarly to the <pre> element in HTML.
A snippet may include further placeholders in their usual syntax of <(expression)>:
def version: |0.1.0|
def description: |A lightweight macro system \| v<version>|[!NOTE] Following the C convention, a backslash (
\) may be used to escape a whole bunch of characters within snippet literals. Outside of snippets, however, such as within circumscribed files, special backslash handling could introduce incompatibilites with the rest of the source.Since
<is the only specially-handled sequence within circumscribed sources, one may wish to escape it. To do, given the lack of backslash-escapes, we recommend: Not escaping it at all. Instead, embrace the replacement logic:# <math-homework>.txt 5 <|<|> 7
circumscribe.json
The behavior of circumscribe may be configured through the circumscribe.json config in the directory you call circumscribe from:
{
"structure": {
// The root directory to search for circumscribed
// files in, defaults to pwd
"root": "./src",
// The sources directory to output the processed files
// to, defaults to pwd
"build": "./build",
// The glob patterns to ignore when substituting. If 'mirror'
// is enabled, matching files aren't be copied either.
"ignore": ["..."]
},
// Whether to copy uncircumscribed files
// from sources/ to the build/ directory
"mirror": true
}