package xm::code::perl;

use xm::o;
use xm::code::vars;
use xm::code::func;

sub DESC{"
  highlight sourcecode - PERL mode
"}

# BEGIN {

 
# taken from nedit
# modified by PP
# modified by BS
# modified by JD
# modified by JP
$LANGUAGE{'perl'}       = {
                            'filename'   => '(?i)\\.p([lm5]|od)$',
                            'regex'      => '^\\s*#\\s*![^\\s]*perl',
                            'patterns'   => [
                                              {
                                                'name'       => 'comment',
                                                'regex'      => '(?:#.*?(?:\r?\n\s*)+)+',
                                                'style'      => 'comment',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'variables',
                                                'regex'      => '[\\$@%]\\$?(?:{[^}]*}|[^a-zA-Z0-9_/\\t\\n\\.,\\\\[\\\\{\\\\(]|[0-9]+|[a-zA-Z_][a-zA-Z0-9_]*)?',
                                                'style'      => 'identifier',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => '"" string',
                                                'regex'      => '""|".*?([^\\\\](\\\\\\\\)*)"|"\\\\\\\\"',
#                                                'regex'      => '""|"\\\\\\\\"|"[^"\\\\]"|"[^"].*?[^\\\\]"',
                                                'style'      => 'string',
                                                'childregex' => [
                                                                  {
                                                                    'name'       => 'esc character',
                                                                    'regex'      => '\\\\.',
                                                                    'style'      => 'esc character',
                                                                    'childregex' => []
                                                                  },
                                                                  {
                                                                    'name'       => 'variables',
                                                                    'regex'      => '[\\$@%]\\$?(?:{[^}]*}|[^a-zA-Z0-9_/\\t\\n\\.,\\\\[\\\\{\\\\(]|[0-9]+|[a-zA-Z_][a-zA-Z0-9_]*)?',
                                                                    'style'      => 'identifier',
                                                                    'childregex' => []
                                                                  }
                                                                ]
                                              },
                                              {
                                                'name'       => '\'\' string',
                                                'regex'      => '\'\'|\'.*?([^\\\\](\\\\\\\\)*)\'|\'\\\\\\\\\'',
#                                                'regex'      => '\'\'|\'\\\\\\\\\'|\'[^\'\\\\]\'|\'[^\'].*?[^\\\\]\'',
                                                'style'      => 'string',
                                                'childregex' => [
                                                                  {
                                                                    'name'       => 'esc character',
                                                                    'regex'      => '\\\\.',
                                                                    'style'      => 'esc character',
                                                                    'childregex' => []
                                                                  }
                                                                ]
                                              },
                                              {
                                                'name'       => 'more strings - q// qw//',
                                                'regex'      => '(?:\\b| )(?:q|qw)([^\w\s])(?:\\\\\\2|[^\\2\\n])*\\2',
                                                'style'      => 'string',
                                                'childregex' => [
                                                                  {
                                                                    'name'       => 'esc character',
                                                                    'regex'      => '\\\\.',
                                                                    'style'      => 'esc character',
                                                                    'childregex' => []
                                                                  }
                                                                ]
                                              },
                                              {
                                                'name'       => 'more strings - qq// qx//',
                                                'regex'      => '(?:\\b| )(?:qq|qx)([^\w\s])(?:\\\\\\2|[^\\2\\n])*\\2',
                                                'style'      => 'string',
                                                'childregex' => [
                                                                  {
                                                                    'name'       => 'esc character',
                                                                    'regex'      => '\\\\.',
                                                                    'style'      => 'esc character',
                                                                    'childregex' => []
                                                                  },
                                                                  {
                                                                    'name'       => 'variables',
                                                                    'regex'      => '[\\$@%]\\$?(?:{[^}]*}|[^a-zA-Z0-9_/\\t\\n\\.,\\\\[\\\\{\\\\(]|[0-9]+|[a-zA-Z_][a-zA-Z0-9_]*)?',
                                                                    'style'      => 'identifier',
                                                                    'childregex' => []
                                                                  }
                                                                ]
                                              },
                                              {
                                                'name'       => 'subroutine header',
                                                'regex'      => 'sub[\\t ]+(?:[a-zA-Z0-9_]+)[\\t \\n]*(?:\\{|\\(|\\n)',
                                                'style'      => 'function header',
                                                'childregex' => [
                                                                  {
                                                                    'name'       => 'subroutine header coloring',
                                                                    'regex'      => '[\\t ][a-zA-Z0-9_]+',
                                                                    'style'      => 'function header name',
                                                                    'childregex' => []
                                                                  }
                                                                ]
                                              },
                                              {
                                                'name'       => 'regex matching I',
                                                'regex'      => '(?:\\b| )?(?:/(?:\\\\/|[^/\\n])*(?:/[gimesox]*)|s([^\w\s])(?:\\\\\\2|[^\\2\\n])*?(\\2)[^(\\2)\\n]*?(\\2[gimesox]*))',
                                                'style'      => 'regex',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'regex matching II',
                                                'regex'      => '(?:\\b| )(?:m|qq?|tr|y)([^\w\s])(?:\\\\\\2|[^\\2\\n])*(?:\\2[gimesox]*)',
                                                'style'      => 'regex',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'keywords',
                                                'regex'      => '\\b(my|local|new|if|until|while|elsif|else|eval|unless|for|foreach|continue|exit|die|last|goto|next|redo|return|local|exec|do|use|require|package|eval|BEGIN|END|eq|ne|not|\\|\\||\\&\\&|and|or)\\b',
                                                'style'      => 'reserved word',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'library functions',
                                                'regex'      => '\\b(?:a(?:bs|ccept|larm|tan2)|b(?:ind|inmode|less)|c(?:aller|hdir|hmod|homp|hop|hr|hroot|hown|losedir|lose|onnect|os|rypt)|d(?:bmclose|bmopen|efined|elete|ie|ump)|e(?:ach|nd(?:grent|hostent|netent|protoent|pwent|servent)|of|xec|xists|xp)|f(?:ctnl|ileno|lock|ork|ormat|ormline)|g(?:et(?:c|grent|grgid|grnam|hostbyaddr|hostbyname|hostent|login|netbyaddr|netbyname|netent|peername|pgrp|ppid|priority|protobyname|protobynumber|protoent|pwent|pwnam|pwuid|servbyname|servbyport|servent|sockname|sockopt)|lob|mtime|rep)|hex|i(?:mport|ndex|nt|octl)|join|keys|kill|l(?:cfirst|c|ength|ink|isten|og|ocaltime|stat)|m(?:ap|kdir|sgctl|sgget|sgrcv)|no|o(?:ct|pendir|pen|rd)|p(?:ack|ipe|op|os|rintf|rint|ush)|quotemeta|r(?:and|eaddir|ead|eadlink|ecv|ef|ename|eset|everse|ewinddir|index|mdir)|s(?:calar|eekdir|eek|elect|emctl|emget|emop|end|et(?:grent|hostent|netent|pgrp|priority|protoent|pwent|sockopt)|hift|hmctl|hmget|hmread|hmwrite|hutdown|in|leep|ocket|ocketpair|ort|plice|plit|printf|qrt|rand|tat|tudy|ubstr|ymlink|yscall|ysopen|ysread|ystem|yswrite)|t(?:elldir|ell|ie|ied|ime|imes|runcate)|u(?:c|cfirst|mask|ndef|nlink|npack|nshift|ntie|time)|values|vec|w(?:ait|aitpid|antarray|arn|rite)|qw|-[rwxoRWXOezsfdlpSbctugkTBMAC])\\b',
                                                'style'      => 'library function',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'braces, parens and brakets',
                                                'regex'      => '[\\[\\]\\{\\}\\(\\)]',
                                                'style'      => 'braces',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => '<< stuff',
                                                'regex'      => '<<(?:("|\')([^\\n]*)\\2|\\w*).*?^\\3$',
                                                'style'      => 'text',
                                                'childregex' => []
                                              },
                                              {
                                                'name'       => 'POD',
                                                'regex'      => '^=.*?^(?:=cut|\\Z)',
                                                'style'      => 'doc comment',
                                                'childregex' => []
                                              }
                                            ]
                          };
 


# }1;


sub DO
{
    return xm::code::func::DO($_[0],$LANGUAGE{perl}{patterns});
}

sub ARGS { return    xm::o::args_stdin(@_, DESC); }
sub main { return DO(xm::o::args_stdin(@_, DESC)); }

1;