== matchertext [[toc:]] == Description ''matchertext'' is a "syntactic discipline" that allows for cross-language embedding of source code. It was invented by Bryan Ford (who also invented parsing expression grammars and packrat parsing). To learn more, see Ford's [[https://bford.info/pub/lang/matchertext/|introductory blog post]], and his [[https://arxiv.org/abs/2212.14129|more substantial paper]]. Briefly (quote from the blog post), The pragmatic essence of the matchertext idea is simple. First, we define six particular ASCII characters as matchers: namely the open and close parentheses (), the square brackets [], and the curly braces {}. We call these characters matchers because their traditional, already-ubiquitous purpose is to be used in matching pairs to surround and delimit other text. Now we define matchertext as any plain text string conforming to one additional rule or “syntactic discipline”: namely that matchers must match, throughout any matchertext string, without exception. Nesting is allowed, but must use corresponding matchers. For example, the string ‘([{foo}])’ is valid matchertext, but strings like ‘(foo’, ‘bar}’, or ‘(]’ are not matchertext. The matchertext egg extends the Scheme language to be able to host matchertext in string literals. == Syntax The syntax for matchertext string literals is as follows. literal <- '#M' nested '"(' mtxt ')"' nested <- '(' nested ')' | '[' nested ']' | '{' nested '}' | ε mtxt <- non-matcher mtxt | '(' mtxt ')' mtxt | '[' mtxt ']' mtxt | '{' mtxt '}' mtxt | ε non-matcher <- any character except one of ()[]{} In the simplest case, {{nested}} matches the empty string in {{literal}}. Then, the {{literal}} is equivalent to a string with contents {{mtxt}}. When {{nested}} matches a non-empty sequence of openers followed by closers: nested ::= openers closers then any string enclosed in {{openers}} and {{closers}} inside {{mtxt}} is interpreted as an Scheme expression that evaluates to a string. This is to allow for interpolation. == Examples (import matchertext) (string=? "Hello, world!" #M"(Hello, world!)") ; #t (string=? "\\([{}])" #M"(\([{{}]))"); #t (define greeting "Hello") (string=? "Hello, world!" #M{}"({greeting}, world)") ; #t == Author [[/users/hernan-ibarra-mejia|Hernán Ibarra Mejia]] == Acknowledgements Many thanks to [[https://github.com/AntoineBastide47|Antoine Bastide]] for helping me with the changes in version 2.0. == Repository Development happens in [[https://git.sr.ht/~nagbu/matchertext|SourceHut]]. == Requirements None (but testing requires the [[test|test egg]]). == Version history ; 2.0 : Port to C6, change to standard syntax, and add support for interpolation. ; 1.0 : Initial release. == License [[https://git.sr.ht/~nagbu/matchertext/blob/main/COPYING|GPLv3]].