diff --git a/loader/lang-eiffel.js b/loader/lang-eiffel.js new file mode 100644 index 00000000..31133a2f --- /dev/null +++ b/loader/lang-eiffel.js @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2018-2020 Alexander Kogtenkov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^\s+/u,null,' \r\n\t\xA0'],["str",/^(?:'''|'[^']+')/,null,"'"],["str",/^"(?:(?:%[ \t\v]*[\r\n]\s*%|%"|[^"\r\n])*|\[(?=\s*[\r\n])[\s\S]*[\r\n]\s*\]|\{(?=\s*[\r\n])[\s\S]*[\r\n]\s*\})"/,null,'"'],["lit",/^0[bcx][a-f\d](?:[_a-f\d]*[a-f\d])?|(?:\d(?:[_\d]*\d)?(?:\.(?:\d(?:[_\d]*\d)?)?(?:e[-+]?\d+)?)?)/i,null,'0123456789']],[["com",/^--[^\r\n]*/],["kwd",/^\b(?:across|agent|alias|all|and|as|assign|attached|attribute|check|class|convert|create|debug|deferred|detachable|do|else|elseif|end|ensure|expanded|export|external|feature|from|frozen|if|implies|inherit|inspect|invariant|like|local|loop|not|note|obsolete|old|once|only|or|redefine|rename|require|rescue|retry|select|separate|some|then|undefine|until|variant|when|xor)\b/i],["kwd",/^\b(?:Current|Precursor|Result)\b/i],["kwd",/^[\u2200\u2203\xA6\u27F3\u27F2]/iu],["lit",/^\b(?:False|True|Void)\b/i],["typ",/^[A-Z][_A-Z\d]*/],["lit",/^\.\d(?:[_\d]*\d)?(?:e[-+]?\d+)?/i],["pln",/^[a-z]\w*/iu],["pun",/^[^\s\xA0\w'"\u2200\u2203\xA6\u27F3\u27F2]+/]]),['eiffel','e']); diff --git a/src/lang-eiffel.js b/src/lang-eiffel.js new file mode 100644 index 00000000..472e371d --- /dev/null +++ b/src/lang-eiffel.js @@ -0,0 +1,61 @@ +/** + * @license + * Copyright (C) 2018-2020 Alexander Kogtenkov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @fileoverview + * Registers a language handler for Eiffel. + * + * To use, include prettify.js and this file in your HTML page. + * Then put your code in an HTML tag like + *
(my Eiffel code)
+ * + * @author Alexander Kogtenkov + */ + +PR.registerLangHandler( + PR.createSimpleLexer( + [ // shortcutStylePatterns + // Whitespace + [PR['PR_PLAIN'], /^\s+/u, null, ' \r\n\t\xA0'], + // Character + [PR['PR_STRING'], /^(?:'''|'[^']+')/, null, "'"], + // String + [PR['PR_STRING'], /^"(?:(?:%[ \t\v]*[\r\n]\s*%|%"|[^"\r\n])*|\[(?=\s*[\r\n])[\s\S]*[\r\n]\s*\]|\{(?=\s*[\r\n])[\s\S]*[\r\n]\s*\})"/, null, '"'], + // Integer or real starting from a digit + [PR['PR_LITERAL'], /^0[bcx][a-f\d](?:[_a-f\d]*[a-f\d])?|(?:\d(?:[_\d]*\d)?(?:\.(?:\d(?:[_\d]*\d)?)?(?:e[-+]?\d+)?)?)/i, null, '0123456789'] + ], + [ // fallthroughStylePatterns + // A line comment + [PR['PR_COMMENT'], /^--[^\r\n]*/], + // Keyword + [PR['PR_KEYWORD'], /^\b(?:across|agent|alias|all|and|as|assign|attached|attribute|check|class|convert|create|debug|deferred|detachable|do|else|elseif|end|ensure|expanded|export|external|feature|from|frozen|if|implies|inherit|inspect|invariant|like|local|loop|not|note|obsolete|old|once|only|or|redefine|rename|require|rescue|retry|select|separate|some|then|undefine|until|variant|when|xor)\b/i], + // A reserved word: entity + [PR['PR_KEYWORD'], /^\b(?:Current|Precursor|Result)\b/i], + // A reserved symbol: syntax (for_all, there_exists, broken_bar, clockwise_gapped_circle_arrow, anticlockwise_gapped_circle_arrow) + [PR['PR_KEYWORD'], /^[\u2200\u2203\xA6\u27F3\u27F2]/iu], + // A reserved word: value + [PR['PR_LITERAL'], /^\b(?:False|True|Void)\b/i], + // Treat an upper case identifier as a type + [PR['PR_TYPE'], /^[A-Z][_A-Z\d]*/], + // Real starting from a dot + [PR['PR_LITERAL'], /^\.\d(?:[_\d]*\d)?(?:e[-+]?\d+)?/i], + // Identifier + [PR['PR_PLAIN'], /^[a-z]\w*/iu], + // Other symbols + [PR['PR_PUNCTUATION'], /^[^\s\xA0\w'"\u2200\u2203\xA6\u27F3\u27F2]+/] + ]), + ['eiffel','e']); diff --git a/tests/prettify_test_2.html b/tests/prettify_test_2.html index c62e032b..69dd4e24 100644 --- a/tests/prettify_test_2.html +++ b/tests/prettify_test_2.html @@ -25,6 +25,7 @@ 'lang-clj.js', 'lang-css.js', 'lang-dart.js', + 'lang-eiffel.js', 'lang-ex.js', 'lang-kotlin.js', 'lang-lisp.js', @@ -1201,5 +1202,65 @@

Kotlin

fun Boolean?.getOrThrow(): Boolean = this ?: throw Exception() + +

Eiffel

+
+note
+	description: "[
+		A test class with "string" literals, numbers, etc.
+	]"
+	usage: "[testing %"quotes%"]"
+
+class POLYGON
+
+inherit
+	ANY
+		rename
+			default_create as make
+		redefine
+			make,
+			out
+		end
+
+feature {NONE} -- Creation
+
+	make
+			-- Set coordinates to (0, 0).
+		do
+			x_offset := 0
+			y_offset := 123 - 0c124 + 0b001 + 1.0 + 1. - .0 + .1e3 - 1.e03 + (1_234.567_8 - 12_345.678e-1)
+		end
+
+feature -- Access
+
+	x_offset, y_offset: INTEGER_64
+			-- Offset of the polygon.
+
+	mask: NATURAL_8 = 0xA5
+			-- A color mask.
+
+feature -- Output
+
+	out: STRING
+			-- <Precursor>
+		do
+			Result :=
+				"An old-style %
+				%multi-line string with " +
+				"%
+				%%"quotes%"%
+				%" +
+				"{
+					and a "new"-style one.
+				}"
+			Result.precede ('=')
+			Result.append_boolean (∀ x: Result ¦ x >= ' ')
+		ensure then
+			result_attached: Result /= Void
+		end
+
+end
+
+ diff --git a/tests/prettify_test_2.js b/tests/prettify_test_2.js index 03e29f5a..20760080 100644 --- a/tests/prettify_test_2.js +++ b/tests/prettify_test_2.js @@ -1068,5 +1068,62 @@ var goldens = { ' `END`ATV~C<hello>`END`PLN\n' + ' `END`KWDend`END`PLN\n' + '\n' + -'`END`KWDend`END') +'`END`KWDend`END'), + eiffel: ( + '`KWDnote`END`PLN\n' + + ' description`END`PUN:`END`PLN `END`STR"[\n' + + ' A test class with "string" literals, numbers, etc.\n' + + ' ]"`END`PLN\n' + + ' usage`END`PUN:`END`PLN `END`STR"[testing %"quotes%"]"`END`PLN\n' + + '\n' + + '`END`KWDclass`END`PLN `END`TYPPOLYGON`END`PLN\n' + + '\n' + + '`END`KWDinherit`END`PLN\n' + + ' `END`TYPANY`END`PLN\n' + + ' `END`KWDrename`END`PLN\n' + + ' default_create `END`KWDas`END`PLN make\n' + + ' `END`KWDredefine`END`PLN\n' + + ' make`END`PUN,`END`PLN\n' + + ' out\n' + + ' `END`KWDend`END`PLN\n' + + '\n' + + '`END`KWDfeature`END`PLN `END`PUN{`END`TYPNONE`END`PUN}`END`PLN `END`COM-- Creation`END`PLN\n' + + '\n' + + ' make\n' + + ' `END`COM-- Set coordinates to (0, 0).`END`PLN\n' + + ' `END`KWDdo`END`PLN\n' + + ' x_offset `END`PUN:=`END`PLN `END`LIT0`END`PLN\n' + + ' y_offset `END`PUN:=`END`PLN `END`LIT123`END`PLN `END`PUN-`END`PLN `END`LIT0c124`END`PLN `END`PUN+`END`PLN `END`LIT0b001`END`PLN `END`PUN+`END`PLN `END`LIT1.0`END`PLN `END`PUN+`END`PLN `END`LIT1.`END`PLN `END`PUN-`END`PLN `END`LIT.0`END`PLN `END`PUN+`END`PLN `END`LIT.1e3`END`PLN `END`PUN-`END`PLN `END`LIT1.e03`END`PLN `END`PUN+`END`PLN `END`PUN(`END`LIT1_234.567_8`END`PLN `END`PUN-`END`PLN `END`LIT12_345.678e-1`END`PUN)`END`PLN\n' + + ' `END`KWDend`END`PLN\n' + + '\n' + + '`END`KWDfeature`END`PLN `END`COM-- Access`END`PLN\n' + + '\n' + + ' x_offset`END`PUN,`END`PLN y_offset`END`PUN:`END`PLN `END`TYPINTEGER_64`END`PLN\n' + + ' `END`COM-- Offset of the polygon.`END`PLN\n' + + '\n' + + ' mask`END`PUN:`END`PLN `END`TYPNATURAL_8`END`PLN `END`PUN=`END`PLN `END`LIT0xA5`END`PLN\n' + + ' `END`COM-- A color mask.`END`PLN\n' + + '\n' + + '`END`KWDfeature`END`PLN `END`COM-- Output`END`PLN\n' + + '\n' + + ' out`END`PUN:`END`PLN `END`TYPSTRING`END`PLN\n' + + ' `END`COM-- <Precursor>`END`PLN\n' + + ' `END`KWDdo`END`PLN\n' + + ' `END`KWDResult`END`PLN `END`PUN:=`END`PLN\n' + + ' `END`STR"An old-style %\n' + + ' %multi-line string with "`END`PLN `END`PUN+`END`PLN\n' + + ' `END`STR"%\n' + + ' %%"quotes%"%\n' + + ' %"`END`PLN `END`PUN+`END`PLN\n' + + ' `END`STR"{\n' + + ' and a "new"-style one.\n' + + ' }"`END`PLN\n' + + ' `END`KWDResult`END`PUN.`END`PLNprecede `END`PUN(`END`STR\'=\'`END`PUN)`END`PLN\n' + + ' `END`KWDResult`END`PUN.`END`PLNappend_boolean `END`PUN(`END`KWD\u2200`END`PLN x`END`PUN:`END`PLN `END`KWDResult`END`PLN `END`KWD\xA6`END`PLN x `END`PUN>=`END`PLN `END`STR\' \'`END`PUN)`END`PLN\n' + + ' `END`KWDensure`END`PLN `END`KWDthen`END`PLN\n' + + ' result_attached`END`PUN:`END`PLN `END`KWDResult`END`PLN `END`PUN/=`END`PLN `END`LITVoid`END`PLN\n' + + ' `END`KWDend`END`PLN\n' + + '\n' + + '`END`KWDend`END' + ) };