Table of Contents
NAME
Syntax::Highlighters
AUTHOR
Francis Grizzly Smit (grizzly@smit.id.au)
VERSION
0.1.5
TITLE
Syntax::Highlighters
SUBTITLE
A Raku module to do basic syntax highlighting.
COPYRIGHT
LGPL V3.0+ LICENSE
Top of Document
Introduction
Some syntax highlighting stuff: grammars to parse basic Raku forms and highlight them with colours. And functions to use them.
NB: by no means complete or exhaustive (as yet at least), and no way to parse expressions etc.
Top of Document
HighlighterFailed
An Exception class for reporting errors in parsing.
class HighlighterFailed is Exception is export {
has Str:D $.msg = 'Error: Highlighter Failed.';
method message( --> Str:D) {
$!msg;
}
}
Top of Document
VariablesBase
A grammar for parsing variable forms forms the basis of Variables which syntax highlights variable forms.
VariablesBaseActions
A role to assist in the parsing variable forms forms the basis of VariablesActions which syntax highlights variable forms.
Top of Document
Variables and VariablesActions
The grammar and class pair that do the actual syntax highlighting of the variable forms.
NB: Uses VariablesBase and VariablesBaseActions to do the actual parsing.
grammar Variables is VariablesBase is export {
token TOP { <var> }
}
class VariablesActions does VariablesBaseActions is export {
method TOP($made) {
my %spec = $made<var>.made;
my Str $top = t.color(255,0,0) ~ %spec«sigil»;
if %spec«twigil» eq '<' {
$top ~= t.color(0,255,255) ~ '<' ~ %spec«name» ~ '>';
} elsif %spec«type» eq 'Failed' {
$top ~= t.color(255,0,0) ~ %spec«name»;
} else {
$top ~= %spec«twigil» ~ t.color(0,255,255) ~ %spec«name»;
}
if %spec«derref»:exists && (%spec«derref»«derref-char»:exists) {
if %spec«derref»«derref-char» eq '[' {
$top ~= t.color(255,0,0) ~ '[' ~ t.color(255,0,255) ~ %spec«derref»«ind» ~ t.color(255,0,0) ~ ']';
} elsif %spec«derref»«derref-char» eq '«' {
$top ~= t.color(255,74,0) ~ '«' ~ %spec«derref»«ind» ~ '»';
} elsif %spec«derref»«derref-char» eq '<' {
$top ~= t.color(255,0,0) ~ '<' ~ t.color(255,0,255) ~ %spec«derref»«ind» ~ t.color(255,0,0) ~ '>';
} elsif %spec«derref»«derref-char» eq '{' {
$top ~= t.color(255,0,0) ~ '{$' ~ t.color(255,0,255) ~ %spec«derref»«ind» ~ t.color(255,0,0) ~ '}';
} elsif %spec«derref»«derref-char» eq '(' {
$top ~= t.color(255,0,0) ~ '(' ~ t.color(255,0,255) ~ %spec«derref»«ind» ~ t.color(255,0,0) ~ ')';
}
}
$made.make: $top;
}
}
Top of Document
ValueBase and ValueBaseActions
ValueBase and ValueBaseActions are a grammar role pair that implement parsing of Raku style values.
NB: not comprehensive nor complete (yet at least).
Value and ValueActions
Value and ValueActions are a grammar class pair that implements syntax highlighting of Raku style values, using ValueBase and ValueBaseActions, as the parsing work horse.
grammar Value is ValueBase is export {
token TOP { ^ <value> $ }
}
class ValueActions does ValueBaseActions is export {
method !highlight(%spec) {
my $highlight = '';
$highlight ~= %spec«space»«val» if %spec«space»;
if %spec«type» eq 'int' {
$highlight ~= t.color(255, 0, 255) ~ %spec«val»;
} elsif %spec«type» eq 'rat-val' {
$highlight ~= t.color(255, 0, 255) ~ %spec«numerator» ~ '/' ~ %spec«denominator»;
} elsif %spec«type» eq 'num' {
$highlight ~= t.color(255, 0, 255) ~ %spec«mantisa»;
$highlight ~= %spec«exponent»«signifitant» ~ %spec«exponent»«sign» ~ %spec«exponent»«exp» if %spec«exponent»;
} elsif %spec«type» eq 'bool' {
$highlight ~= t.color(255, 0, 255) ~ %spec«val»;
} elsif %spec«type» eq 'bare-word' {
$highlight ~= t.color(255, 0, 255) ~ %spec«val»;
} elsif %spec«type» eq 'string' {
$highlight ~= t.color(255, 0, 255) ~ %spec«open» ~ %spec«val» ~ %spec«close»;
} elsif %spec«type» eq 'array-val' {
$highlight ~= t.color(255, 0, 0) ~ '[';
$highlight ~= %spec«a-space»«val» if %spec«a-space»;
my Str:D $sep = '';
my @vals = |%spec«val»;
for @vals -> %val {
$highlight ~= t.color(255, 0, 0) ~ $sep ~ self!highlight(%val);
$sep = ',';
}
$highlight ~= %spec«a-space-after»«val» if %spec«a-space-after»;
$highlight ~= t.color(255, 0, 0) ~ ']';
} elsif %spec«type» eq 'hash-val' {
$highlight ~= t.color(255, 0, 0) ~ '{';
$highlight ~= %spec«h-space»«val» if %spec«h-space»;
my Str:D $sep = '';
my @vals = |%spec«val»;
for @vals -> %val {
$highlight ~= t.color(255, 0, 0) ~ $sep ~ self!highlight(%val);
$sep = ',';
}
$highlight ~= %spec«h-space-after»«val» if %spec«h-space-after»;
$highlight ~= t.color(255, 0, 0) ~ '}';
} elsif %spec«type» eq 'pair0' {
$highlight ~= t.color(255, 0, 255) ~ %spec«key» ~ t.color(255, 0, 0) ~ ' => ' ~ self!highlight(%spec«val»);
} elsif %spec«type» eq 'pair1' {
$highlight ~= t.color(255, 0, 0) ~ ':' ~ t.color(255, 0, 255)
~ %spec«key» ~ t.color(255, 0, 0) ~ '(' ~ self!highlight(%spec«val»)
~ t.color(255, 0, 0) ~ ')';
}
$highlight ~= %spec«space-after»«val» if %spec«space-after»;
return $highlight;
}
method TOP($made) {
my %spec = $made<value>.made;
my Str $top = self!highlight(%spec);
$made.make: $top;
}
} # class ValueActions does ValueBaseActions #
Top of Document
highlight-var
wraps up the actual usage of the grammars above.
Defined as:
sub highlight-var($var --> Str:D) is export {
my $actions = VariablesActions;
my $tmp = Variables.parse($var, :enc('UTF-8'), :$actions).made;;
HighlighterFailed.new(:msg("Error: Variables.parse Failed.")).throw if $tmp === Any;
return $tmp;
} # sub highlight-var($var --> Str:D) is export #
highlight-val
sub highlight-val($val --> Str:D) is export {
my $actions = ValueActions;
my $tmp = Value.parse($val, :enc('UTF-8'), :$actions).made;;
HighlighterFailed.new(:msg("Error: Variables.parse Failed.")).throw if $tmp === Any;
return $tmp;
} # sub highlight-val($val --> Str:D) is export #
Top of Document