111 lines
3.2 KiB
Ruby
111 lines
3.2 KiB
Ruby
|
# -*- coding: utf-8 -*- #
|
||
|
# frozen_string_literal: true
|
||
|
|
||
|
module Rouge
|
||
|
module Lexers
|
||
|
class Mason < TemplateLexer
|
||
|
title 'Mason'
|
||
|
desc 'The HTML::Mason framework (https://metacpan.org/pod/HTML::Mason)'
|
||
|
tag 'mason'
|
||
|
filenames '*.mi', '*.mc', '*.mas', '*.m', '*.mhtml', '*.mcomp', 'autohandler', 'dhandler'
|
||
|
mimetypes 'text/x-mason', 'application/x-mason'
|
||
|
|
||
|
def initialize(*)
|
||
|
super
|
||
|
@perl = Perl.new
|
||
|
end
|
||
|
|
||
|
# Note: If you add a tag in the lines below, you also need to modify "disambiguate '*.m'" in file disambiguation.rb
|
||
|
TEXT_BLOCKS = %w(text doc)
|
||
|
PERL_BLOCKS = %w(args flags attr init once shared perl cleanup filter)
|
||
|
COMPONENTS = %w(def method)
|
||
|
|
||
|
state :root do
|
||
|
mixin :mason_tags
|
||
|
end
|
||
|
|
||
|
state :mason_tags do
|
||
|
rule %r/\s+/, Text::Whitespace
|
||
|
|
||
|
rule %r/<%(#{TEXT_BLOCKS.join('|')})>/oi, Comment::Preproc, :text_block
|
||
|
|
||
|
rule %r/<%(#{PERL_BLOCKS.join('|')})>/oi, Comment::Preproc, :perl_block
|
||
|
|
||
|
rule %r/(<%(#{COMPONENTS.join('|')}))([^>]*)(>)/oi do |m|
|
||
|
token Comment::Preproc, m[1]
|
||
|
token Name, m[3]
|
||
|
token Comment::Preproc, m[4]
|
||
|
push :component_block
|
||
|
end
|
||
|
|
||
|
# perl line
|
||
|
rule %r/^(%)(.*)$/ do |m|
|
||
|
token Comment::Preproc, m[1]
|
||
|
delegate @perl, m[2]
|
||
|
end
|
||
|
|
||
|
# start of component call
|
||
|
rule %r/<%/, Comment::Preproc, :component_call
|
||
|
|
||
|
# start of component with content
|
||
|
rule %r/<&\|/ do
|
||
|
token Comment::Preproc
|
||
|
push :component_with_content
|
||
|
push :component_sub
|
||
|
end
|
||
|
|
||
|
# start of component substitution
|
||
|
rule %r/<&/, Comment::Preproc, :component_sub
|
||
|
|
||
|
# fallback to HTML until a mason tag is encountered
|
||
|
rule(/(.+?)(?=(<\/?&|<\/?%|^%|^#))/m) { delegate parent }
|
||
|
|
||
|
# if we get here, there's no more mason tags, so we parse the rest of the doc as HTML
|
||
|
rule(/.+/m) { delegate parent }
|
||
|
end
|
||
|
|
||
|
state :perl_block do
|
||
|
rule %r/<\/%(#{PERL_BLOCKS.join('|')})>/oi, Comment::Preproc, :pop!
|
||
|
rule %r/\s+/, Text::Whitespace
|
||
|
rule %r/^(#.*)$/, Comment
|
||
|
rule(/(.*?[^"])(?=<\/%)/m) { delegate @perl }
|
||
|
end
|
||
|
|
||
|
state :text_block do
|
||
|
rule %r/<\/%(#{TEXT_BLOCKS.join('|')})>/oi, Comment::Preproc, :pop!
|
||
|
rule %r/\s+/, Text::Whitespace
|
||
|
rule %r/^(#.*)$/, Comment
|
||
|
rule %r/(.*?[^"])(?=<\/%)/m, Comment
|
||
|
end
|
||
|
|
||
|
state :component_block do
|
||
|
rule %r/<\/%(#{COMPONENTS.join('|')})>/oi, Comment::Preproc, :pop!
|
||
|
rule %r/\s+/, Text::Whitespace
|
||
|
rule %r/^(#.*)$/, Comment
|
||
|
mixin :mason_tags
|
||
|
end
|
||
|
|
||
|
state :component_with_content do
|
||
|
rule %r/<\/&>/ do
|
||
|
token Comment::Preproc
|
||
|
pop!
|
||
|
end
|
||
|
|
||
|
mixin :mason_tags
|
||
|
end
|
||
|
|
||
|
state :component_sub do
|
||
|
rule %r/&>/, Comment::Preproc, :pop!
|
||
|
|
||
|
rule(/(.*?)(?=&>)/m) { delegate @perl }
|
||
|
end
|
||
|
|
||
|
state :component_call do
|
||
|
rule %r/%>/, Comment::Preproc, :pop!
|
||
|
|
||
|
rule(/(.*?)(?=%>)/m) { delegate @perl }
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|