diff --git a/gulp.d/tasks/build.js b/gulp.d/tasks/build.js index ffe3f382..475e273c 100644 --- a/gulp.d/tasks/build.js +++ b/gulp.d/tasks/build.js @@ -21,6 +21,21 @@ const postcssVar = require('postcss-custom-properties') const { Transform } = require('stream') const map = (transform) => new Transform({ objectMode: true, transform }) const through = () => map((file, enc, next) => next(null, file)) +// Minifying drops some license notices (/*! ... */ comments), which the licenses of the bundled +// libraries require us to keep, so record them first and put back any that are lost. +const LICENSE_NOTICE_RX = /\/\*![\s\S]*?\*\//g +const recordLicenseNotices = () => + map((file, enc, next) => { + file.licenseNotices = [...new Set(file.contents.toString().match(LICENSE_NOTICE_RX))] + next(null, file) + }) +const restoreLicenseNotices = () => + map((file, enc, next) => { + const code = file.contents.toString() + const lost = (file.licenseNotices || []).filter((notice) => !code.includes(notice)) + if (lost.length) file.contents = Buffer.from(lost.join('\n') + '\n' + code) + next(null, file) + }) const uglify = require('gulp-uglify') const vfs = require('vinyl-fs') const hash = require('gulp-hash') @@ -84,9 +99,9 @@ module.exports = (src, dest, preview) => () => { vfs .src('js/vendor/*([^.])?(.bundle).js', { ...opts, read: false }) .pipe(bundle(opts)) - // .pipe(uglify({ output: { comments: /^! / } })) - .pipe(map((file) => file.relative === 'js/vendor/floatingui.js') - ? through() : uglify({ output: { comments: /^! / } })) + .pipe(recordLicenseNotices()) + .pipe(gulpif((file) => file.relative !== 'js/vendor/floatingui.js', uglify({ output: { comments: /^! / } }))) + .pipe(restoreLicenseNotices()) .pipe(gulpif( !preview, hash({ template: '<%= name %>-<%= hash %><%= ext %>' }))) diff --git a/gulpfile.js b/gulpfile.js index 47e1aa3d..7359d643 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -18,7 +18,9 @@ const task = require('./gulp.d/tasks') const glob = { all: [srcDir, previewSrcDir], css: `${srcDir}/css/**/*.css`, - js: ['gulpfile.js', 'gulp.d/**/*.js', `${srcDir}/{helpers,js}/**/*.js`], + // src/js/vendor/languages holds grammars maintained elsewhere (see its README); they keep + // their upstream formatting, so lint and format skip them. + js: ['gulpfile.js', 'gulp.d/**/*.js', `${srcDir}/{helpers,js}/**/*.js`, `!${srcDir}/js/vendor/languages/**`], } const cleanTask = createTask({ diff --git a/preview-src/asciidoc/code.adoc b/preview-src/asciidoc/code.adoc index b4801566..7cf17855 100644 --- a/preview-src/asciidoc/code.adoc +++ b/preview-src/asciidoc/code.adoc @@ -81,6 +81,94 @@ public class CurrentDateTime { } ---- +=== Syntax highlighting samples + +These samples show how each kind of token is colored in the languages the docs use most, and in PowerShell. + +.CQL: schema and queries +[source,cql] +---- +CREATE TABLE IF NOT EXISTS store.orders ( + order_id uuid, + placed_at timestamp, + status text, + items list>>, + embedding vector, + PRIMARY KEY ((order_id), placed_at) +) WITH CLUSTERING ORDER BY (placed_at DESC) + AND comment = 'Orders by customer' + AND default_time_to_live = 0; + +SELECT order_id, writetime(status), toJson(items) FROM store.orders +WHERE order_id = 6ab09bec-e68e-48d9-a5f8-97e6fb4c9b47 + AND placed_at >= ? -- a bind marker +ORDER BY embedding ANN OF [0.1, 0.2, 0.3] LIMIT 5; +---- + +.CQL: syntax summary with placeholders +[source,cql] +---- +CREATE TABLE [ IF NOT EXISTS ] [.] + ( [ STATIC ] [ PRIMARY KEY ] [ , ... ] ) + [ WITH ] ; +---- + +.CQL: cqlsh session +[source,cql] +---- +cqlsh> CONSISTENCY LOCAL_QUORUM +cqlsh> USE store; +cqlsh:store> SELECT order_id, status FROM orders LIMIT 1; + + order_id | status +--------------------------------------+-------- + 6ab09bec-e68e-48d9-a5f8-97e6fb4c9b47 | NEW + +(1 rows) +---- + +.GraphQL +[source,graphql] +---- +query getOrder($id: Uuid!) { + orders(value: { order_id: $id }) @cql_column(name: "orders") { + values { order_id status } + } +} +---- + +.YAML +[source,yaml] +---- +# Audit logging in cassandra.yaml +audit_logging_options: + enabled: true + logger: + - class_name: BinAuditLogger + included_categories: QUERY, DDL, AUTH +---- + +.XML +[source,xml] +---- + + + org.apache.cassandra + java-driver-core + ${driver.version} + +---- + +.PowerShell +[source,powershell] +---- +# Install the Astra CLI on Windows +$env:ASTRA_HOME = "C:\Tools\astra" +New-Item -ItemType Directory -Force -Path $env:ASTRA_HOME | Out-Null +Expand-Archive -Path "$env:TEMP\astra.zip" -DestinationPath $env:ASTRA_HOME -Force +if (-not (Get-Command astra -ErrorAction SilentlyContinue)) { Write-Output "Add $env:ASTRA_HOME to PATH" } +---- + === Line wrapping .Line wrapping is turned off by default diff --git a/src/css/asciidoc/doc.css b/src/css/asciidoc/doc.css index b3be67da..e9fed258 100644 --- a/src/css/asciidoc/doc.css +++ b/src/css/asciidoc/doc.css @@ -764,7 +764,9 @@ padding: var(--ds-space-2); } - .doc .language-console .hljs-meta { + /* Prompts (console $, cqlsh>) are not selected along with the commands after them. */ + .doc .language-console .hljs-meta, + .doc .language-cql .hljs-meta { user-select: none; } diff --git a/src/css/highlight.css b/src/css/highlight.css index 035a4d89..7f3478e9 100644 --- a/src/css/highlight.css +++ b/src/css/highlight.css @@ -1,109 +1,94 @@ -.hljs-comment { - color: var(--ds-text-tertiary); -} +/* Syntax highlighting for code blocks, for highlight.js 9 class names and the highlight.js 11 + sub-scopes that differ. Colors come from the --ds-code-* variables in vars/light.css and + vars/dark.css; each has at least 4.5:1 contrast (WCAG AA) on the code block background. + Punctuation, operators, parameters, and names stay in the text color. */ +.hljs-comment, .hljs-quote { - color: var(--ds-text-tertiary); -} - -.hljs-variable { - color: var(--ds-failure-main); + color: var(--ds-code-comment); + font-style: italic; } -.hljs-template-variable { - color: var(--ds-failure-main); +/* Prompts, preprocessor lines, annotations, markup brackets, and list bullets. */ +.hljs-meta, +.hljs-tag, +.hljs-bullet { + color: var(--ds-code-meta); } -.hljs-tag { - color: var(--ds-failure-main); +.hljs-keyword, +.hljs-selector-tag, +.hljs-name, +.hljs-doctag, +.hljs-meta-keyword, +.hljs-meta .hljs-keyword, +.hljs-variable.language_ { + color: var(--ds-code-keyword); } -.hljs-name { - color: var(--ds-failure-main); +.hljs-type, +.hljs-built_in, +.hljs-builtin-name, +.hljs-title.class_ { + color: var(--ds-code-type); } +/* Names being defined or called: functions, classes, headings. */ +.hljs-title, +.hljs-section, .hljs-selector-id { - color: var(--ds-failure-main); -} - -.hljs-selector-class { - color: var(--ds-cyan-main); -} - -.hljs-regexp { - color: var(--ds-cyan-main); -} - -.hljs-deletion { - color: var(--ds-failure-main); -} - -.hljs-number { - color: var(--ds-orange-main); -} - -.hljs-built_in { - color: var(--ds-teal-main); -} - -.hljs-builtin-name { - color: var(--ds-orange-main); + color: var(--ds-code-title); } -.hljs-literal { - color: var(--ds-orange-main); -} - -.hljs-type { - color: var(--ds-orange-main); -} - -.hljs-params { - color: var(--ds-orange-main); -} - -.hljs-meta { - color: var(--ds-orange-main); +.hljs-section { + font-weight: 600; } +/* Keys and setting names: JSON and YAML keys, XML attributes, CSS properties, options. */ +.hljs-attr, +.hljs-attribute, +.hljs-property, +.hljs-symbol, +.hljs-selector-attr, +.hljs-selector-class, +.hljs-selector-pseudo, .hljs-link { - color: var(--ds-orange-main); + color: var(--ds-code-attr); } -.hljs-attribute { - color: var(--ds-orange-main); -} - -.hljs-string { - color: var(--ds-orange-main); -} - -.hljs-symbol { - color: var(--ds-success-main); -} - -.hljs-bullet { - color: var(--ds-success-main); +.hljs-link { + text-decoration: underline; } +.hljs-string, +.hljs-regexp, +.hljs-meta-string, +.hljs-meta .hljs-string, .hljs-addition { - color: var(--ds-success-main); + color: var(--ds-code-string); } -.hljs-title { - color: var(--ds-cyan-main); +.hljs-number, +.hljs-literal, +.hljs-char.escape_, +.hljs-variable.constant_ { + color: var(--ds-code-number); } -.hljs-section { - color: var(--ds-cyan-main); +/* Values supplied by the reader or the environment: variables, bind markers, and + placeholders such as , which are also italic, like variables in prose. */ +.hljs-variable, +.hljs-template-variable, +.hljs-template-tag { + color: var(--ds-code-variable); } -.hljs-keyword { - color: var(--ds-primary-main); +.hljs-template-variable { + font-style: italic; } -.hljs-selector-tag { - color: var(--ds-primary-main); +.hljs-deletion { + color: var(--ds-code-deletion); } .hljs-emphasis { @@ -111,5 +96,5 @@ } .hljs-strong { - font-weight: 500; + font-weight: 600; } diff --git a/src/css/vars/dark.css b/src/css/vars/dark.css index 1abf405b..f8091d5f 100644 --- a/src/css/vars/dark.css +++ b/src/css/vars/dark.css @@ -98,6 +98,19 @@ --ds-warning-solid-bg: theme(colors.amber.500); --ds-warning-solid-color: theme(colors.black); --ds-warning-solid-hover-bg: theme(colors.amber.400); + + /* Code syntax highlighting (see highlight.css). Each color has at least 4.5:1 + contrast (WCAG AA) on --ds-background-level1, the code block background. */ + --ds-code-comment: theme(colors.zinc.400); + --ds-code-meta: theme(colors.zinc.400); + --ds-code-keyword: theme(colors.purple.400); + --ds-code-type: theme(colors.lime.400); + --ds-code-title: theme(colors.pink.400); + --ds-code-attr: theme(colors.sky.400); + --ds-code-string: theme(colors.emerald.400); + --ds-code-number: theme(colors.orange.400); + --ds-code-variable: theme(colors.amber.400); + --ds-code-deletion: theme(colors.red.400); } @mixin dark-inverse { diff --git a/src/css/vars/light.css b/src/css/vars/light.css index b1175326..942e046d 100644 --- a/src/css/vars/light.css +++ b/src/css/vars/light.css @@ -98,6 +98,19 @@ --ds-warning-solid-bg: theme(colors.amber.600); --ds-warning-solid-color: theme(colors.white); --ds-warning-solid-hover-bg: theme(colors.amber.700); + + /* Code syntax highlighting (see highlight.css). Each color has at least 4.5:1 + contrast (WCAG AA) on --ds-background-level1, the code block background. */ + --ds-code-comment: theme(colors.zinc.500); + --ds-code-meta: theme(colors.zinc.500); + --ds-code-keyword: theme(colors.purple.700); + --ds-code-type: theme(colors.lime.700); + --ds-code-title: theme(colors.pink.700); + --ds-code-attr: theme(colors.sky.700); + --ds-code-string: theme(colors.emerald.700); + --ds-code-number: theme(colors.orange.700); + --ds-code-variable: theme(colors.amber.700); + --ds-code-deletion: theme(colors.red.700); } @mixin light-inverse { diff --git a/src/js/vendor/floatingui.bundle.js b/src/js/vendor/floatingui.bundle.js index 96b5364e..b2acf9b8 100644 --- a/src/js/vendor/floatingui.bundle.js +++ b/src/js/vendor/floatingui.bundle.js @@ -1,3 +1,6 @@ +/*! Floating UI | MIT | Copyright (c) 2021-present Floating UI contributors | https://github.com/floating-ui/floating-ui + * @floating-ui/dom 1.6.12, @floating-ui/core 1.6.8, @floating-ui/utils 0.2.8 + */ /** * Dropdown Example * diff --git a/src/js/vendor/highlight.bundle.js b/src/js/vendor/highlight.bundle.js index eea40cdf..719fa9f7 100644 --- a/src/js/vendor/highlight.bundle.js +++ b/src/js/vendor/highlight.bundle.js @@ -1,10 +1,15 @@ +/*! Syntax highlighting in this bundle: + * highlight.js 9.18.3 | BSD-3-Clause | Copyright (c) 2006, Ivan Sagalaev | https://github.com/highlightjs/highlight.js + * GraphQL grammar ported from highlight.js 11.12.0 | BSD-3-Clause | Copyright (c) 2006, Ivan Sagalaev + * highlightjs-curl 1.3.0 | Apache-2.0 | John Foster | https://github.com/highlightjs/highlightjs-curl + * highlightjs-cql 1.0.0 | Apache-2.0 | https://github.com/eric-schneider/highlightjs-cql + */ ;(function () { 'use strict' var hljs = require('highlight.js/lib/highlight') var hljsCurl = require('highlightjs-curl') var sql = require('highlight.js/lib/languages/sql') - var ini = require('highlight.js/lib/languages/ini') hljs.registerLanguage('asciidoc', require('highlight.js/lib/languages/asciidoc')) hljs.registerLanguage('bash', require('highlight.js/lib/languages/bash')) @@ -17,9 +22,10 @@ hljs.registerLanguage('dockerfile', require('highlight.js/lib/languages/dockerfile')) hljs.registerLanguage('elixir', require('highlight.js/lib/languages/elixir')) hljs.registerLanguage('go', require('highlight.js/lib/languages/go')) + hljs.registerLanguage('graphql', require('./languages/graphql.js')) hljs.registerLanguage('groovy', require('highlight.js/lib/languages/groovy')) hljs.registerLanguage('haskell', require('highlight.js/lib/languages/haskell')) - hljs.registerLanguage('ini', ini) + hljs.registerLanguage('ini', require('highlight.js/lib/languages/ini')) hljs.registerLanguage('java', require('highlight.js/lib/languages/java')) hljs.registerLanguage('javascript', require('highlight.js/lib/languages/javascript')) hljs.registerLanguage('json', require('highlight.js/lib/languages/json')) @@ -31,7 +37,9 @@ hljs.registerLanguage('objectivec', require('highlight.js/lib/languages/objectivec')) hljs.registerLanguage('perl', require('highlight.js/lib/languages/perl')) hljs.registerLanguage('php', require('highlight.js/lib/languages/php')) + hljs.registerLanguage('powershell', require('highlight.js/lib/languages/powershell')) hljs.registerLanguage('properties', require('highlight.js/lib/languages/properties')) + hljs.registerLanguage('protobuf', require('highlight.js/lib/languages/protobuf')) hljs.registerLanguage('puppet', require('highlight.js/lib/languages/puppet')) hljs.registerLanguage('python', require('highlight.js/lib/languages/python')) hljs.registerLanguage('ruby', require('highlight.js/lib/languages/ruby')) @@ -39,10 +47,8 @@ hljs.registerLanguage('scala', require('highlight.js/lib/languages/scala')) hljs.registerLanguage('shell', require('highlight.js/lib/languages/shell')) hljs.registerLanguage('sql', sql) - // Use SQL highlighter for CQL - hljs.registerLanguage('cql', sql) + hljs.registerLanguage('cql', require('./languages/cql.js')) hljs.registerLanguage('swift', require('highlight.js/lib/languages/swift')) - hljs.registerLanguage('toml', ini) hljs.registerLanguage('typescript', require('highlight.js/lib/languages/typescript')) hljs.registerLanguage('xml', require('highlight.js/lib/languages/xml')) hljs.registerLanguage('yaml', require('highlight.js/lib/languages/yaml')) diff --git a/src/js/vendor/languages/README.md b/src/js/vendor/languages/README.md new file mode 100644 index 00000000..99d19c6a --- /dev/null +++ b/src/js/vendor/languages/README.md @@ -0,0 +1,16 @@ +# Syntax highlighting grammars + +`highlight.bundle.js` registers these grammars with highlight.js 9.18.3, alongside the ones highlight.js ships. +They are maintained outside this repository, so lint and format skip this folder (see `glob.js` in `gulpfile.js`). + +| File | Language | Source | License | +|---|---|---|---| +| `cql.js` | CQL and cqlsh (`cql`, `cqlsh`) | `dist/cql.cjs` of [highlightjs-cql](https://github.com/eric-schneider/highlightjs-cql) 1.0.0 | Apache-2.0 | +| `graphql.js` | GraphQL (`graphql`, `gql`) | Ported from highlight.js 11.12.0 `src/languages/graphql.js`, which highlight.js 9 lacks | BSD-3-Clause | + +The license notice at the top of `highlight.bundle.js` survives minification, so it appears in the published `js/vendor/highlight.bundle.js`. + +## Updating + +- **CQL.** Copy `dist/cql.cjs` from a highlightjs-cql release to `cql.js`, and update its version in the notice at the top of `highlight.bundle.js`. +- **GraphQL.** If you move to highlight.js 11, remove `graphql.js` and register `highlight.js/lib/languages/graphql` instead. To refresh the port from a newer highlight.js release, apply the changes its header lists. diff --git a/src/js/vendor/languages/cql.js b/src/js/vendor/languages/cql.js new file mode 100644 index 00000000..cb23ec78 --- /dev/null +++ b/src/js/vendor/languages/cql.js @@ -0,0 +1,717 @@ +/*! highlightjs-cql 1.0.0 | CQL for highlight.js 9.18, 10.7, and 11.x | Apache-2.0 | https://github.com/eric-schneider/highlightjs-cql */ +'use strict'; + +// GENERATED by tools/generate-vocabulary.mjs from data/*.json. Do not edit by hand. +// Sources: Apache Cassandra 1.2, 2.0, 2.1, 2.2, 3.0, 3.11, 4.0, 4.1, 5.0, 6.0, trunk; DataStax fork +// (HCD 1.1.6, 1.2.7, 2.0.7); DataStax Enterprise 5.1.51, 6.8.65, 6.9.25. +var VOCABULARY = { + keywords: 'access active add aggregate aggregates all allow alter and ann any apply as asc authentication authorize backup backups batch begin between bm25 by call called calls cancel cast check cidrs clean cluster clustering column columnfamilies columnfamily columns comment comments commit compact config configuration configurations contains count counter create custom datacenters default delete desc describe deterministic distinct drop dropped edge end entries execute exists field filtering finalfunc for force from full function functions generated geo_distance grant group hashed identity if in index indexes indices initcond input insert internal internals into is json kerberos key keys keyspace keyspaces label labels language ldap let like limit list login masked materialized maxwritetime mbean mbeans method modify monotonic nologin norecursive nosuperuser not object of offset on only options or order partition password per permission permissions primary profiles proxy.execute proxy.login rebuild record reload remote rename replace restore restrict returns revoke role roles rows run schema scheme schemes search security select select_masked set sfunc static stdin stdout storage store stores stype submission superuser superusers table tables then timestamp to token transaction trigger truncate ttl type types unlogged unmask unrestrict unset update use user users using values verify vertex view where with without workpool writetime', + reserved: [ + 'add', + 'allow', + 'alter', + 'and', + 'apply', + 'asc', + 'authorize', + 'batch', + 'begin', + 'by', + 'columnfamily', + 'create', + 'delete', + 'desc', + 'describe', + 'drop', + 'entries', + 'execute', + 'from', + 'full', + 'grant', + 'if', + 'in', + 'index', + 'infinity', + 'insert', + 'into', + 'is', + 'keyspace', + 'limit', + 'materialized', + 'modify', + 'nan', + 'norecursive', + 'not', + 'null', + 'of', + 'on', + 'or', + 'order', + 'primary', + 'rename', + 'revoke', + 'schema', + 'select', + 'set', + 'table', + 'to', + 'token', + 'truncate', + 'unlogged', + 'update', + 'use', + 'using', + 'view', + 'where', + 'with' + ], + types: [ + 'ascii', + 'bigint', + 'blob', + 'boolean', + 'counter', + 'date', + 'decimal', + 'double', + 'duration', + 'float', + 'inet', + 'int', + 'smallint', + 'text', + 'time', + 'timestamp', + 'timeuuid', + 'tinyint', + 'uuid', + 'varchar', + 'varint' + ], + typeConstructors: [ + 'frozen', + 'list', + 'map', + 'set', + 'tuple', + 'vector' + ], + literals: 'false infinity nan null true', + functions: [ + 'abs', + 'ascii_as_blob', + 'asciiasblob', + 'avg', + 'bigint_as_blob', + 'bigintasblob', + 'blob_as_ascii', + 'blob_as_bigint', + 'blob_as_boolean', + 'blob_as_counter', + 'blob_as_date', + 'blob_as_decimal', + 'blob_as_double', + 'blob_as_duration', + 'blob_as_empty', + 'blob_as_float', + 'blob_as_inet', + 'blob_as_int', + 'blob_as_smallint', + 'blob_as_text', + 'blob_as_time', + 'blob_as_timestamp', + 'blob_as_timeuuid', + 'blob_as_tinyint', + 'blob_as_uuid', + 'blob_as_varchar', + 'blob_as_varint', + 'blobasascii', + 'blobasbigint', + 'blobasboolean', + 'blobascounter', + 'blobasdate', + 'blobasdecimal', + 'blobasdouble', + 'blobasduration', + 'blobasempty', + 'blobasfloat', + 'blobasinet', + 'blobasint', + 'blobassmallint', + 'blobastext', + 'blobastime', + 'blobastimestamp', + 'blobastimeuuid', + 'blobastinyint', + 'blobasuuid', + 'blobasvarchar', + 'blobasvarint', + 'boolean_as_blob', + 'booleanasblob', + 'cast', + 'cast_as_ascii', + 'cast_as_bigint', + 'cast_as_date', + 'cast_as_decimal', + 'cast_as_double', + 'cast_as_float', + 'cast_as_int', + 'cast_as_smallint', + 'cast_as_text', + 'cast_as_timestamp', + 'cast_as_tinyint', + 'cast_as_varint', + 'castasascii', + 'castasbigint', + 'castasdate', + 'castasdecimal', + 'castasdouble', + 'castasfloat', + 'castasint', + 'castassmallint', + 'castastext', + 'castastimestamp', + 'castastinyint', + 'castasvarint', + 'collection_avg', + 'collection_count', + 'collection_max', + 'collection_min', + 'collection_sum', + 'count', + 'count_rows', + 'counter_as_blob', + 'counterasblob', + 'countrows', + 'current_date', + 'current_time', + 'current_timestamp', + 'current_timeuuid', + 'currentdate', + 'currenttime', + 'currenttimestamp', + 'currenttimeuuid', + 'date_as_blob', + 'dateasblob', + 'dateof', + 'decimal_as_blob', + 'decimalasblob', + 'double_as_blob', + 'doubleasblob', + 'duration_as_blob', + 'durationasblob', + 'empty_as_blob', + 'emptyasblob', + 'exp', + 'float_as_blob', + 'floatasblob', + 'floor', + 'format_bytes', + 'format_time', + 'from_json', + 'fromjson', + 'geo_distance', + 'inet_as_blob', + 'inetasblob', + 'int_as_blob', + 'intasblob', + 'json', + 'length', + 'log', + 'log10', + 'map_keys', + 'map_values', + 'mask_default', + 'mask_hash', + 'mask_inner', + 'mask_null', + 'mask_outer', + 'mask_replace', + 'max', + 'max_timeuuid', + 'maxtimeuuid', + 'maxwritetime', + 'min', + 'min_timeuuid', + 'mintimeuuid', + 'normalize_l2', + 'now', + 'octet_length', + 'random_float_vector', + 'regexp', + 'round', + 'sai_analyze', + 'similarity_cosine', + 'similarity_dot_product', + 'similarity_euclidean', + 'smallint_as_blob', + 'smallintasblob', + 'sum', + 'text_as_blob', + 'textasblob', + 'time_as_blob', + 'timeasblob', + 'timestamp_as_blob', + 'timestampasblob', + 'timeuuid_as_blob', + 'timeuuidasblob', + 'tinyint_as_blob', + 'tinyintasblob', + 'to_date', + 'to_json', + 'to_timestamp', + 'to_unix_timestamp', + 'todate', + 'tojson', + 'token', + 'totimestamp', + 'tounixtimestamp', + 'transformation_kind', + 'ttl', + 'unixtimestampof', + 'uuid', + 'uuid_as_blob', + 'uuidasblob', + 'varchar_as_blob', + 'varcharasblob', + 'varint_as_blob', + 'varintasblob', + 'writetime' + ], + consistencyLevels: [ + 'all', + 'any', + 'each_quorum', + 'local_one', + 'local_quorum', + 'local_serial', + 'node_local', + 'one', + 'quorum', + 'serial', + 'three', + 'two' + ], + cqlshLineCommands: [ + 'capture', + 'clear', + 'cls', + 'consistency', + 'debug', + 'elapsed', + 'exit', + 'expand', + 'help', + 'history', + 'login', + 'paging', + 'quit', + 'serial', + 'show', + 'source', + 'timing', + 'tracing' + ], + cqlshArguments: 'consistency host off on replicas session version', + roleOptions: [ + 'access', + 'generated', + 'hashed', + 'login', + 'password', + 'superuser' + ], + unreservedPermissions: [ + 'select_masked', + 'unmask' + ]}; + +/* +Language: CQL +Description: Cassandra Query Language and cqlsh commands for Apache Cassandra (1.2 through 6.0), DataStax Enterprise, Hyper-Converged Database (HCD), and Astra DB. +Author: Eric Schneider +Contributors: Therapon Skoteiniotis (original beta definition) +Website: https://cassandra.apache.org/doc/latest/cassandra/developing/cql/ +Category: database +*/ + + +/** @type LanguageFn */ +function cql(hljs) { + var V = VOCABULARY; + + // --- Version adapter --------------------------------------------------------------- + // highlight.js 11 renders sub-scopes such as title.function.invoke as + // "hljs-title function_ invoke__". Versions 9 and 10 would emit the dotted name as a + // single class no theme styles, so they get the parent scope ("hljs-title") instead. + // highlight.js 9 has no versionString, so a missing value means 9. + var MAJOR = parseInt(String(hljs.versionString || '9').split('.')[0], 10) || 9; + var MODERN = MAJOR >= 11; + function scope(name) { + return MODERN ? name : name.split('.')[0]; + } + + // A keyword is a word, or a dotted chain of words. Treating "ks.table" as one lexeme + // keeps qualified names such as system_schema.tables from highlighting "tables", and + // lets DataStax Enterprise permissions such as PROXY.LOGIN be keywords. + var LEXEME = /[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*/; + + // Version 9 and 10 read the keyword pattern from mode.lexemes; 11 reads keywords.$pattern + // and ignores lexemes. Every mode that has keywords goes through this helper. + function withKeywords(mode, keywords) { + var copy = {}; + for (var k in keywords) { + if (Object.prototype.hasOwnProperty.call(keywords, k)) copy[k] = keywords[k]; + } + if (MODERN) copy.$pattern = LEXEME; + else mode.lexemes = LEXEME; + mode.keywords = copy; + return mode; + } + + function escapeRegex(s) { + return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); + } + function either(words) { + return '(?:' + words.map(escapeRegex).join('|') + ')'; + } + + var IDENT = '[A-Za-z][A-Za-z0-9_]*'; + var TYPES = either(V.types); + var CONSTRUCTORS = either(V.typeConstructors); + var TYPE_START = '(?:' + CONSTRUCTORS + '\\s*<|' + TYPES + '\\b)'; + + // Words that can never be the name in "name type" or "name = value": Cassandra's + // reserved words, plus words that are keywords in exactly those positions. + var DSE_STATEMENT_WORDS = ['backup', 'backups', 'restore', 'store', 'stores', 'search', + 'workpool', 'submission', 'remote', 'object', 'call', 'calls', 'scheme', 'schemes', + 'configuration', 'configurations', 'profiles', 'columns', 'cancel', 'clean', 'verify', + 'run', 'reload', 'rebuild', 'commit', 'restrict', 'unrestrict', 'rows', 'indices', 'config']; + var NOT_A_NAME_WORDS = V.reserved.concat(V.literals.split(' '), V.unreservedPermissions, + DSE_STATEMENT_WORDS, ['as', 'returns', 'stype', 'static', 'record', 'access', 'default', 'unset', + 'keyspaces', 'tables', 'functions', 'aggregates', 'mbeans', 'roles']); + var NOT_A_NAME = '(?!' + either(NOT_A_NAME_WORDS) + '\\b)'; + // Inside WITH clauses, role options (PASSWORD = '...', LOGIN = true) are keywords. NULL + // stays available as a name there: cqlsh COPY has an option called NULL (NULL = '-'). + var NOT_AN_OPTION_NAME = '(?!' + either(NOT_A_NAME_WORDS.filter(function (w) { + return w !== 'null'; + }).concat(V.roleOptions)) + '\\b)'; + + var KEYWORDS = { keyword: V.keywords, literal: V.literals }; + + // --- Literals ------------------------------------------------------------------------ + var DURATION_UNIT = '(?:y|mo|w|d|h|ms|us|\u00b5s|ns|m|s)'; + var NUMBER = { + className: 'number', + relevance: 0, + variants: [ + // UUID before integers: 123e4567-... must not split into 123e4567 and fragments. + { begin: /\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/ }, + // Duration: 1h30m, 12mo, -2d, 3us (Lexer.g DURATION, DURATION_UNIT). + { begin: '-?\\b\\d+' + DURATION_UNIT + '(?:\\d+' + DURATION_UNIT + ')*\\b' }, + // Duration, ISO 8601: P0001-02-03T04:05:06, P1Y2M3DT4H, PT15M, P2W. + { begin: /-?\bP\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\b/ }, + { begin: /-?\bP(?:\d+W|(?=\d|T\d)(?:\d+Y)?(?:\d+M)?(?:\d+D)?(?:T(?=\d)(?:\d+H)?(?:\d+M)?(?:\d+S)?)?)\b/ }, + // Blob: 0x followed by zero or more hex digits (0x alone is an empty blob). + { begin: /\b0x[0-9a-f]*\b/ }, + // Integer and float, with the lexer's optional leading minus. "1..3" is a range. + { begin: /-?\b\d+(?:\.(?!\.)\d*)?(?:e[+-]?\d+)?\b/ } + ] + }; + var SPECIAL_FLOAT = { className: 'literal', begin: /-?\b(?:NaN|Infinity)\b/, relevance: 0 }; + + // Synopsis placeholders such as or , as used in reference + // documentation. Collection types (set) are matched before this rule. + var PLACEHOLDER = { + className: 'template-variable', + begin: /<[A-Za-z_][A-Za-z0-9_.:\/@-]*(?: [A-Za-z0-9_.:\/@-]+)*>/, + relevance: 0 + }; + + var STRING = { + className: 'string', + begin: "'", + end: "'", + contains: [{ begin: "''" }, PLACEHOLDER], + relevance: 0 + }; + // $$pg-style string$$, also used for function bodies. + var DOLLAR_STRING = { className: 'string', begin: /\$\$/, end: /\$\$/, relevance: 0 }; + // "Quoted names" keep their exact case and are never keywords. + var QUOTED_NAME = { begin: '"', end: '"', contains: [{ begin: '""' }], relevance: 0 }; + + var BIND_MARKER = { + className: 'variable', + relevance: 0, + variants: [ + { begin: /\?/ }, + // :name, but not a literal or function call after a UDT field name ({weight:null}). + { begin: /:(?!(?:true|false|null|nan|infinity)\b)[A-Za-z_][A-Za-z0-9_]*\b(?!\s*\()/ }, + { begin: /:"(?:[^"]|"")+"/ } + ] + }; + + var COMMENTS = [ + hljs.COMMENT('--', '$', { relevance: 0 }), + hljs.COMMENT('//', '$', { relevance: 0 }), + hljs.COMMENT('/\\*', '\\*/', { relevance: 0 }) + ]; + + // --- cqlsh ------------------------------------------------------------------------- + var PROMPT = { className: scope('meta.prompt'), begin: /cqlsh(?::[A-Za-z0-9_"]+)?>/, relevance: 0 }; + // Where a cqlsh command can start: a line start, after a semicolon, or after a prompt. + var STATEMENT_START = '(?:^[ \\t]*|;[ \\t]*|cqlsh(?::[A-Za-z0-9_"]+)?>[ \\t]*)'; + var LEVEL = { + className: 'literal', + begin: '\\b' + either(V.consistencyLevels) + '\\b(?!\\s+CONSISTENCY\\b)', + relevance: 0 + }; + // Shell commands such as CONSISTENCY QUORUM or TRACING ON, recognized only at the start + // of a statement so that a column called "source" or "history" stays a name. + var PROMPT_SOURCE = 'cqlsh(?::[A-Za-z0-9_"]+)?>'; + var COMMAND_WORD = either(V.cqlshLineCommands) + '\\b'; + var CQLSH_COMMAND = withKeywords({ + variants: [ + // At a line start or after a semicolon the matched text is consumed; highlight.js + // colors it with this mode's keywords. It must not be re-scanned: a mode that begins + // at a semicolon and ends on that same semicolon would restart there forever. + { begin: '^[ \\t]*' + COMMAND_WORD }, + { begin: ';[ \\t]*' + COMMAND_WORD }, + // After a prompt the text is re-scanned, so that the prompt gets its own scope. + { begin: PROMPT_SOURCE + '[ \\t]*' + COMMAND_WORD, returnBegin: true } + ], + end: /;|$/, + returnEnd: true, + relevance: 0, + contains: [PROMPT, STRING, PLACEHOLDER, LEVEL, NUMBER, { className: 'literal', begin: /\b(?:ON|OFF)\b/ }] + }, { keyword: V.cqlshLineCommands.join(' ') + ' ' + V.cqlshArguments }); + // COPY is a cqlsh command only at the start of a statement; the rest of the statement is + // CQL-like (TO 'file' WITH HEADER = true). The mode ends on the word COPY itself, which + // highlight.js colors with the mode's keywords. (A mode without an explicit end would end + // at the first position after a nested prompt, before reaching COPY.) + var COPY_COMMAND = withKeywords({ + begin: STATEMENT_START + 'COPY\\b', + returnBegin: true, + end: /\bCOPY\b/, + relevance: 0, + contains: [PROMPT] + }, { keyword: 'copy' }); + + // cqlsh query output pasted into examples: a separator row of dashes (with + between + // columns), the rows below it, and the "(3 rows)" footer stay plain text. + var RESULT_TABLE = { + relevance: 0, + // Each pattern has exactly one way to match a line ([^\n|]* stops at the first |, + // [ \t]* at the first visible character), so a long line cannot cause backtracking. + variants: [ + { begin: /^[^\n|]*\|[^\n]*(?=\n[ \t]*-+(?:\+-+)+[ \t]*$)/ }, + { begin: /^[ \t]*\S[^\n]*(?=\n[ \t]*-{3,}[ \t]*$)/ }, + { begin: /^[ \t]*-+(?:\+-+)+[ \t]*$/ } + ], + end: /^[ \t]*$|^\(\d+ rows?\)/ + }; + var ROW_COUNT = { begin: /^\(\d+ rows?\)[ \t]*$/, relevance: 0 }; + + // --- Types --------------------------------------------------------------------------- + // Type names are colored only where a type can appear, because every native type name + // (text, date, time, ...) is also a legal column name. + // Inside <...>, nested collection types come first, so frozen
in + // map> is not mistaken for an
placeholder. + var NESTED_GENERIC = { begin: '\\b' + CONSTRUCTORS + '\\s*<', end: />/, relevance: 0 }; + var ANGLES = { begin: //, relevance: 0 }; + var GENERIC_CONTENTS = [NESTED_GENERIC, PLACEHOLDER, NUMBER, QUOTED_NAME, ANGLES]; + NESTED_GENERIC.contains = GENERIC_CONTENTS; + ANGLES.contains = GENERIC_CONTENTS; + function genericType(endsParent) { + return { + className: 'type', + begin: '\\b' + CONSTRUCTORS + '\\s*<', + end: '>', + endsParent: endsParent, + relevance: 0, + contains: GENERIC_CONTENTS + }; + } + function typeWord(endsParent) { + return { className: 'type', begin: '\\b' + TYPES + '\\b', endsParent: endsParent, relevance: 0 }; + } + var TYPE_CONTENTS = [genericType(true), typeWord(true)]; + + // name type: a column, UDT field, or parameter definition (key text, date date). + var TYPED_NAME = { + relevance: 0, + variants: [ + { begin: '\\b' + NOT_A_NAME + IDENT + '(?=\\s+' + TYPE_START + ')' }, + { begin: '"(?:[^"]|"")+"(?=\\s+' + TYPE_START + ')' } + ], + end: /[,;()]/, + returnEnd: true, + contains: TYPE_CONTENTS + }; + // name udt_name: since Cassandra 3.6 a user-defined type column need not be frozen + // (address address_type). Two plain words are a definition only when a definition's + // ending follows: a comma, ")", STATIC, PRIMARY KEY, MASKED WITH, or CHECK. SELECT JSON + // and SELECT DISTINCT are followed by names, never by a type. + var UDT_TYPED_NAME = { + begin: '\\b' + NOT_A_NAME + '(?!(?:JSON|DISTINCT)\\b)' + IDENT + '(?=\\s+(?!' + either(V.keywords.split(' ').concat(V.literals.split(' '))) + + '\\b)' + IDENT + '\\s*(?:[,)]|\\b(?:STATIC|PRIMARY|MASKED|CHECK)\\b))', + end: /[,;()]/, + returnEnd: true, + relevance: 0, + contains: [{ className: 'type', begin: '\\b' + IDENT, endsParent: true, relevance: 0 }] + }; + // RETURNS int, STYPE map, RETURNS address (any name here is a type, so user- + // defined types are colored too). RETURNS NULL ON NULL INPUT is not a type. + var TYPE_AFTER_KEYWORD = withKeywords({ + begin: /\b(?:RETURNS|STYPE)\s+(?!NULL\b)(?=[A-Za-z"])/, + returnBegin: true, + end: /[,;()]/, + returnEnd: true, + relevance: 0, + contains: TYPE_CONTENTS.concat([{ + className: 'type', + begin: '(?:\\b(?!(?:RETURNS|STYPE)\\b)|(?="))(?:' + IDENT + '\\.)?(?:' + IDENT + '|"(?:[^"]|"")+")', + endsParent: true, + relevance: 0 + }]) + }, { keyword: 'returns stype' }); + // CAST(value AS int) + var CAST_TYPE = withKeywords({ + begin: '\\bAS\\s+(?=' + TYPES + '\\s*\\))', + returnBegin: true, + end: /\)/, + returnEnd: true, + relevance: 0, + contains: TYPE_CONTENTS + }, { keyword: 'as' }); + + // --- Functions ----------------------------------------------------------------------- + // Calls to native functions (now(), writetime(col), similarity_cosine(v, ?), ...). + // Unknown names before "(" are left plain: they are usually tables (INSERT INTO t (...)). + var FUNCTION_CALL = { + className: scope('title.function.invoke'), + begin: '\\b' + either(V.functions) + '(?=\\s*\\()', + relevance: 0 + }; + // CREATE FUNCTION ks.name (a int, b text), DROP AGGREGATE name (int), ON FUNCTION f(int) + var SIGNATURE = { + begin: /\(/, + end: /\)/, + endsParent: true, + relevance: 0, + contains: [TYPED_NAME, genericType(false), typeWord(false), QUOTED_NAME, PLACEHOLDER].concat(COMMENTS) + }; + var FUNCTION_DECLARATION = withKeywords({ + begin: /\b(?:FUNCTION|AGGREGATE)\s+(?=(?:IF\s+(?:NOT\s+)?EXISTS\s+)?["A-Za-z<])/, + returnBegin: true, + end: /;|$/, + returnEnd: true, + relevance: 0, + contains: [ + PLACEHOLDER, + { + className: scope('title.function'), + begin: '\\b(?!(?:FUNCTION|AGGREGATE|IF|NOT|EXISTS)\\b)(?:' + IDENT + '\\.)?(?:' + IDENT + '|"(?:[^"]|"")+")', + relevance: 0 + }, + SIGNATURE + ] + }, KEYWORDS); + + // --- Names in positions where keywords cannot appear ----------------------------------- + // Many CQL keywords are unreserved: key, type, status, comment, and every native type + // can name a column. A word right before a comparison, a list separator, FROM, AS, ASC, + // DESC, or a DataStax Enterprise search-index option block ({ ... }) is a name, so it is + // not colored as a keyword (WHERE key = 1; SELECT type, date; COLUMNS comment { ... }). + var RELATION = '(?=\\s*(?:!=|<=|>=|=|<(?![A-Za-z_])|>|:(?![A-Za-z_":])|\\b(?:IN|CONTAINS|LIKE|IS|BETWEEN|NOT)\\b))'; + var NAME_BEFORE_RELATION = { begin: '\\b' + NOT_A_NAME + IDENT + RELATION, relevance: 0 }; + var NAME_BEFORE_RELATION_IN_WITH = { begin: '\\b' + NOT_AN_OPTION_NAME + IDENT + RELATION, relevance: 0 }; + var NAME_BEFORE_DELIMITER = { + relevance: 0, + variants: [ + { begin: '\\b' + NOT_A_NAME + IDENT + '(?=\\s*[,)]|\\s+(?:FROM|ASC|DESC|AS)\\b)' }, + // A name before { is a DataStax Enterprise search-index column; ACCESS TO + // DATACENTERS {...} and CONFIG {...} are keywords. + { + begin: '\\b(?!' + either(NOT_A_NAME_WORDS.concat(['datacenters', 'cidrs', 'config', 'options', + 'contains', 'key'])) + + '\\b)' + IDENT + '(?=\\s*\\{)' + } + ] + }; + // The object named right after TABLE, FROM, INTO, ON, and similar words is a name even + // when the word is a keyword elsewhere: CREATE TABLE users, INSERT INTO user, KEYSPACE store. + // Each keyword lists the words that may follow it as syntax instead (FROM STDIN, ON ROLE). + var NAME_PART = '(?:' + IDENT + '|"(?:[^"]|"")+")'; + var NOT_OBJECT_BASE = V.reserved.concat(V.literals.split(' '), ['if', 'not', 'exists', 'all']); + function objectAfter(keywords, notObjects) { + return { + begin: '\\b' + either(keywords) + '\\s+(?:IF\\s+(?:NOT\\s+)?EXISTS\\s+)?(?!' + + either(NOT_OBJECT_BASE.concat(notObjects)) + '\\b)(?=["A-Za-z])' + }; + } + // DataStax Enterprise objects named by a keyword: FROM BACKUP b, ON STORE s, ON REMOTE OBJECT. + var DSE_OBJECT_WORDS = ['backup', 'backups', 'store', 'stores', 'configuration', 'configurations', + 'remote', 'any', 'workpool', 'submission', 'search', 'internal', 'ldap', 'kerberos', 'scheme', 'schemes']; + var OBJECT_NAME = withKeywords({ + variants: [ + objectAfter(['from'], ['stdin', 'cidrs'].concat(DSE_OBJECT_WORDS)), + objectAfter(['index'], ['schema', 'config']), + objectAfter(['truncate'], ['table']), + objectAfter(['on'], ['table', 'keyspace', 'keyspaces', 'tables', 'index', 'type', 'view', + 'materialized', 'column', 'function', 'functions', 'aggregate', 'aggregates', 'role', 'roles', + 'mbean', 'mbeans', 'resource', 'user', 'trigger'].concat(DSE_OBJECT_WORDS)), + objectAfter(['table', 'into', 'update', 'keyspace', 'use', 'view', 'type', 'user'], []) + ], + end: /[;(]|$/, + returnEnd: true, + relevance: 0, + contains: [{ begin: NAME_PART + '(?:\\.' + NAME_PART + ')?', endsParent: true, relevance: 0 }] + }, KEYWORDS); + // DataStax Enterprise documents DESCRIBE PENDING SEARCH INDEX; PENDING is a keyword only in + // that phrase. + var PENDING = { className: 'keyword', begin: /\bPENDING(?=\s+SEARCH\s+INDEX\b)/, relevance: 0 }; + // KEY is unreserved (a column may be called key), but PRIMARY KEY is always syntax. + var PRIMARY_KEY = { className: 'keyword', begin: /\bPRIMARY\s+KEY\b/, relevance: 0 }; + var ELLIPSIS = { begin: /\.\.\./, relevance: 0 }; + var OPERATOR = { className: 'operator', begin: /\+=|-=|!=|<=|>=|\.\.|[-+*\/%=<>]/, relevance: 0 }; + + var COMMON = [ + STRING, DOLLAR_STRING, + TYPED_NAME, UDT_TYPED_NAME, QUOTED_NAME, + PLACEHOLDER, BIND_MARKER, SPECIAL_FLOAT, NUMBER, + FUNCTION_DECLARATION, TYPE_AFTER_KEYWORD, CAST_TYPE, genericType(false), + FUNCTION_CALL, OBJECT_NAME, PENDING, PRIMARY_KEY, NAME_BEFORE_DELIMITER, + ELLIPSIS, OPERATOR + ]; + + // WITH option = value AND option = value: table, keyspace, index, and COPY options are + // setting names (the attr scope), except role options such as PASSWORD and LOGIN. + var OPTION_NAME = { + className: 'attr', + begin: '\\b' + NOT_AN_OPTION_NAME + IDENT + '(?=\\s*=(?!=))', + relevance: 0 + }; + var STATEMENT_KEYWORD = '(?:SELECT|INSERT|UPDATE|DELETE|CREATE|ALTER|DROP|BEGIN|APPLY|GRANT|' + + 'REVOKE|USE|TRUNCATE|LIST|DESCRIBE|DESC|COPY|COMMIT|RESTRICT|UNRESTRICT)'; + var WITH_OPTIONS = withKeywords({ + begin: /\bWITH\b/, + returnBegin: true, + end: new RegExp(';|^[ \\t]*' + STATEMENT_KEYWORD + '\\b'), + returnEnd: true, + relevance: 0, + contains: COMMENTS.concat([OPTION_NAME, NAME_BEFORE_RELATION_IN_WITH], COMMON) + }, KEYWORDS); + + return withKeywords({ + name: 'CQL', + aliases: ['cqlsh'], + case_insensitive: true, + // CQL resembles SQL closely enough that automatic detection would claim SQL blocks. + disableAutodetect: true, + contains: [RESULT_TABLE, ROW_COUNT].concat(COMMENTS, [CQLSH_COMMAND, COPY_COMMAND, PROMPT, WITH_OPTIONS], + COMMON, [NAME_BEFORE_RELATION]) + }, KEYWORDS); +} + +module.exports = cql; diff --git a/src/js/vendor/languages/graphql.js b/src/js/vendor/languages/graphql.js new file mode 100644 index 00000000..0377070b --- /dev/null +++ b/src/js/vendor/languages/graphql.js @@ -0,0 +1,85 @@ +/* + * GraphQL grammar for highlight.js 9, ported from highlight.js 11.12.0 + * (src/languages/graphql.js; Language: GraphQL; Author: John Foster (GH jf990), and others). + * + * The port changes only what highlight.js 9 needs: `scope` becomes `className`, `match` + * becomes `begin`, keyword lists are strings, the name-before-colon pattern is written out + * instead of built with `hljs.regex`, and the two `illegal` patterns are combined into one. + * + * BSD 3-Clause License + * + * Copyright (c) 2006, Ivan Sagalaev. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +'use strict' + +module.exports = function graphql (hljs) { + return { + name: 'GraphQL', + aliases: ['gql'], + case_insensitive: true, + disableAutodetect: false, + keywords: { + keyword: 'query mutation subscription type input schema directive interface union scalar fragment enum on', + literal: 'true false null', + }, + contains: [ + hljs.HASH_COMMENT_MODE, + hljs.QUOTE_STRING_MODE, + hljs.NUMBER_MODE, + { + className: 'punctuation', + begin: /[.]{3}/, + relevance: 0, + }, + { + className: 'punctuation', + begin: /[\!\(\)\:\=\[\]\{\|\}]{1}/, // eslint-disable-line no-useless-escape + relevance: 0, + }, + { + className: 'variable', + begin: /\$/, + end: /\W/, + excludeEnd: true, + relevance: 0, + }, + { + className: 'meta', + begin: /@\w+/, + excludeEnd: true, + }, + { + className: 'symbol', + begin: /[_A-Za-z][_0-9A-Za-z]*(?=\s*:)/, + relevance: 0, + }, + ], + illegal: /[;<']|BEGIN/, + } +} diff --git a/src/js/vendor/zooming.bundle.js b/src/js/vendor/zooming.bundle.js index 92f06932..e8eafac2 100644 --- a/src/js/vendor/zooming.bundle.js +++ b/src/js/vendor/zooming.bundle.js @@ -1,3 +1,4 @@ +/*! zooming 2.1.1 | MIT | Copyright (c) 2017-present Desmond Ding | https://github.com/kingdido999/zooming */ ;(function () { 'use strict'