Skip to content

Commit

Permalink
Add Perl 6 Pod lexer
Browse files Browse the repository at this point in the history
  • Loading branch information
Tyil committed Aug 29, 2018
1 parent 27a4bfb commit 2991fa9
Show file tree
Hide file tree
Showing 3 changed files with 445 additions and 0 deletions.
123 changes: 123 additions & 0 deletions lib/rouge/demos/perl6pod
@@ -0,0 +1,123 @@
#! /usr/bin/env perl6

=begin pod
=NAME Test Program for Pod::To::Parser
=AUTHOR Patrick Spek
=VERSION 0.0.1
=begin LICENSE
GNU Affero GPLN<Version 3>
=end LICENSE
=head1 A test program for App::POD::Manual
Now we're reaching the real POD document that I care about. Let's add in some
test cases as well here.
=head2 Text styles
=item1 This text is B<bold>
=item1 This text is I<italic>
=item1 This text is U<underlined>
=item1 This text is C<code>
=item1 This text is L<a link|https://www.tyil.work> to my blog
=item1 This text is normal Z<or is it?>
=item1 I'm running ouf of ideas N<Search the Internet for more!>
=head2 Lists
=item2 Starting off at level 2
=item5 Progressing to level 5
=item1 Back to level 1
=item2 On to level 2
=item3 On to level 3
=item4 On to level 4
=item8 But what about an item with content that goes well beyond the 80 characters?
=begin item10
Which can easily occur in a block item, for instance. It should wrap around
and bring the next lines on a similar level of indentation.
The question is, does it?
=end item10
=head3 Definition lists
=defn pod
Plain Ol' Documentation
=defn foo
Not the same as bar
=head2 Code blocks
Now on to some code blocks. These are generally used to show code samples.
This is a code block. It is indented by 4 spaces to indicate this.
Code samples are important to easily show a user how to interact with the
program they're using. Nobody wants to read through pages of a manual when they
just want to know how to use it for their particular use case.
=begin code :name<Named code block>
This is a code block by name. It is covered by a begin and end block. It has no limit to line length.
Spaces in the code are preserved .
Similar for newlines, actually.
=end code
=code Code on a single line should also work as expected.
And that concludes the test for code blocks!
=head2 IO blocks
There are blocks to denote program input and output, called IO blocks. They
also have in-line variants:
=item1 This is K<keyboard input>
=item1 This is T<terminal output>
The bigger blocks deserve a test as well, I think:
=head3 Short-hand input and output
=input A simple input line
=output A simple output line
=head3 Big input and output blocks
=begin input
A larger block of input.
=end input
=begin output
A larger block of output.
=end output
=head2 Unicode
And of course, let's throw in some Unicode stuff. I stole these examples from
the documentation site, but I don't think that's a bad source of input for
testing purposes.
Perl 6 makes considerable use of the E<171> and E<187> characters.
Perl 6 makes considerable use of the E<laquo> and E<raquo> characters.N<Not sure why these don't work>
Perl 6 makes considerable use of the E<0b10101011> and E<0b10111011> characters.
Perl 6 makes considerable use of the E<0o253> and E<0o273> characters.
Perl 6 makes considerable use of the E<0d171> and E<0d187> characters.
Perl 6 makes considerable use of the E<0xAB> and E<0xBB> characters.
=head2 Conclusion
And that concludes this test file. If everything looked good in your tests, you
may now be confident about your work.
=end pod
199 changes: 199 additions & 0 deletions lib/rouge/lexers/perl6pod.rb
@@ -0,0 +1,199 @@
# -*- coding: utf-8 -*- #

module Rouge
module Lexers
class Pod6 < RegexLexer
title "Perl 6 Pod"
desc "Perl 6 Plain' Ol Documentation (perl6.org)"

tag 'perl6pod'
aliases 'pod6'

filenames '*.pod', '*.pod6'

state :root do
rule(/\=begin pod/m, Keyword, :pod6)
rule(/^#.*$/, Comment)
end

state :pod6 do
rule(/\=end pod/m, Keyword, :pop!)

rule(/\=NAME/, Keyword, :semantic)
rule(/\=AUTHOR/, Keyword, :semantic)
rule(/\=VERSION/, Keyword, :semantic)
rule(/\=TITLE/, Keyword, :semantic)
rule(/\=SUBTITLE/, Keyword, :semantic)

rule(/\=begin code/, Keyword, :block_code)
rule(/\=begin input/, Keyword, :block_input)
rule(/\=begin output/, Keyword, :block_output)
rule(/\=begin/, Keyword, :block)

rule(/\=head(\d+)\s+/, Keyword, :head)
rule(/\=item(\d+)\s+/, Keyword, :item)
rule(/\=input/, Keyword, :input)
rule(/\=output/, Keyword, :output)
rule(/\=defn/, Keyword)

rule(/B\</, Punctuation::Indicator, :formatting_b)
rule(/C\</, Punctuation::Indicator, :formatting_c)
rule(/E\</, Punctuation::Indicator, :formatting_e)
rule(/I\</, Punctuation::Indicator, :formatting_i)
rule(/K\</, Punctuation::Indicator, :formatting_k)
rule(/L\</, Punctuation::Indicator, :formatting_l)
rule(/N\</, Punctuation::Indicator, :formatting_n)
rule(/T\</, Punctuation::Indicator, :formatting_t)
rule(/U\</, Punctuation::Indicator, :formatting_u)
rule(/Z\</, Punctuation::Indicator, :formatting_z)

rule(/^(?:\t|\s{4,})/, Other, :code)

rule(/./, Text)
end

state :semantic do
rule(/.+\n/, Name, :pop!)
end

state :head do
rule(/\n/, Text::Whitespace, :pop!)

rule(/:\w+\</, Name::Attribute, :attribute)

rule(/./, Generic::Heading)
end

state :item do
rule(/\n/, Text::Whitespace, :pop!)

rule(/B\</, Punctuation::Indicator, :formatting_b)
rule(/C\</, Punctuation::Indicator, :formatting_c)
rule(/E\</, Punctuation::Indicator, :formatting_e)
rule(/I\</, Punctuation::Indicator, :formatting_i)
rule(/K\</, Punctuation::Indicator, :formatting_k)
rule(/L\</, Punctuation::Indicator, :formatting_l)
rule(/N\</, Punctuation::Indicator, :formatting_n)
rule(/T\</, Punctuation::Indicator, :formatting_t)
rule(/U\</, Punctuation::Indicator, :formatting_u)
rule(/Z\</, Punctuation::Indicator, :formatting_z)

rule(/./, Generic)
end

state :input do
rule(/\n/, Text::Whitespace, :pop!)

rule(/./, Generic::Inserted)
end

state :output do
rule(/\n/, Text::Whitespace, :pop!)

rule(/./, Generic::Output)
end

state :code do
rule(/.*$/, Generic::Output, :pop!)
end

state :attribute do
rule(/\>/, Name::Attribute, :pop!)

rule(/./, Name)
end

state :block do
# TODO: Check the name of the block, and make sure the =end matches
# the same name

rule(/:\w+\</, Name::Attribute, :attribute)
rule(/\=end/, Keyword, :pop!)

rule(/B\</, Punctuation::Indicator, :formatting_b)
rule(/C\</, Punctuation::Indicator, :formatting_c)
rule(/E\</, Punctuation::Indicator, :formatting_e)
rule(/I\</, Punctuation::Indicator, :formatting_i)
rule(/K\</, Punctuation::Indicator, :formatting_k)
rule(/L\</, Punctuation::Indicator, :formatting_l)
rule(/N\</, Punctuation::Indicator, :formatting_n)
rule(/T\</, Punctuation::Indicator, :formatting_t)
rule(/U\</, Punctuation::Indicator, :formatting_u)
rule(/Z\</, Punctuation::Indicator, :formatting_z)

rule(/./, Generic)
end

state :block_code do
rule(/:\w+\</, Name::Attribute, :attribute)
rule(/\=end code/, Keyword, :pop!)

rule(/./, Generic::Output)
end

state :block_input do
rule(/:\w+\</, Name::Attribute, :attribute)
rule(/\=end input/, Keyword, :pop!)

rule(/./, Generic::Inserted)
end

state :block_output do
rule(/:\w+\</, Name::Attribute, :attribute)
rule(/\=end output/, Keyword, :pop!)

rule(/./, Generic::Output)
end

state :formatting_b do
rule(/\>/, Punctuation::Indicator, :pop!)
rule(/.*?(?=\>)/, Generic::Strong)
end

state :formatting_c do
rule(/\>/, Punctuation::Indicator, :pop!)
rule(/.*?(?=\>)/, Generic::Output)
end

state :formatting_e do
rule(/\>/, Punctuation::Indicator, :pop!)
rule(/.*?(?=\>)/, Literal::Number::Other)
end

state :formatting_i do
rule(/\>/, Punctuation::Indicator, :pop!)
rule(/.*?(?=\>)/, Generic::Emph)
end

state :formatting_k do
rule(/\>/, Punctuation::Indicator, :pop!)
rule(/.*?(?=\>)/, Generic::Inserted)
end

state :formatting_l do
rule(/\>/, Punctuation::Indicator, :pop!)
rule(/.*?(?=\>)/, Other)
end

state :formatting_n do
rule(/\>/, Punctuation::Indicator, :pop!)
rule(/.*?(?=\>)/, Comment::Special)
end

state :formatting_t do
rule(/\>/, Punctuation::Indicator, :pop!)
rule(/.*?(?=\>)/, Generic::Output)
end

state :formatting_u do
rule(/\>/, Punctuation::Indicator, :pop!)
rule(/.*?(?=\>)/, Generic)
end

state :formatting_z do
rule(/\>/, Punctuation::Indicator, :pop!)
rule(/.*?(?=\>)/, Comment)
end
end
end
end

0 comments on commit 2991fa9

Please sign in to comment.