Hi Everyone,
I want to write a portable library using DCGs to parse mustache-like templates. The contents of anything inside the mustaches is a term (ie: foo {{some(term)}} bar
).
]
I know about quasi-quotation but I want something more flexible that has these properties:
- Can be embedded in a single file like a markdown or org file, which can be viewed in it’s “raw” form as a form of documentation
- Easy to port to other prolog implementations (ie a DCG)
- Have two versions of the string, the raw implementation that shows the terms inside the mustache that are unprocessed for documentation reasons, and another that can replace callable terms with their values like this:
Raw form:
This is an example of {{append}}:
{{append(X, Y, [1,2,3,4])}}
And you can extract the atom and compound term in the example like this:
Extracted = [append, append(X, Y, [1,2,3,4])]
And then an interpolated form where the atom is interpreted “as is” (depending on how the double_quotes
directive is set), and the callable term is run and the result is stringified:
This is an example of append:
?- append(X, Y, [1,2,3,4]).
X = [],
Y = [1, 2, 3, 4] r
X = [1],
Y = [2, 3, 4] r
X = [1, 2],
Y = [3, 4] r
X = [1, 2, 3],
Y = [4] r
X = [1, 2, 3, 4],
Y = [] r
false.
I’m a newbie at writing DCGs, this is what I have so far:
mustache(Atom) -->
string_without("{{", _), "{{", string(Atom), "}}", string(_).
flip(Functor, X, Y) :-
Goal =.. [Functor, Y, X],
call(Goal).
?- once(phrase(sequence(mustache, Mustaches), `foo{{bar}}baz{{quxx(foo)}}norf`, L)), maplist(flip(atom_chars), Mustaches, M), atom_chars(L2, L).
Mustaches = [[98, 97, 114], [113, 117, 120, 120, 40, 102, 111|...]],
L = [110, 111, 114, 102],
M = [bar, 'quxx(foo)'],
L2 = norf.