From 5c1d0396da4abcbf5e59440dde32b4e687ad19ae Mon Sep 17 00:00:00 2001 From: Martijn Laarman Date: Mon, 17 Feb 2025 16:39:06 +0100 Subject: [PATCH 1/2] Add ES|QL language support and move hl theme over to theme colors --- docs/testing/custom-highlighters.md | 45 +++++++++- src/Elastic.Markdown/Assets/hljs.ts | 69 +++++++++++++++- src/Elastic.Markdown/Assets/markdown/code.css | 82 +++++++++++++++++++ src/Elastic.Markdown/Assets/styles.css | 1 - .../Myst/CodeBlocks/SupportedLanguages.cs | 3 +- 5 files changed, 196 insertions(+), 4 deletions(-) diff --git a/docs/testing/custom-highlighters.md b/docs/testing/custom-highlighters.md index cde141e91..cc6f559cb 100644 --- a/docs/testing/custom-highlighters.md +++ b/docs/testing/custom-highlighters.md @@ -32,6 +32,7 @@ GET /mydocuments/_search } ``` ```` +:::: ## EQL @@ -68,4 +69,46 @@ function calls modulo(10, 6) modulo(10, 5) modulo(10, 0.5) -``` \ No newline at end of file +``` + + + + ## ESQL + + +```esql +FROM employees +| LIMIT 1000 +``` + +```esql +ROW a = "2023-01-23T12:15:00.000Z - some text - 127.0.0.1" +| DISSECT a """%{date} - %{msg} - %{ip}""" +| KEEP date, msg, ip +``` + +```esql +FROM books +| WHERE KQL("author: Faulkner") +| KEEP book_no, author +| SORT book_no +| LIMIT 5 +``` + +```esql +FROM hosts +| STATS COUNT_DISTINCT(ip0), COUNT_DISTINCT(ip1) +``` + +```esql +ROW message = "foo ( bar" +| WHERE message RLIKE "foo \\( bar" +``` + +```esql +FROM books +| WHERE author:"Faulkner" +| KEEP book_no, author +| SORT book_no +| LIMIT 5; +``` diff --git a/src/Elastic.Markdown/Assets/hljs.ts b/src/Elastic.Markdown/Assets/hljs.ts index f00895a79..fa3fe8d6b 100644 --- a/src/Elastic.Markdown/Assets/hljs.ts +++ b/src/Elastic.Markdown/Assets/hljs.ts @@ -43,7 +43,6 @@ const NUMBER = { relevance: 0 }; - hljs.registerLanguage('eql', function() { return { case_insensitive: true, // language is case-insensitive @@ -69,6 +68,74 @@ hljs.registerLanguage('eql', function() { } }) +hljs.registerLanguage('esql', function() { + return { + case_insensitive: true, // language is case-insensitive + keywords: { + keyword: 'FROM ROW SHOW DISSECT DROP ENRICH EVAL GROK KEEP LIMIT RENAME SORT STATS WHERE METADATA', + literal: ['false','true','null'], + function: [ + // aggregate + "AVG", "COUNT", "COUNT_DISTINCT", "MAX", "MEDIAN", "MEDIAN_ABSOLUTE_DEVIATION", "MIN", + "PERCENTILE", "SUM", "TOP", "VALUES", "WEIGHTED_AVG", "BUCKET", + + // conditional + "CASE", "COALESCE", "GREATEST", "LEAST", + + //Date + "DATE_DIFF", "DATE_EXTRACT", "DATE_FORMAT", "DATE_PARSE", "DATE_TRUNC", "NOW", + + //ip + "CIDR_MATCH", "IP_PREFIX", + + //math + "ABS", "ACOS", "ASIN", "ATAN", "ATAN2", "CBRT", "CEIL", "COS", "COSH", "E", "EXP", "FLOOR", + "HYPOT", "LOG", "LOG10", "PI", "POW", "ROUND", "SIGNUM", "SIN", "SINH", "SQRT", "TAN", + "TANH", "TAU", + + //search + "MATCH", "QSTR", + + //spatial + "ST_DISTANCE", "ST_INTERSECTS", "ST_DISJOINT", "ST_CONTAINS", "ST_WITHIN", "ST_X", "ST_Y", + + //string + + "BIT_LENGTH", "BYTE_LENGTH", "CONCAT", "ENDS_WITH", "FROM_BASE64", "LEFT", "LENGTH", "LOCATE", + "LTRIM", "REPEAT", "REPLACE", "REVERSE", "RIGHT", "RTRIM", "SPACE", "SPLIT", "STARTS_WITH", + "SUBSTRING", "TO_BASE64", "TO_LOWER", "TO_UPPER", "TRIM", + + //type conversion + "TO_BOOLEAN", "TO_CARTESIANPOINT", "TO_CARTESIANSHAPE", "TO_DATETIME", "TO_DEGREES", + "TO_DOUBLE", "TO_GEOPOINT", "TO_GEOSHAPE", "TO_INTEGER", "TO_IP", "TO_LONG", "TO_RADIANS", + "TO_STRING", "TO_VERSION", + + //multivalued + "MV_APPEND", "MV_AVG", "MV_CONCAT", "MV_COUNT", "MV_DEDUPE", "MV_FIRST", "MV_LAST", "MV_MAX", + "MV_MEDIAN", "MV_MEDIAN_ABSOLUTE_DEVIATION", "MV_MIN", "MV_PERCENTILE", "MV_PSERIES_WEIGHTED_SUM", + "MV_SORT", "MV_SLICE", "MV_SUM", "MV_ZIP", + + "KQL" + ] + }, + contains: [ + hljs.QUOTE_STRING_MODE, + hljs.C_LINE_COMMENT_MODE, + { + scope: "operator", // (pathname: path1/path2/dothis) color #ab5656 + match: /(?:<|<=|==|::|\w+:|!=|>=|>|LIKE|RLIKE|IS NULL|IS NOT NULL)/, + }, + { + scope: "punctuation", // (pathname: path1/path2/dothis) color #ab5656 + match: /(?:!?\[|\]|\|)/, + }, + NUMBER, + + ] + } +}) + + hljs.addPlugin(mergeHTMLPlugin); export function initHighlight() { diff --git a/src/Elastic.Markdown/Assets/markdown/code.css b/src/Elastic.Markdown/Assets/markdown/code.css index ce2241917..a80f619cf 100644 --- a/src/Elastic.Markdown/Assets/markdown/code.css +++ b/src/Elastic.Markdown/Assets/markdown/code.css @@ -79,4 +79,86 @@ text-decoration: inherit; font-weight: inherit; } + + + .hljs-built_in, + .hljs-selector-tag, + .hljs-section, + .hljs-link { + color: var(--color-blue-elastic-70) + } + + .hljs-keyword { + color: var(--color-blue-elastic-70) + } + + .hljs { + color: var(--color-blue-elastic-30) !important; + } + .hljs-subst { + color: var(--color-purple-60) + } + .hljs-function { + color: var(--color-purple-60) + } + + .hljs-title, + .hljs-title.function, + .hljs-attr, + .hljs-meta-keyword { + color: var(--color-yellow-50) + } + + .hljs-string { + color: var(--color-green-50) + } + .hljs-operator { + color: var(--color-yellow-50) + } + + .hljs-meta, + .hljs-name, + .hljs-type, + .hljs-symbol, + .hljs-bullet, + .hljs-addition, + .hljs-variable, + .hljs-template-tag, + .hljs-template-variable { + color: var(--color-yellow-50) + } + + .hljs-comment, + .hljs-quote, + .hljs-deletion { + color: var(--color-grey-70) + } + + .hljs-punctuation { + color: var(--color-grey-50); + font-weight: bold; + } + + .hljs-keyword, + .hljs-selector-tag, + .hljs-literal, + .hljs-title, + .hljs-section, + .hljs-doctag, + .hljs-type, + .hljs-name, + .hljs-strong { + font-weight: bold; + } + + .hljs-literal { + color: var(--color-pink-50) + } + .hljs-number { + color: var(--color-teal-50) + } + + .hljs-emphasis { + font-style: italic; + } } diff --git a/src/Elastic.Markdown/Assets/styles.css b/src/Elastic.Markdown/Assets/styles.css index 7c237e978..e8d68c97d 100644 --- a/src/Elastic.Markdown/Assets/styles.css +++ b/src/Elastic.Markdown/Assets/styles.css @@ -1,7 +1,6 @@ @import "tailwindcss"; @import "./fonts.css"; @import "./theme.css"; -@import "highlight.js/styles/github-dark-dimmed.css"; @import "./markdown/typography.css"; @import "./markdown/list.css"; @import "./markdown/tabs.css"; diff --git a/src/Elastic.Markdown/Myst/CodeBlocks/SupportedLanguages.cs b/src/Elastic.Markdown/Myst/CodeBlocks/SupportedLanguages.cs index 38e3ff95f..bc44bdeb7 100644 --- a/src/Elastic.Markdown/Myst/CodeBlocks/SupportedLanguages.cs +++ b/src/Elastic.Markdown/Myst/CodeBlocks/SupportedLanguages.cs @@ -181,7 +181,8 @@ public static class CodeBlock { "zephir", "zep" }, // Zephir //CUSTOM, Elastic language we wrote highlighters for - { "eql", "" } + { "eql", "" }, + { "esql", "" } }; From 55f65349dee09ac5552b8dfa9f150d0dd7e77227 Mon Sep 17 00:00:00 2001 From: Martijn Laarman Date: Tue, 18 Feb 2025 09:48:33 +0100 Subject: [PATCH 2/2] Add Painless language support (#521) --- docs/testing/custom-highlighters.md | 37 +++++++++++++++++++ src/Elastic.Markdown/Assets/hljs.ts | 26 +++++++++++++ src/Elastic.Markdown/Assets/markdown/code.css | 13 +++++-- .../CodeBlocks/EnhancedCodeBlockParser.cs | 1 + 4 files changed, 73 insertions(+), 4 deletions(-) diff --git a/docs/testing/custom-highlighters.md b/docs/testing/custom-highlighters.md index cc6f559cb..35fec9e3f 100644 --- a/docs/testing/custom-highlighters.md +++ b/docs/testing/custom-highlighters.md @@ -112,3 +112,40 @@ FROM books | SORT book_no | LIMIT 5; ``` + +## Painless + +```painless +int i = (int)5L; +Map m = new HashMap(); +HashMap hm = (HashMap)m; +``` + +```painless +ZonedDateTime zdt1 = + ZonedDateTime.of(1983, 10, 13, 22, 15, 30, 0, ZoneId.of('Z')); +ZonedDateTime zdt2 = + ZonedDateTime.of(1983, 10, 17, 22, 15, 35, 0, ZoneId.of('Z')); + +if (zdt1.isAfter(zdt2)) { + // handle condition +} +``` + +```painless +if (doc.containsKey('start') && doc.containsKey('end')) { + + if (doc['start'].size() > 0 && doc['end'].size() > 0) { + + ZonedDateTime start = doc['start'].value; + ZonedDateTime end = doc['end'].value; + long differenceInMillis = ChronoUnit.MILLIS.between(start, end); + + // handle difference in times + } else { + // handle fields without values + } +} else { + // handle index with missing fields +} +``` \ No newline at end of file diff --git a/src/Elastic.Markdown/Assets/hljs.ts b/src/Elastic.Markdown/Assets/hljs.ts index fa3fe8d6b..675963dc4 100644 --- a/src/Elastic.Markdown/Assets/hljs.ts +++ b/src/Elastic.Markdown/Assets/hljs.ts @@ -68,6 +68,32 @@ hljs.registerLanguage('eql', function() { } }) +hljs.registerLanguage('painless', function() { + return { + case_insensitive: true, // language is case-insensitive + keywords: { + keyword: 'where sequence sample untill and or not in in~', + literal: ['false','true','null'], + 'subst': 'add between cidrMatch concat divide endsWith indexOf length modulo multiply number startsWith string stringContains substring subtract' + }, + contains: [ + hljs.QUOTE_STRING_MODE, + hljs.C_LINE_COMMENT_MODE, + { + scope: "operator", // (pathname: path1/path2/dothis) color #ab5656 + match: /(?:<|<=|==|:|!=|>=|>|like~?|regex~?)/, + }, + { + scope: "punctuation", // (pathname: path1/path2/dothis) color #ab5656 + match: /(?:!?\[|\]|\|)/, + }, + NUMBER, + + ] + } +}) + + hljs.registerLanguage('esql', function() { return { case_insensitive: true, // language is case-insensitive diff --git a/src/Elastic.Markdown/Assets/markdown/code.css b/src/Elastic.Markdown/Assets/markdown/code.css index a80f619cf..b01ef22dd 100644 --- a/src/Elastic.Markdown/Assets/markdown/code.css +++ b/src/Elastic.Markdown/Assets/markdown/code.css @@ -118,16 +118,21 @@ .hljs-meta, .hljs-name, - .hljs-type, - .hljs-symbol, .hljs-bullet, .hljs-addition, - .hljs-variable, .hljs-template-tag, .hljs-template-variable { color: var(--color-yellow-50) } + .hljs-type, + .hljs-symbol { + color: var(--color-teal-50) + } + .hljs-variable { + color: var(--color-purple-50) + } + .hljs-comment, .hljs-quote, .hljs-deletion { @@ -155,7 +160,7 @@ color: var(--color-pink-50) } .hljs-number { - color: var(--color-teal-50) + color: var(--color-red-50) } .hljs-emphasis { diff --git a/src/Elastic.Markdown/Myst/CodeBlocks/EnhancedCodeBlockParser.cs b/src/Elastic.Markdown/Myst/CodeBlocks/EnhancedCodeBlockParser.cs index 5cd0787c8..6857fa991 100644 --- a/src/Elastic.Markdown/Myst/CodeBlocks/EnhancedCodeBlockParser.cs +++ b/src/Elastic.Markdown/Myst/CodeBlocks/EnhancedCodeBlockParser.cs @@ -85,6 +85,7 @@ public override bool Close(BlockProcessor processor, Block block) "console-response" => "json", "console-result" => "json", "terminal" => "bash", + "painless" => "java", _ => codeBlock.Language }; if (!string.IsNullOrEmpty(codeBlock.Language) && !CodeBlock.Languages.Contains(codeBlock.Language))