513 list(lxlexer.get_tokens_unprocessed(latex)))) |
514 list(lxlexer.get_tokens_unprocessed(latex)))) |
514 for item in do_insertions(insertions, hslexer.get_tokens_unprocessed(code)): |
515 for item in do_insertions(insertions, hslexer.get_tokens_unprocessed(code)): |
515 yield item |
516 yield item |
516 |
517 |
517 |
518 |
|
519 class SMLLexer(RegexLexer): |
|
520 """ |
|
521 For the Standard ML language. |
|
522 |
|
523 *New in Pygments 1.5.* |
|
524 """ |
|
525 |
|
526 name = 'Standard ML' |
|
527 aliases = ['sml'] |
|
528 filenames = ['*.sml', '*.sig', '*.fun',] |
|
529 mimetypes = ['text/x-standardml', 'application/x-standardml'] |
|
530 |
|
531 alphanumid_reserved = [ |
|
532 # Core |
|
533 'abstype', 'and', 'andalso', 'as', 'case', 'datatype', 'do', 'else', |
|
534 'end', 'exception', 'fn', 'fun', 'handle', 'if', 'in', 'infix', |
|
535 'infixr', 'let', 'local', 'nonfix', 'of', 'op', 'open', 'orelse', |
|
536 'raise', 'rec', 'then', 'type', 'val', 'with', 'withtype', 'while', |
|
537 # Modules |
|
538 'eqtype', 'functor', 'include', 'sharing', 'sig', 'signature', |
|
539 'struct', 'structure', 'where', |
|
540 ] |
|
541 |
|
542 symbolicid_reserved = [ |
|
543 # Core |
|
544 ':', '\|', '=', '=>', '->', '#', |
|
545 # Modules |
|
546 ':>', |
|
547 ] |
|
548 |
|
549 nonid_reserved = [ '(', ')', '[', ']', '{', '}', ',', ';', '...', '_' ] |
|
550 |
|
551 alphanumid_re = r"[a-zA-Z][a-zA-Z0-9_']*" |
|
552 symbolicid_re = r"[!%&$#+\-/:<=>?@\\~`^|*]+" |
|
553 |
|
554 # A character constant is a sequence of the form #s, where s is a string |
|
555 # constant denoting a string of size one character. This setup just parses |
|
556 # the entire string as either a String.Double or a String.Char (depending |
|
557 # on the argument), even if the String.Char is an erronous |
|
558 # multiple-character string. |
|
559 def stringy (whatkind): |
|
560 return [ |
|
561 (r'[^"\\]', whatkind), |
|
562 (r'\\[\\\"abtnvfr]', String.Escape), |
|
563 # Control-character notation is used for codes < 32, |
|
564 # where \^@ == \000 |
|
565 (r'\\\^[\x40-\x5e]', String.Escape), |
|
566 # Docs say 'decimal digits' |
|
567 (r'\\[0-9]{3}', String.Escape), |
|
568 (r'\\u[0-9a-fA-F]{4}', String.Escape), |
|
569 (r'\\\s+\\', String.Interpol), |
|
570 (r'"', whatkind, '#pop'), |
|
571 ] |
|
572 |
|
573 # Callbacks for distinguishing tokens and reserved words |
|
574 def long_id_callback(self, match): |
|
575 if match.group(1) in self.alphanumid_reserved: token = Error |
|
576 else: token = Name.Namespace |
|
577 yield match.start(1), token, match.group(1) |
|
578 yield match.start(2), Punctuation, match.group(2) |
|
579 |
|
580 def end_id_callback(self, match): |
|
581 if match.group(1) in self.alphanumid_reserved: token = Error |
|
582 elif match.group(1) in self.symbolicid_reserved: token = Error |
|
583 else: token = Name |
|
584 yield match.start(1), token, match.group(1) |
|
585 |
|
586 def id_callback(self, match): |
|
587 str = match.group(1) |
|
588 if str in self.alphanumid_reserved: token = Keyword.Reserved |
|
589 elif str in self.symbolicid_reserved: token = Punctuation |
|
590 else: token = Name |
|
591 yield match.start(1), token, str |
|
592 |
|
593 tokens = { |
|
594 # Whitespace and comments are (almost) everywhere |
|
595 'whitespace': [ |
|
596 (r'\s+', Text), |
|
597 (r'\(\*', Comment.Multiline, 'comment'), |
|
598 ], |
|
599 |
|
600 'delimiters': [ |
|
601 # This lexer treats these delimiters specially: |
|
602 # Delimiters define scopes, and the scope is how the meaning of |
|
603 # the `|' is resolved - is it a case/handle expression, or function |
|
604 # definition by cases? (This is not how the Definition works, but |
|
605 # it's how MLton behaves, see http://mlton.org/SMLNJDeviations) |
|
606 (r'\(|\[|{', Punctuation, 'main'), |
|
607 (r'\)|\]|}', Punctuation, '#pop'), |
|
608 (r'\b(let|if|local)\b(?!\')', Keyword.Reserved, ('main', 'main')), |
|
609 (r'\b(struct|sig|while)\b(?!\')', Keyword.Reserved, 'main'), |
|
610 (r'\b(do|else|end|in|then)\b(?!\')', Keyword.Reserved, '#pop'), |
|
611 ], |
|
612 |
|
613 'core': [ |
|
614 # Punctuation that doesn't overlap symbolic identifiers |
|
615 (r'(%s)' % '|'.join([re.escape(z) for z in nonid_reserved]), |
|
616 Punctuation), |
|
617 |
|
618 # Special constants: strings, floats, numbers in decimal and hex |
|
619 (r'#"', String.Char, 'char'), |
|
620 (r'"', String.Double, 'string'), |
|
621 (r'~?0x[0-9a-fA-F]+', Number.Hex), |
|
622 (r'0wx[0-9a-fA-F]+', Number.Hex), |
|
623 (r'0w\d+', Number.Integer), |
|
624 (r'~?\d+\.\d+[eE]~?\d+', Number.Float), |
|
625 (r'~?\d+\.\d+', Number.Float), |
|
626 (r'~?\d+[eE]~?\d+', Number.Float), |
|
627 (r'~?\d+', Number.Integer), |
|
628 |
|
629 # Labels |
|
630 (r'#\s*[1-9][0-9]*', Name.Label), |
|
631 (r'#\s*(%s)' % alphanumid_re, Name.Label), |
|
632 (r'#\s+(%s)' % symbolicid_re, Name.Label), |
|
633 # Some reserved words trigger a special, local lexer state change |
|
634 (r'\b(datatype|abstype)\b(?!\')', Keyword.Reserved, 'dname'), |
|
635 (r'(?=\b(exception)\b(?!\'))', Text, ('ename')), |
|
636 (r'\b(functor|include|open|signature|structure)\b(?!\')', |
|
637 Keyword.Reserved, 'sname'), |
|
638 (r'\b(type|eqtype)\b(?!\')', Keyword.Reserved, 'tname'), |
|
639 |
|
640 # Regular identifiers, long and otherwise |
|
641 (r'\'[0-9a-zA-Z_\']*', Name.Decorator), |
|
642 (r'(%s)(\.)' % alphanumid_re, long_id_callback, "dotted"), |
|
643 (r'(%s)' % alphanumid_re, id_callback), |
|
644 (r'(%s)' % symbolicid_re, id_callback), |
|
645 ], |
|
646 'dotted': [ |
|
647 (r'(%s)(\.)' % alphanumid_re, long_id_callback), |
|
648 (r'(%s)' % alphanumid_re, end_id_callback, "#pop"), |
|
649 (r'(%s)' % symbolicid_re, end_id_callback, "#pop"), |
|
650 (r'\s+', Error), |
|
651 (r'\S+', Error), |
|
652 ], |
|
653 |
|
654 |
|
655 # Main parser (prevents errors in files that have scoping errors) |
|
656 'root': [ (r'', Text, 'main') ], |
|
657 |
|
658 # In this scope, I expect '|' to not be followed by a function name, |
|
659 # and I expect 'and' to be followed by a binding site |
|
660 'main': [ |
|
661 include('whitespace'), |
|
662 |
|
663 # Special behavior of val/and/fun |
|
664 (r'\b(val|and)\b(?!\')', Keyword.Reserved, 'vname'), |
|
665 (r'\b(fun)\b(?!\')', Keyword.Reserved, |
|
666 ('#pop', 'main-fun', 'fname')), |
|
667 |
|
668 include('delimiters'), |
|
669 include('core'), |
|
670 (r'\S+', Error), |
|
671 ], |
|
672 |
|
673 # In this scope, I expect '|' and 'and' to be followed by a function |
|
674 'main-fun': [ |
|
675 include('whitespace'), |
|
676 |
|
677 (r'\s', Text), |
|
678 (r'\(\*', Comment.Multiline, 'comment'), |
|
679 |
|
680 # Special behavior of val/and/fun |
|
681 (r'\b(fun|and)\b(?!\')', Keyword.Reserved, 'fname'), |
|
682 (r'\b(val)\b(?!\')', Keyword.Reserved, |
|
683 ('#pop', 'main', 'vname')), |
|
684 |
|
685 # Special behavior of '|' and '|'-manipulating keywords |
|
686 (r'\|', Punctuation, 'fname'), |
|
687 (r'\b(case|handle)\b(?!\')', Keyword.Reserved, |
|
688 ('#pop', 'main')), |
|
689 |
|
690 include('delimiters'), |
|
691 include('core'), |
|
692 (r'\S+', Error), |
|
693 ], |
|
694 |
|
695 # Character and string parsers |
|
696 'char': stringy(String.Char), |
|
697 'string': stringy(String.Double), |
|
698 |
|
699 'breakout': [ |
|
700 (r'(?=\b(%s)\b(?!\'))' % '|'.join(alphanumid_reserved), Text, '#pop'), |
|
701 ], |
|
702 |
|
703 # Dealing with what comes after module system keywords |
|
704 'sname': [ |
|
705 include('whitespace'), |
|
706 include('breakout'), |
|
707 |
|
708 (r'(%s)' % alphanumid_re, Name.Namespace), |
|
709 (r'', Text, '#pop'), |
|
710 ], |
|
711 |
|
712 # Dealing with what comes after the 'fun' (or 'and' or '|') keyword |
|
713 'fname': [ |
|
714 include('whitespace'), |
|
715 (r'\'[0-9a-zA-Z_\']*', Name.Decorator), |
|
716 (r'\(', Punctuation, 'tyvarseq'), |
|
717 |
|
718 (r'(%s)' % alphanumid_re, Name.Function, '#pop'), |
|
719 (r'(%s)' % symbolicid_re, Name.Function, '#pop'), |
|
720 |
|
721 # Ignore interesting function declarations like "fun (x + y) = ..." |
|
722 (r'', Text, '#pop'), |
|
723 ], |
|
724 |
|
725 # Dealing with what comes after the 'val' (or 'and') keyword |
|
726 'vname': [ |
|
727 include('whitespace'), |
|
728 (r'\'[0-9a-zA-Z_\']*', Name.Decorator), |
|
729 (r'\(', Punctuation, 'tyvarseq'), |
|
730 |
|
731 (r'(%s)(\s*)(=(?!%s))' % (alphanumid_re, symbolicid_re), |
|
732 bygroups(Name.Variable, Text, Punctuation), '#pop'), |
|
733 (r'(%s)(\s*)(=(?!%s))' % (symbolicid_re, symbolicid_re), |
|
734 bygroups(Name.Variable, Text, Punctuation), '#pop'), |
|
735 (r'(%s)' % alphanumid_re, Name.Variable, '#pop'), |
|
736 (r'(%s)' % symbolicid_re, Name.Variable, '#pop'), |
|
737 |
|
738 # Ignore interesting patterns like 'val (x, y)' |
|
739 (r'', Text, '#pop'), |
|
740 ], |
|
741 |
|
742 # Dealing with what comes after the 'type' (or 'and') keyword |
|
743 'tname': [ |
|
744 include('whitespace'), |
|
745 include('breakout'), |
|
746 |
|
747 (r'\'[0-9a-zA-Z_\']*', Name.Decorator), |
|
748 (r'\(', Punctuation, 'tyvarseq'), |
|
749 (r'=(?!%s)' % symbolicid_re, Punctuation, ('#pop', 'typbind')), |
|
750 |
|
751 (r'(%s)' % alphanumid_re, Keyword.Type), |
|
752 (r'(%s)' % symbolicid_re, Keyword.Type), |
|
753 (r'\S+', Error, '#pop'), |
|
754 ], |
|
755 |
|
756 # A type binding includes most identifiers |
|
757 'typbind': [ |
|
758 include('whitespace'), |
|
759 |
|
760 (r'\b(and)\b(?!\')', Keyword.Reserved, ('#pop', 'tname')), |
|
761 |
|
762 include('breakout'), |
|
763 include('core'), |
|
764 (r'\S+', Error, '#pop'), |
|
765 ], |
|
766 |
|
767 # Dealing with what comes after the 'datatype' (or 'and') keyword |
|
768 'dname': [ |
|
769 include('whitespace'), |
|
770 include('breakout'), |
|
771 |
|
772 (r'\'[0-9a-zA-Z_\']*', Name.Decorator), |
|
773 (r'\(', Punctuation, 'tyvarseq'), |
|
774 (r'(=)(\s*)(datatype)', |
|
775 bygroups(Punctuation, Text, Keyword.Reserved), '#pop'), |
|
776 (r'=(?!%s)' % symbolicid_re, Punctuation, |
|
777 ('#pop', 'datbind', 'datcon')), |
|
778 |
|
779 (r'(%s)' % alphanumid_re, Keyword.Type), |
|
780 (r'(%s)' % symbolicid_re, Keyword.Type), |
|
781 (r'\S+', Error, '#pop'), |
|
782 ], |
|
783 |
|
784 # common case - A | B | C of int |
|
785 'datbind': [ |
|
786 include('whitespace'), |
|
787 |
|
788 (r'\b(and)\b(?!\')', Keyword.Reserved, ('#pop', 'dname')), |
|
789 (r'\b(withtype)\b(?!\')', Keyword.Reserved, ('#pop', 'tname')), |
|
790 (r'\b(of)\b(?!\')', Keyword.Reserved), |
|
791 |
|
792 (r'(\|)(\s*)(%s)' % alphanumid_re, |
|
793 bygroups(Punctuation, Text, Name.Class)), |
|
794 (r'(\|)(\s+)(%s)' % symbolicid_re, |
|
795 bygroups(Punctuation, Text, Name.Class)), |
|
796 |
|
797 include('breakout'), |
|
798 include('core'), |
|
799 (r'\S+', Error), |
|
800 ], |
|
801 |
|
802 # Dealing with what comes after an exception |
|
803 'ename': [ |
|
804 include('whitespace'), |
|
805 |
|
806 (r'(exception|and)\b(\s+)(%s)' % alphanumid_re, |
|
807 bygroups(Keyword.Reserved, Text, Name.Class)), |
|
808 (r'(exception|and)\b(\s*)(%s)' % symbolicid_re, |
|
809 bygroups(Keyword.Reserved, Text, Name.Class)), |
|
810 (r'\b(of)\b(?!\')', Keyword.Reserved), |
|
811 |
|
812 include('breakout'), |
|
813 include('core'), |
|
814 (r'\S+', Error), |
|
815 ], |
|
816 |
|
817 'datcon': [ |
|
818 include('whitespace'), |
|
819 (r'(%s)' % alphanumid_re, Name.Class, '#pop'), |
|
820 (r'(%s)' % symbolicid_re, Name.Class, '#pop'), |
|
821 (r'\S+', Error, '#pop'), |
|
822 ], |
|
823 |
|
824 # Series of type variables |
|
825 'tyvarseq': [ |
|
826 (r'\s', Text), |
|
827 (r'\(\*', Comment.Multiline, 'comment'), |
|
828 |
|
829 (r'\'[0-9a-zA-Z_\']*', Name.Decorator), |
|
830 (alphanumid_re, Name), |
|
831 (r',', Punctuation), |
|
832 (r'\)', Punctuation, '#pop'), |
|
833 (symbolicid_re, Name), |
|
834 ], |
|
835 |
|
836 'comment': [ |
|
837 (r'[^(*)]', Comment.Multiline), |
|
838 (r'\(\*', Comment.Multiline, '#push'), |
|
839 (r'\*\)', Comment.Multiline, '#pop'), |
|
840 (r'[(*)]', Comment.Multiline), |
|
841 ], |
|
842 } |
|
843 |
|
844 |
518 class OcamlLexer(RegexLexer): |
845 class OcamlLexer(RegexLexer): |
519 """ |
846 """ |
520 For the OCaml language. |
847 For the OCaml language. |
521 |
848 |
522 *New in Pygments 0.7.* |
849 *New in Pygments 0.7.* |
753 if curcode: |
1080 if curcode: |
754 for item in do_insertions(insertions, |
1081 for item in do_insertions(insertions, |
755 erlexer.get_tokens_unprocessed(curcode)): |
1082 erlexer.get_tokens_unprocessed(curcode)): |
756 yield item |
1083 yield item |
757 |
1084 |
|
1085 |
|
1086 class OpaLexer(RegexLexer): |
|
1087 """ |
|
1088 Lexer for the Opa language (http://opalang.org). |
|
1089 |
|
1090 *New in Pygments 1.5.* |
|
1091 """ |
|
1092 |
|
1093 name = 'Opa' |
|
1094 aliases = ['opa'] |
|
1095 filenames = ['*.opa'] |
|
1096 mimetypes = ['text/x-opa'] |
|
1097 |
|
1098 # most of these aren't strictly keywords |
|
1099 # but if you color only real keywords, you might just |
|
1100 # as well not color anything |
|
1101 keywords = [ |
|
1102 'and', 'as', 'begin', 'css', 'database', 'db', 'do', 'else', 'end', |
|
1103 'external', 'forall', 'if', 'import', 'match', 'package', 'parser', |
|
1104 'rec', 'server', 'then', 'type', 'val', 'with', 'xml_parser' |
|
1105 ] |
|
1106 |
|
1107 # matches both stuff and `stuff` |
|
1108 ident_re = r'(([a-zA-Z_]\w*)|(`[^`]*`))' |
|
1109 |
|
1110 op_re = r'[.=\-<>,@~%/+?*&^!]' |
|
1111 punc_re = r'[()\[\],;|]' # '{' and '}' are treated elsewhere |
|
1112 # because they are also used for inserts |
|
1113 |
|
1114 tokens = { |
|
1115 # copied from the caml lexer, should be adapted |
|
1116 'escape-sequence': [ |
|
1117 (r'\\[\\\"\'ntr}]', String.Escape), |
|
1118 (r'\\[0-9]{3}', String.Escape), |
|
1119 (r'\\x[0-9a-fA-F]{2}', String.Escape), |
|
1120 ], |
|
1121 |
|
1122 # factorizing these rules, because they are inserted many times |
|
1123 'comments': [ |
|
1124 (r'/\*', Comment, 'nested-comment'), |
|
1125 (r'//.*?$', Comment), |
|
1126 ], |
|
1127 'comments-and-spaces': [ |
|
1128 include('comments'), |
|
1129 (r'\s+', Text), |
|
1130 ], |
|
1131 |
|
1132 'root': [ |
|
1133 include('comments-and-spaces'), |
|
1134 # keywords |
|
1135 (r'\b(%s)\b' % '|'.join(keywords), Keyword), |
|
1136 # directives |
|
1137 # we could parse the actual set of directives instead of anything |
|
1138 # starting with @, but this is troublesome |
|
1139 # because it needs to be adjusted all the time |
|
1140 # and assuming we parse only sources that compile, it is useless |
|
1141 (r'@'+ident_re+r'\b', Name.Builtin.Pseudo), |
|
1142 |
|
1143 # number literals |
|
1144 (r'-?.[\d]+([eE][+\-]?\d+)', Number.Float), |
|
1145 (r'-?\d+.\d*([eE][+\-]?\d+)', Number.Float), |
|
1146 (r'-?\d+[eE][+\-]?\d+', Number.Float), |
|
1147 (r'0[xX][\da-fA-F]+', Number.Hex), |
|
1148 (r'0[oO][0-7]+', Number.Oct), |
|
1149 (r'0[bB][01]+', Number.Binary), |
|
1150 (r'\d+', Number.Integer), |
|
1151 # color literals |
|
1152 (r'#[\da-fA-F]{3,6}', Number.Integer), |
|
1153 |
|
1154 # string literals |
|
1155 (r'"', String.Double, 'string'), |
|
1156 # char literal, should be checked because this is the regexp from |
|
1157 # the caml lexer |
|
1158 (r"'(?:(\\[\\\"'ntbr ])|(\\[0-9]{3})|(\\x[0-9a-fA-F]{2})|.)'", |
|
1159 String.Char), |
|
1160 |
|
1161 # this is meant to deal with embedded exprs in strings |
|
1162 # every time we find a '}' we pop a state so that if we were |
|
1163 # inside a string, we are back in the string state |
|
1164 # as a consequence, we must also push a state every time we find a |
|
1165 # '{' or else we will have errors when parsing {} for instance |
|
1166 (r'{', Operator, '#push'), |
|
1167 (r'}', Operator, '#pop'), |
|
1168 |
|
1169 # html literals |
|
1170 # this is a much more strict that the actual parser, |
|
1171 # since a<b would not be parsed as html |
|
1172 # but then again, the parser is way too lax, and we can't hope |
|
1173 # to have something as tolerant |
|
1174 (r'<(?=[a-zA-Z>])', String.Single, 'html-open-tag'), |
|
1175 |
|
1176 # db path |
|
1177 # matching the '[_]' in '/a[_]' because it is a part |
|
1178 # of the syntax of the db path definition |
|
1179 # unfortunately, i don't know how to match the ']' in |
|
1180 # /a[1], so this is somewhat inconsistent |
|
1181 (r'[@?!]?(/\w+)+(\[_\])?', Name.Variable), |
|
1182 # putting the same color on <- as on db path, since |
|
1183 # it can be used only to mean Db.write |
|
1184 (r'<-(?!'+op_re+r')', Name.Variable), |
|
1185 |
|
1186 # 'modules' |
|
1187 # although modules are not distinguished by their names as in caml |
|
1188 # the standard library seems to follow the convention that modules |
|
1189 # only area capitalized |
|
1190 (r'\b([A-Z]\w*)(?=\.)', Name.Namespace), |
|
1191 |
|
1192 # operators |
|
1193 # = has a special role because this is the only |
|
1194 # way to syntactic distinguish binding constructions |
|
1195 # unfortunately, this colors the equal in {x=2} too |
|
1196 (r'=(?!'+op_re+r')', Keyword), |
|
1197 (r'(%s)+' % op_re, Operator), |
|
1198 (r'(%s)+' % punc_re, Operator), |
|
1199 |
|
1200 # coercions |
|
1201 (r':', Operator, 'type'), |
|
1202 # type variables |
|
1203 # we need this rule because we don't parse specially type |
|
1204 # definitions so in "type t('a) = ...", "'a" is parsed by 'root' |
|
1205 ("'"+ident_re, Keyword.Type), |
|
1206 |
|
1207 # id literal, #something, or #{expr} |
|
1208 (r'#'+ident_re, String.Single), |
|
1209 (r'#(?={)', String.Single), |
|
1210 |
|
1211 # identifiers |
|
1212 # this avoids to color '2' in 'a2' as an integer |
|
1213 (ident_re, Text), |
|
1214 |
|
1215 # default, not sure if that is needed or not |
|
1216 # (r'.', Text), |
|
1217 ], |
|
1218 |
|
1219 # it is quite painful to have to parse types to know where they end |
|
1220 # this is the general rule for a type |
|
1221 # a type is either: |
|
1222 # * -> ty |
|
1223 # * type-with-slash |
|
1224 # * type-with-slash -> ty |
|
1225 # * type-with-slash (, type-with-slash)+ -> ty |
|
1226 # |
|
1227 # the code is pretty funky in here, but this code would roughly |
|
1228 # translate in caml to: |
|
1229 # let rec type stream = |
|
1230 # match stream with |
|
1231 # | [< "->"; stream >] -> type stream |
|
1232 # | [< ""; stream >] -> |
|
1233 # type_with_slash stream |
|
1234 # type_lhs_1 stream; |
|
1235 # and type_1 stream = ... |
|
1236 'type': [ |
|
1237 include('comments-and-spaces'), |
|
1238 (r'->', Keyword.Type), |
|
1239 (r'', Keyword.Type, ('#pop', 'type-lhs-1', 'type-with-slash')), |
|
1240 ], |
|
1241 |
|
1242 # parses all the atomic or closed constructions in the syntax of type |
|
1243 # expressions: record types, tuple types, type constructors, basic type |
|
1244 # and type variables |
|
1245 'type-1': [ |
|
1246 include('comments-and-spaces'), |
|
1247 (r'\(', Keyword.Type, ('#pop', 'type-tuple')), |
|
1248 (r'~?{', Keyword.Type, ('#pop', 'type-record')), |
|
1249 (ident_re+r'\(', Keyword.Type, ('#pop', 'type-tuple')), |
|
1250 (ident_re, Keyword.Type, '#pop'), |
|
1251 ("'"+ident_re, Keyword.Type), |
|
1252 # this case is not in the syntax but sometimes |
|
1253 # we think we are parsing types when in fact we are parsing |
|
1254 # some css, so we just pop the states until we get back into |
|
1255 # the root state |
|
1256 (r'', Keyword.Type, '#pop'), |
|
1257 ], |
|
1258 |
|
1259 # type-with-slash is either: |
|
1260 # * type-1 |
|
1261 # * type-1 (/ type-1)+ |
|
1262 'type-with-slash': [ |
|
1263 include('comments-and-spaces'), |
|
1264 (r'', Keyword.Type, ('#pop', 'slash-type-1', 'type-1')), |
|
1265 ], |
|
1266 'slash-type-1': [ |
|
1267 include('comments-and-spaces'), |
|
1268 ('/', Keyword.Type, ('#pop', 'type-1')), |
|
1269 # same remark as above |
|
1270 (r'', Keyword.Type, '#pop'), |
|
1271 ], |
|
1272 |
|
1273 # we go in this state after having parsed a type-with-slash |
|
1274 # while trying to parse a type |
|
1275 # and at this point we must determine if we are parsing an arrow |
|
1276 # type (in which case we must continue parsing) or not (in which |
|
1277 # case we stop) |
|
1278 'type-lhs-1': [ |
|
1279 include('comments-and-spaces'), |
|
1280 (r'->', Keyword.Type, ('#pop', 'type')), |
|
1281 (r'(?=,)', Keyword.Type, ('#pop', 'type-arrow')), |
|
1282 (r'', Keyword.Type, '#pop'), |
|
1283 ], |
|
1284 'type-arrow': [ |
|
1285 include('comments-and-spaces'), |
|
1286 # the look ahead here allows to parse f(x : int, y : float -> truc) |
|
1287 # correctly |
|
1288 (r',(?=[^:]*?->)', Keyword.Type, 'type-with-slash'), |
|
1289 (r'->', Keyword.Type, ('#pop', 'type')), |
|
1290 # same remark as above |
|
1291 (r'', Keyword.Type, '#pop'), |
|
1292 ], |
|
1293 |
|
1294 # no need to do precise parsing for tuples and records |
|
1295 # because they are closed constructions, so we can simply |
|
1296 # find the closing delimiter |
|
1297 # note that this function would be not work if the source |
|
1298 # contained identifiers like `{)` (although it could be patched |
|
1299 # to support it) |
|
1300 'type-tuple': [ |
|
1301 include('comments-and-spaces'), |
|
1302 (r'[^\(\)/*]+', Keyword.Type), |
|
1303 (r'[/*]', Keyword.Type), |
|
1304 (r'\(', Keyword.Type, '#push'), |
|
1305 (r'\)', Keyword.Type, '#pop'), |
|
1306 ], |
|
1307 'type-record': [ |
|
1308 include('comments-and-spaces'), |
|
1309 (r'[^{}/*]+', Keyword.Type), |
|
1310 (r'[/*]', Keyword.Type), |
|
1311 (r'{', Keyword.Type, '#push'), |
|
1312 (r'}', Keyword.Type, '#pop'), |
|
1313 ], |
|
1314 |
|
1315 # 'type-tuple': [ |
|
1316 # include('comments-and-spaces'), |
|
1317 # (r'\)', Keyword.Type, '#pop'), |
|
1318 # (r'', Keyword.Type, ('#pop', 'type-tuple-1', 'type-1')), |
|
1319 # ], |
|
1320 # 'type-tuple-1': [ |
|
1321 # include('comments-and-spaces'), |
|
1322 # (r',?\s*\)', Keyword.Type, '#pop'), # ,) is a valid end of tuple, in (1,) |
|
1323 # (r',', Keyword.Type, 'type-1'), |
|
1324 # ], |
|
1325 # 'type-record':[ |
|
1326 # include('comments-and-spaces'), |
|
1327 # (r'}', Keyword.Type, '#pop'), |
|
1328 # (r'~?(?:\w+|`[^`]*`)', Keyword.Type, 'type-record-field-expr'), |
|
1329 # ], |
|
1330 # 'type-record-field-expr': [ |
|
1331 # |
|
1332 # ], |
|
1333 |
|
1334 'nested-comment': [ |
|
1335 (r'[^/*]+', Comment), |
|
1336 (r'/\*', Comment, '#push'), |
|
1337 (r'\*/', Comment, '#pop'), |
|
1338 (r'[/*]', Comment), |
|
1339 ], |
|
1340 |
|
1341 # the coy pasting between string and single-string |
|
1342 # is kinda sad. Is there a way to avoid that?? |
|
1343 'string': [ |
|
1344 (r'[^\\"{]+', String.Double), |
|
1345 (r'"', String.Double, '#pop'), |
|
1346 (r'{', Operator, 'root'), |
|
1347 include('escape-sequence'), |
|
1348 ], |
|
1349 'single-string': [ |
|
1350 (r'[^\\\'{]+', String.Double), |
|
1351 (r'\'', String.Double, '#pop'), |
|
1352 (r'{', Operator, 'root'), |
|
1353 include('escape-sequence'), |
|
1354 ], |
|
1355 |
|
1356 # all the html stuff |
|
1357 # can't really reuse some existing html parser |
|
1358 # because we must be able to parse embedded expressions |
|
1359 |
|
1360 # we are in this state after someone parsed the '<' that |
|
1361 # started the html literal |
|
1362 'html-open-tag': [ |
|
1363 (r'[\w\-:]+', String.Single, ('#pop', 'html-attr')), |
|
1364 (r'>', String.Single, ('#pop', 'html-content')), |
|
1365 ], |
|
1366 |
|
1367 # we are in this state after someone parsed the '</' that |
|
1368 # started the end of the closing tag |
|
1369 'html-end-tag': [ |
|
1370 # this is a star, because </> is allowed |
|
1371 (r'[\w\-:]*>', String.Single, '#pop'), |
|
1372 ], |
|
1373 |
|
1374 # we are in this state after having parsed '<ident(:ident)?' |
|
1375 # we thus parse a possibly empty list of attributes |
|
1376 'html-attr': [ |
|
1377 (r'\s+', Text), |
|
1378 (r'[\w\-:]+=', String.Single, 'html-attr-value'), |
|
1379 (r'/>', String.Single, '#pop'), |
|
1380 (r'>', String.Single, ('#pop', 'html-content')), |
|
1381 ], |
|
1382 |
|
1383 'html-attr-value': [ |
|
1384 (r"'", String.Single, ('#pop', 'single-string')), |
|
1385 (r'"', String.Single, ('#pop', 'string')), |
|
1386 (r'#'+ident_re, String.Single, '#pop'), |
|
1387 (r'#(?={)', String.Single, ('#pop', 'root')), |
|
1388 (r'{', Operator, ('#pop', 'root')), # this is a tail call! |
|
1389 ], |
|
1390 |
|
1391 # we should probably deal with '\' escapes here |
|
1392 'html-content': [ |
|
1393 (r'<!--', Comment, 'html-comment'), |
|
1394 (r'</', String.Single, ('#pop', 'html-end-tag')), |
|
1395 (r'<', String.Single, 'html-open-tag'), |
|
1396 (r'{', Operator, 'root'), |
|
1397 (r'.|\s+', String.Single), |
|
1398 ], |
|
1399 |
|
1400 'html-comment': [ |
|
1401 (r'-->', Comment, '#pop'), |
|
1402 (r'[^\-]+|-', Comment), |
|
1403 ], |
|
1404 } |
|
1405 |
|
1406 |
|
1407 class CoqLexer(RegexLexer): |
|
1408 """ |
|
1409 For the `Coq <http://coq.inria.fr/>`_ theorem prover. |
|
1410 |
|
1411 *New in Pygments 1.5.* |
|
1412 """ |
|
1413 |
|
1414 name = 'Coq' |
|
1415 aliases = ['coq'] |
|
1416 filenames = ['*.v'] |
|
1417 mimetypes = ['text/x-coq'] |
|
1418 |
|
1419 keywords1 = [ |
|
1420 # Vernacular commands |
|
1421 'Section', 'Module', 'End', 'Require', 'Import', 'Export', 'Variable', |
|
1422 'Variables', 'Parameter', 'Parameters', 'Axiom', 'Hypothesis', |
|
1423 'Hypotheses', 'Notation', 'Local', 'Tactic', 'Reserved', 'Scope', |
|
1424 'Open', 'Close', 'Bind', 'Delimit', 'Definition', 'Let', 'Ltac', |
|
1425 'Fixpoint', 'CoFixpoint', 'Morphism', 'Relation', 'Implicit', |
|
1426 'Arguments', 'Set', 'Unset', 'Contextual', 'Strict', 'Prenex', |
|
1427 'Implicits', 'Inductive', 'CoInductive', 'Record', 'Structure', |
|
1428 'Canonical', 'Coercion', 'Theorem', 'Lemma', 'Corollary', |
|
1429 'Proposition', 'Fact', 'Remark', 'Example', 'Proof', 'Goal', 'Save', |
|
1430 'Qed', 'Defined', 'Hint', 'Resolve', 'Rewrite', 'View', 'Search', |
|
1431 'Show', 'Print', 'Printing', 'All', 'Graph', 'Projections', 'inside', |
|
1432 'outside', |
|
1433 ] |
|
1434 keywords2 = [ |
|
1435 # Gallina |
|
1436 'forall', 'exists', 'exists2', 'fun', 'fix', 'cofix', 'struct', |
|
1437 'match', 'end', 'in', 'return', 'let', 'if', 'is', 'then', 'else', |
|
1438 'for', 'of', 'nosimpl', 'with', 'as', |
|
1439 ] |
|
1440 keywords3 = [ |
|
1441 # Sorts |
|
1442 'Type', 'Prop', |
|
1443 ] |
|
1444 keywords4 = [ |
|
1445 # Tactics |
|
1446 'pose', 'set', 'move', 'case', 'elim', 'apply', 'clear', 'hnf', 'intro', |
|
1447 'intros', 'generalize', 'rename', 'pattern', 'after', 'destruct', |
|
1448 'induction', 'using', 'refine', 'inversion', 'injection', 'rewrite', |
|
1449 'congr', 'unlock', 'compute', 'ring', 'field', 'replace', 'fold', |
|
1450 'unfold', 'change', 'cutrewrite', 'simpl', 'have', 'suff', 'wlog', |
|
1451 'suffices', 'without', 'loss', 'nat_norm', 'assert', 'cut', 'trivial', |
|
1452 'revert', 'bool_congr', 'nat_congr', 'symmetry', 'transitivity', 'auto', |
|
1453 'split', 'left', 'right', 'autorewrite', |
|
1454 ] |
|
1455 keywords5 = [ |
|
1456 # Terminators |
|
1457 'by', 'done', 'exact', 'reflexivity', 'tauto', 'romega', 'omega', |
|
1458 'assumption', 'solve', 'contradiction', 'discriminate', |
|
1459 ] |
|
1460 keywords6 = [ |
|
1461 # Control |
|
1462 'do', 'last', 'first', 'try', 'idtac', 'repeat', |
|
1463 ] |
|
1464 # 'as', 'assert', 'begin', 'class', 'constraint', 'do', 'done', |
|
1465 # 'downto', 'else', 'end', 'exception', 'external', 'false', |
|
1466 # 'for', 'fun', 'function', 'functor', 'if', 'in', 'include', |
|
1467 # 'inherit', 'initializer', 'lazy', 'let', 'match', 'method', |
|
1468 # 'module', 'mutable', 'new', 'object', 'of', 'open', 'private', |
|
1469 # 'raise', 'rec', 'sig', 'struct', 'then', 'to', 'true', 'try', |
|
1470 # 'type', 'val', 'virtual', 'when', 'while', 'with' |
|
1471 keyopts = [ |
|
1472 '!=', '#', '&', '&&', r'\(', r'\)', r'\*', r'\+', ',', '-', |
|
1473 r'-\.', '->', r'\.', r'\.\.', ':', '::', ':=', ':>', ';', ';;', '<', |
|
1474 '<-', '=', '>', '>]', '>}', r'\?', r'\?\?', r'\[', r'\[<', r'\[>', |
|
1475 r'\[\|', ']', '_', '`', '{', '{<', r'\|', r'\|]', '}', '~', '=>', |
|
1476 r'/\\', r'\\/', |
|
1477 'Π', 'λ', |
|
1478 ] |
|
1479 operators = r'[!$%&*+\./:<=>?@^|~-]' |
|
1480 word_operators = ['and', 'asr', 'land', 'lor', 'lsl', 'lxor', 'mod', 'or'] |
|
1481 prefix_syms = r'[!?~]' |
|
1482 infix_syms = r'[=<>@^|&+\*/$%-]' |
|
1483 primitives = ['unit', 'int', 'float', 'bool', 'string', 'char', 'list', |
|
1484 'array'] |
|
1485 |
|
1486 tokens = { |
|
1487 'root': [ |
|
1488 (r'\s+', Text), |
|
1489 (r'false|true|\(\)|\[\]', Name.Builtin.Pseudo), |
|
1490 (r'\(\*', Comment, 'comment'), |
|
1491 (r'\b(%s)\b' % '|'.join(keywords1), Keyword.Namespace), |
|
1492 (r'\b(%s)\b' % '|'.join(keywords2), Keyword), |
|
1493 (r'\b(%s)\b' % '|'.join(keywords3), Keyword.Type), |
|
1494 (r'\b(%s)\b' % '|'.join(keywords4), Keyword), |
|
1495 (r'\b(%s)\b' % '|'.join(keywords5), Keyword.Pseudo), |
|
1496 (r'\b(%s)\b' % '|'.join(keywords6), Keyword.Reserved), |
|
1497 (r'\b([A-Z][A-Za-z0-9_\']*)(?=\s*\.)', |
|
1498 Name.Namespace, 'dotted'), |
|
1499 (r'\b([A-Z][A-Za-z0-9_\']*)', Name.Class), |
|
1500 (r'(%s)' % '|'.join(keyopts[::-1]), Operator), |
|
1501 (r'(%s|%s)?%s' % (infix_syms, prefix_syms, operators), Operator), |
|
1502 (r'\b(%s)\b' % '|'.join(word_operators), Operator.Word), |
|
1503 (r'\b(%s)\b' % '|'.join(primitives), Keyword.Type), |
|
1504 |
|
1505 (r"[^\W\d][\w']*", Name), |
|
1506 |
|
1507 (r'\d[\d_]*', Number.Integer), |
|
1508 (r'0[xX][\da-fA-F][\da-fA-F_]*', Number.Hex), |
|
1509 (r'0[oO][0-7][0-7_]*', Number.Oct), |
|
1510 (r'0[bB][01][01_]*', Number.Binary), |
|
1511 (r'-?\d[\d_]*(.[\d_]*)?([eE][+\-]?\d[\d_]*)', Number.Float), |
|
1512 |
|
1513 (r"'(?:(\\[\\\"'ntbr ])|(\\[0-9]{3})|(\\x[0-9a-fA-F]{2}))'", |
|
1514 String.Char), |
|
1515 (r"'.'", String.Char), |
|
1516 (r"'", Keyword), # a stray quote is another syntax element |
|
1517 |
|
1518 (r'"', String.Double, 'string'), |
|
1519 |
|
1520 (r'[~?][a-z][\w\']*:', Name.Variable), |
|
1521 ], |
|
1522 'comment': [ |
|
1523 (r'[^(*)]+', Comment), |
|
1524 (r'\(\*', Comment, '#push'), |
|
1525 (r'\*\)', Comment, '#pop'), |
|
1526 (r'[(*)]', Comment), |
|
1527 ], |
|
1528 'string': [ |
|
1529 (r'[^"]+', String.Double), |
|
1530 (r'""', String.Double), |
|
1531 (r'"', String.Double, '#pop'), |
|
1532 ], |
|
1533 'dotted': [ |
|
1534 (r'\s+', Text), |
|
1535 (r'\.', Punctuation), |
|
1536 (r'[A-Z][A-Za-z0-9_\']*(?=\s*\.)', Name.Namespace), |
|
1537 (r'[A-Z][A-Za-z0-9_\']*', Name.Class, '#pop'), |
|
1538 (r'[a-z][a-z0-9_\']*', Name, '#pop'), |
|
1539 (r'', Text, '#pop') |
|
1540 ], |
|
1541 } |
|
1542 |
|
1543 def analyse_text(text): |
|
1544 if text.startswith('(*'): |
|
1545 return True |
|
1546 |
|
1547 |
|
1548 class NewLispLexer(RegexLexer): |
|
1549 """ |
|
1550 For `newLISP. <www.newlisp.org>`_ source code (version 10.3.0). |
|
1551 |
|
1552 *New in Pygments 1.5.* |
|
1553 """ |
|
1554 |
|
1555 name = 'NewLisp' |
|
1556 aliases = ['newlisp'] |
|
1557 filenames = ['*.lsp', '*.nl'] |
|
1558 mimetypes = ['text/x-newlisp', 'application/x-newlisp'] |
|
1559 |
|
1560 flags = re.IGNORECASE | re.MULTILINE | re.UNICODE |
|
1561 |
|
1562 # list of built-in functions for newLISP version 10.3 |
|
1563 builtins = [ |
|
1564 '^', '--', '-', ':', '!', '!=', '?', '@', '*', '/', '&', '%', '+', '++', |
|
1565 '<', '<<', '<=', '=', '>', '>=', '>>', '|', '~', '$', '$0', '$1', '$10', |
|
1566 '$11', '$12', '$13', '$14', '$15', '$2', '$3', '$4', '$5', '$6', '$7', |
|
1567 '$8', '$9', '$args', '$idx', '$it', '$main-args', 'abort', 'abs', |
|
1568 'acos', 'acosh', 'add', 'address', 'amb', 'and', 'and', 'append-file', |
|
1569 'append', 'apply', 'args', 'array-list', 'array?', 'array', 'asin', |
|
1570 'asinh', 'assoc', 'atan', 'atan2', 'atanh', 'atom?', 'base64-dec', |
|
1571 'base64-enc', 'bayes-query', 'bayes-train', 'begin', 'begin', 'begin', |
|
1572 'beta', 'betai', 'bind', 'binomial', 'bits', 'callback', 'case', 'case', |
|
1573 'case', 'catch', 'ceil', 'change-dir', 'char', 'chop', 'Class', 'clean', |
|
1574 'close', 'command-event', 'cond', 'cond', 'cond', 'cons', 'constant', |
|
1575 'context?', 'context', 'copy-file', 'copy', 'cos', 'cosh', 'count', |
|
1576 'cpymem', 'crc32', 'crit-chi2', 'crit-z', 'current-line', 'curry', |
|
1577 'date-list', 'date-parse', 'date-value', 'date', 'debug', 'dec', |
|
1578 'def-new', 'default', 'define-macro', 'define-macro', 'define', |
|
1579 'delete-file', 'delete-url', 'delete', 'destroy', 'det', 'device', |
|
1580 'difference', 'directory?', 'directory', 'div', 'do-until', 'do-while', |
|
1581 'doargs', 'dolist', 'dostring', 'dotimes', 'dotree', 'dump', 'dup', |
|
1582 'empty?', 'encrypt', 'ends-with', 'env', 'erf', 'error-event', |
|
1583 'eval-string', 'eval', 'exec', 'exists', 'exit', 'exp', 'expand', |
|
1584 'explode', 'extend', 'factor', 'fft', 'file-info', 'file?', 'filter', |
|
1585 'find-all', 'find', 'first', 'flat', 'float?', 'float', 'floor', 'flt', |
|
1586 'fn', 'for-all', 'for', 'fork', 'format', 'fv', 'gammai', 'gammaln', |
|
1587 'gcd', 'get-char', 'get-float', 'get-int', 'get-long', 'get-string', |
|
1588 'get-url', 'global?', 'global', 'if-not', 'if', 'ifft', 'import', 'inc', |
|
1589 'index', 'inf?', 'int', 'integer?', 'integer', 'intersect', 'invert', |
|
1590 'irr', 'join', 'lambda-macro', 'lambda?', 'lambda', 'last-error', |
|
1591 'last', 'legal?', 'length', 'let', 'let', 'let', 'letex', 'letn', |
|
1592 'letn', 'letn', 'list?', 'list', 'load', 'local', 'log', 'lookup', |
|
1593 'lower-case', 'macro?', 'main-args', 'MAIN', 'make-dir', 'map', 'mat', |
|
1594 'match', 'max', 'member', 'min', 'mod', 'module', 'mul', 'multiply', |
|
1595 'NaN?', 'net-accept', 'net-close', 'net-connect', 'net-error', |
|
1596 'net-eval', 'net-interface', 'net-ipv', 'net-listen', 'net-local', |
|
1597 'net-lookup', 'net-packet', 'net-peek', 'net-peer', 'net-ping', |
|
1598 'net-receive-from', 'net-receive-udp', 'net-receive', 'net-select', |
|
1599 'net-send-to', 'net-send-udp', 'net-send', 'net-service', |
|
1600 'net-sessions', 'new', 'nil?', 'nil', 'normal', 'not', 'now', 'nper', |
|
1601 'npv', 'nth', 'null?', 'number?', 'open', 'or', 'ostype', 'pack', |
|
1602 'parse-date', 'parse', 'peek', 'pipe', 'pmt', 'pop-assoc', 'pop', |
|
1603 'post-url', 'pow', 'prefix', 'pretty-print', 'primitive?', 'print', |
|
1604 'println', 'prob-chi2', 'prob-z', 'process', 'prompt-event', |
|
1605 'protected?', 'push', 'put-url', 'pv', 'quote?', 'quote', 'rand', |
|
1606 'random', 'randomize', 'read', 'read-char', 'read-expr', 'read-file', |
|
1607 'read-key', 'read-line', 'read-utf8', 'read', 'reader-event', |
|
1608 'real-path', 'receive', 'ref-all', 'ref', 'regex-comp', 'regex', |
|
1609 'remove-dir', 'rename-file', 'replace', 'reset', 'rest', 'reverse', |
|
1610 'rotate', 'round', 'save', 'search', 'seed', 'seek', 'select', 'self', |
|
1611 'semaphore', 'send', 'sequence', 'series', 'set-locale', 'set-ref-all', |
|
1612 'set-ref', 'set', 'setf', 'setq', 'sgn', 'share', 'signal', 'silent', |
|
1613 'sin', 'sinh', 'sleep', 'slice', 'sort', 'source', 'spawn', 'sqrt', |
|
1614 'starts-with', 'string?', 'string', 'sub', 'swap', 'sym', 'symbol?', |
|
1615 'symbols', 'sync', 'sys-error', 'sys-info', 'tan', 'tanh', 'term', |
|
1616 'throw-error', 'throw', 'time-of-day', 'time', 'timer', 'title-case', |
|
1617 'trace-highlight', 'trace', 'transpose', 'Tree', 'trim', 'true?', |
|
1618 'true', 'unicode', 'unify', 'unique', 'unless', 'unpack', 'until', |
|
1619 'upper-case', 'utf8', 'utf8len', 'uuid', 'wait-pid', 'when', 'while', |
|
1620 'write', 'write-char', 'write-file', 'write-line', 'write', |
|
1621 'xfer-event', 'xml-error', 'xml-parse', 'xml-type-tags', 'zero?', |
|
1622 ] |
|
1623 |
|
1624 # valid names |
|
1625 valid_name = r'([a-zA-Z0-9!$%&*+.,/<=>?@^_~|-])+|(\[.*?\])+' |
|
1626 |
|
1627 tokens = { |
|
1628 'root': [ |
|
1629 # shebang |
|
1630 (r'#!(.*?)$', Comment.Preproc), |
|
1631 # comments starting with semicolon |
|
1632 (r';.*$', Comment.Single), |
|
1633 # comments starting with # |
|
1634 (r'#.*$', Comment.Single), |
|
1635 |
|
1636 # whitespace |
|
1637 (r'\s+', Text), |
|
1638 |
|
1639 # strings, symbols and characters |
|
1640 (r'"(\\\\|\\"|[^"])*"', String), |
|
1641 |
|
1642 # braces |
|
1643 (r"{", String, "bracestring"), |
|
1644 |
|
1645 # [text] ... [/text] delimited strings |
|
1646 (r'\[text\]*', String, "tagstring"), |
|
1647 |
|
1648 # 'special' operators... |
|
1649 (r"('|:)", Operator), |
|
1650 |
|
1651 # highlight the builtins |
|
1652 ('(%s)' % '|'.join(re.escape(entry) + '\\b' for entry in builtins), |
|
1653 Keyword), |
|
1654 |
|
1655 # the remaining functions |
|
1656 (r'(?<=\()' + valid_name, Name.Variable), |
|
1657 |
|
1658 # the remaining variables |
|
1659 (valid_name, String.Symbol), |
|
1660 |
|
1661 # parentheses |
|
1662 (r'(\(|\))', Punctuation), |
|
1663 ], |
|
1664 |
|
1665 # braced strings... |
|
1666 'bracestring': [ |
|
1667 ("{", String, "#push"), |
|
1668 ("}", String, "#pop"), |
|
1669 ("[^{}]+", String), |
|
1670 ], |
|
1671 |
|
1672 # tagged [text]...[/text] delimited strings... |
|
1673 'tagstring': [ |
|
1674 (r'(?s)(.*?)(\[/text\])', String, '#pop'), |
|
1675 ], |
|
1676 } |
|
1677 |
|
1678 |
|
1679 class ElixirLexer(RegexLexer): |
|
1680 """ |
|
1681 For the `Elixir language <http://elixir-lang.org>`_. |
|
1682 |
|
1683 *New in Pygments 1.5.* |
|
1684 """ |
|
1685 |
|
1686 name = 'Elixir' |
|
1687 aliases = ['elixir', 'ex', 'exs'] |
|
1688 filenames = ['*.ex', '*.exs'] |
|
1689 mimetypes = ['text/x-elixir'] |
|
1690 |
|
1691 tokens = { |
|
1692 'root': [ |
|
1693 (r'\s+', Text), |
|
1694 (r'#.*$', Comment.Single), |
|
1695 (r'\b(case|end|bc|lc|if|unless|try|loop|receive|fn|defmodule|' |
|
1696 r'defp|def|defprotocol|defimpl|defrecord|defmacro|defdelegate|' |
|
1697 r'defexception|exit|raise|throw)\b(?![?!])|' |
|
1698 r'(?<!\.)\b(do|\-\>)\b\s*', Keyword), |
|
1699 (r'\b(import|require|use|recur|quote|unquote|super)\b(?![?!])', |
|
1700 Keyword.Namespace), |
|
1701 (r'(?<!\.)\b(and|not|or|when|xor|in)\b', Operator.Word), |
|
1702 (r'%=|\*=|\*\*=|\+=|\-=|\^=|\|\|=|' |
|
1703 r'<=>|<(?!<|=)|>(?!<|=|>)|<=|>=|===|==|=~|!=|!~|(?=[ \t])\?|' |
|
1704 r'(?<=[ \t])!+|&&|\|\||\^|\*|\+|\-|/|' |
|
1705 r'\||\+\+|\-\-|\*\*|\/\/|\<\-|\<\>|<<|>>|=|\.', Operator), |
|
1706 (r'(?<!:)(:)([a-zA-Z_]\w*([?!]|=(?![>=]))?|\<\>|===?|>=?|<=?|' |
|
1707 r'<=>|&&?|%\(\)|%\[\]|%\{\}|\+\+?|\-\-?|\|\|?|\!|//|[%&`/\|]|' |
|
1708 r'\*\*?|=?~|<\-)|([a-zA-Z_]\w*([?!])?)(:)(?!:)', String.Symbol), |
|
1709 (r':"', String.Symbol, 'interpoling_symbol'), |
|
1710 (r'\b(nil|true|false)\b(?![?!])', Name.Constant), |
|
1711 (r'\b[A-Z]\w*\b', Name.Constant), |
|
1712 (r'\b(__(FILE|LINE|MODULE|STOP_ITERATOR|EXCEPTION|OP|REF|FUNCTION|' |
|
1713 r'BLOCK|KVBLOCK)__)\b(?![?!])', Name.Builtin.Pseudo), |
|
1714 (r'[a-zA-Z_!]\w*[!\?]?', Name), |
|
1715 (r'[(){};,/\|:\\\[\]]', Punctuation), |
|
1716 (r'@[a-zA-Z_]\w*|&\d', Name.Variable), |
|
1717 (r'\b(0[xX][0-9A-Fa-f]+|\d(_?\d)*(\.(?![^\d\s])' |
|
1718 r'(_?\d)*)?([eE][-+]?\d(_?\d)*)?|0[bB][01]+)\b', Number), |
|
1719 include('strings'), |
|
1720 ], |
|
1721 'strings': [ |
|
1722 (r'"""(?:.|\n)*?"""', String.Doc), |
|
1723 (r"'''(?:.|\n)*?'''", String.Doc), |
|
1724 (r'"', String.Double, 'dqs'), |
|
1725 (r"'.*'", String.Single), |
|
1726 (r'(?<!\w)\?(\\(x\d{1,2}|\h{1,2}(?!\h)\b|0[0-7]{0,2}(?![0-7])\b|' |
|
1727 r'[^x0MC])|(\\[MC]-)+\w|[^\s\\])', String.Other) |
|
1728 ], |
|
1729 'dqs': [ |
|
1730 (r'"', String.Double, "#pop"), |
|
1731 include('interpoling'), |
|
1732 (r'[^#"]+', String.Double), |
|
1733 ], |
|
1734 'interpoling': [ |
|
1735 (r'#{', String.Interpol, 'interpoling_string'), |
|
1736 ], |
|
1737 'interpoling_string' : [ |
|
1738 (r'}', String.Interpol, "#pop"), |
|
1739 include('root') |
|
1740 ], |
|
1741 'interpoling_symbol': [ |
|
1742 (r'"', String.Symbol, "#pop"), |
|
1743 include('interpoling'), |
|
1744 (r'[^#"]+', String.Symbol), |
|
1745 ], |
|
1746 } |
|
1747 |
|
1748 |
|
1749 class ElixirConsoleLexer(Lexer): |
|
1750 """ |
|
1751 For Elixir interactive console (iex) output like: |
|
1752 |
|
1753 .. sourcecode:: iex |
|
1754 |
|
1755 iex> [head | tail] = [1,2,3] |
|
1756 [1,2,3] |
|
1757 iex> head |
|
1758 1 |
|
1759 iex> tail |
|
1760 [2,3] |
|
1761 iex> [head | tail] |
|
1762 [1,2,3] |
|
1763 iex> length [head | tail] |
|
1764 3 |
|
1765 |
|
1766 *New in Pygments 1.5.* |
|
1767 """ |
|
1768 |
|
1769 name = 'Elixir iex session' |
|
1770 aliases = ['iex'] |
|
1771 mimetypes = ['text/x-elixir-shellsession'] |
|
1772 |
|
1773 _prompt_re = re.compile('(iex|\.{3})> ') |
|
1774 |
|
1775 def get_tokens_unprocessed(self, text): |
|
1776 exlexer = ElixirLexer(**self.options) |
|
1777 |
|
1778 curcode = '' |
|
1779 insertions = [] |
|
1780 for match in line_re.finditer(text): |
|
1781 line = match.group() |
|
1782 if line.startswith('** '): |
|
1783 insertions.append((len(curcode), |
|
1784 [(0, Generic.Error, line[:-1])])) |
|
1785 curcode += line[-1:] |
|
1786 else: |
|
1787 m = self._prompt_re.match(line) |
|
1788 if m is not None: |
|
1789 end = m.end() |
|
1790 insertions.append((len(curcode), |
|
1791 [(0, Generic.Prompt, line[:end])])) |
|
1792 curcode += line[end:] |
|
1793 else: |
|
1794 if curcode: |
|
1795 for item in do_insertions(insertions, |
|
1796 exlexer.get_tokens_unprocessed(curcode)): |
|
1797 yield item |
|
1798 curcode = '' |
|
1799 insertions = [] |
|
1800 yield match.start(), Generic.Output, line |
|
1801 if curcode: |
|
1802 for item in do_insertions(insertions, |
|
1803 exlexer.get_tokens_unprocessed(curcode)): |
|
1804 yield item |