1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
|
# -*- coding: utf-8 -*- #
# frozen_string_literal: true
# Adapted from pygments PostScriptLexer
module Rouge
module Lexers
class PostScript < RegexLexer
title "PostScript"
desc "The PostScript language (adobe.com/devnet/postscript.html)"
tag "postscript"
aliases "postscr", "postscript", "ps", "eps"
filenames "*.ps", "*.eps"
mimetypes "application/postscript"
def self.detect?(text)
return true if /^%!/ =~ text
end
delimiter = %s"()<>\[\]{}/%\s"
delimiter_end = Regexp.new("(?=[#{delimiter}])")
valid_name_chars = Regexp.new("[^#{delimiter}]")
valid_name = /#{valid_name_chars}+#{delimiter_end}/
# These keywords taken from
# <http://www.math.ubc.ca/~cass/graphics/manual/pdf/a1.pdf>
# Is there an authoritative list anywhere that doesn't involve
# trawling documentation?
keywords = %w/abs add aload arc arcn array atan begin
bind ceiling charpath clip closepath concat
concatmatrix copy cos currentlinewidth currentmatrix
currentpoint curveto cvi cvs def defaultmatrix
dict dictstackoverflow div dtransform dup end
exch exec exit exp fill findfont floor get
getinterval grestore gsave identmatrix idiv
idtransform index invertmatrix itransform length
lineto ln load log loop matrix mod moveto
mul neg newpath pathforall pathbbox pop print
pstack put quit rand rangecheck rcurveto repeat
restore rlineto rmoveto roll rotate round run
save scale scalefont setdash setfont setgray
setlinecap setlinejoin setlinewidth setmatrix
setrgbcolor shfill show showpage sin sqrt
stack stringwidth stroke strokepath sub syntaxerror
transform translate truncate typecheck undefined
undefinedfilename undefinedresult/
state :root do
# All comment types
rule %r'^%!.+?$', Comment::Preproc
rule %r'%%.*?$', Comment::Special
rule %r'(^%.*?$){2,}', Comment::Multiline
rule %r'%.*?$', Comment::Single
# String literals are awkward; enter separate state.
rule %r'\(', Str, :stringliteral
# References
rule %r'/#{valid_name}', Name::Variable
rule %r'[{}<>\[\]]', Punctuation
rule %r'(?:#{keywords.join('|')})#{delimiter_end}', Name::Builtin
# Conditionals / flow control
rule %r'(eq|ne|g[et]|l[et]|and|or|not|if(?:else)?|for(?:all)?)#{delimiter_end}', Keyword::Reserved
rule %r'(false|true)#{delimiter_end}', Keyword::Constant
# Numbers
rule %r'<[0-9A-Fa-f]+>#{delimiter_end}', Num::Hex
# Slight abuse: use Oct to signify any explicit base system
rule %r'[0-9]+\#(\-|\+)?([0-9]+\.?|[0-9]*\.[0-9]+|[0-9]+\.[0-9]*)((e|E)[0-9]+)?#{delimiter_end}', Num::Oct
rule %r'(\-|\+)?([0-9]+\.?|[0-9]*\.[0-9]+|[0-9]+\.[0-9]*)((e|E)[0-9]+)?#{delimiter_end}', Num::Float
rule %r'(\-|\+)?[0-9]+#{delimiter_end}', Num::Integer
# Names
rule valid_name, Name::Function # Anything else is executed
rule %r'\s+', Text
end
state :stringliteral do
rule %r'[^()\\]+', Str
rule %r'\\', Str::Escape, :escape
rule %r'\(', Str, :stringliteral
rule %r'\)', Str, :pop!
end
state :escape do
rule %r'[0-8]{3}|n|r|t|b|f|\\|\(|\)', Str::Escape, :pop!
end
end
end
end
|