diff --git a/README.md b/README.md index 119fdcd..cc6c223 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Load the `curl` module after loading Highlight.js. Use the minified version fou ```html + src="https://unpkg.com/highlightjs-curl@1.3.0/dist/curl.min.js"> ``` - More info: @@ -49,7 +49,7 @@ Once loaded, mark the code you want to highlight with the `language-curl` class:
...
``` -Without specifying the language, Highlight.js will attempt to auto-detect the grammar. Since this curl grammar is an extension of bash, it may detect bash instead. +Without specifying the language, Highlight.js will attempt to auto-detect the grammar. Since this curl grammar is an extension of bash, it may detect bash or some other grammar instead. Therefore, always specify `curl` or `language-curl`. For more information, follow instructions at [highlightjs.org](https://highlightjs.org/usage/) to learn how to include the library and CSS and other use cases. See [Getting started](https://github.com/highlightjs/highlight.js#getting-started) for different integration and module options. diff --git a/curl.js b/curl.js deleted file mode 100644 index fe03634..0000000 --- a/curl.js +++ /dev/null @@ -1,72 +0,0 @@ -/* - Language: cURL - Category: scripting - Author: John Foster - Description: Syntax highlighting for cURL commands. -*/ -var module = module ? module : {}; // shim for browser use - -function hljsDefineCurl(hljs) { - var KEYWORDS = { - keyword: - 'curl' - }; - var QUOTE_STRING = { - className: 'string', - begin: /"/, end: /"/, - contains: [ - hljs.BACKSLASH_ESCAPE, - { - className: 'variable', - begin: /\$\(/, end: /\)/, - contains: [hljs.BACKSLASH_ESCAPE] - } - ] - }; - var OPTION = { - className: 'literal', - begin: /--/, end: /[\s"]/, - returnEnd: true - }; - var OPTION_SINGLE = { - className: 'literal', - begin: /-\w/, end: /[\s"]/, - returnEnd: true - }; - var ESCAPED_QUOTE = { - className: 'string', - begin: /\\"/ - }; - var APOS_STRING = { - className: 'string', - begin: /'/, end: /'/ - }; - var NUMBER = { - className: 'number', - variants: [ - { begin: hljs.C_NUMBER_RE } - ], - relevance: 0 - }; - - return { - aliases: ['curl'], - keywords: KEYWORDS, - contains: [ - OPTION, - OPTION_SINGLE, - QUOTE_STRING, - ESCAPED_QUOTE, - APOS_STRING, - hljs.APOS_STRING_MODE, - hljs.QUOTE_STRING_MODE, - NUMBER - ] - }; -} - -module.exports = function(hljs) { - hljs.registerLanguage("curl", hljsDefineCurl); -}; - -module.exports.definer = hljsDefineCurl; diff --git a/dist/curl.es.min.js b/dist/curl.es.min.js new file mode 100644 index 0000000..454c100 --- /dev/null +++ b/dist/curl.es.min.js @@ -0,0 +1,14 @@ +/*! `curl` grammar compiled for Highlight.js 11.3.1 */ +var hljsGrammar=(()=>{"use strict";return e=>{const n={className:"string", +begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,{className:"variable", +begin:/\$\(/,end:/\)/,contains:[e.BACKSLASH_ESCAPE]}],relevance:0},a={ +className:"number",variants:[{begin:e.C_NUMBER_RE}],relevance:0};return{ +name:"curl",aliases:["curl"],keywords:"curl",case_insensitive:!0,contains:[{ +className:"literal",begin:/(--request|-X)\s/,contains:[{className:"symbol", +begin:/(get|post|delete|options|head|put|patch|trace|connect)/,end:/\s/, +returnEnd:!0}],returnEnd:!0,relevance:10},{className:"literal",begin:/--/, +end:/[\s"]/,returnEnd:!0,relevance:0},{className:"literal",begin:/-\w/, +end:/[\s"]/,returnEnd:!0,relevance:0},n,{className:"string",begin:/\\"/, +relevance:0},{className:"string",begin:/'/,end:/'/,relevance:0 +},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,{match:/(\/[a-z._-]+)+/}]}}})() +;export default hljsGrammar; \ No newline at end of file diff --git a/dist/curl.min.js b/dist/curl.min.js index 45bb1cd..924af72 100644 --- a/dist/curl.min.js +++ b/dist/curl.min.js @@ -1 +1,14 @@ -hljs.registerLanguage("curl",function(){"use strict";return function(e){var n={className:"string",begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,{className:"variable",begin:/\$\(/,end:/\)/,contains:[e.BACKSLASH_ESCAPE]}],relevance:0},a={className:"number",variants:[{begin:e.C_NUMBER_RE}],relevance:0};return{name:"curl",aliases:["curl"],keywords:"curl",case_insensitive:!0,contains:[{className:"literal",begin:/(--request|-X)\s/,contains:[{className:"symbol",begin:/(get|post|delete|options|head|put|patch|trace|connect)/,end:/\s/,returnEnd:!0}],returnEnd:!0,relevance:10},{className:"literal",begin:/--/,end:/[\s"]/,returnEnd:!0,relevance:0},{className:"literal",begin:/-\w/,end:/[\s"]/,returnEnd:!0,relevance:0},n,{className:"string",begin:/\\"/,relevance:0},{className:"string",begin:/'/,end:/'/,relevance:0},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a]}}}()); \ No newline at end of file +/*! `curl` grammar compiled for Highlight.js 11.3.1 */ +(()=>{var e=(()=>{"use strict";return e=>{const n={className:"string",begin:/"/, +end:/"/,contains:[e.BACKSLASH_ESCAPE,{className:"variable",begin:/\$\(/, +end:/\)/,contains:[e.BACKSLASH_ESCAPE]}],relevance:0},a={className:"number", +variants:[{begin:e.C_NUMBER_RE}],relevance:0};return{name:"curl", +aliases:["curl"],keywords:"curl",case_insensitive:!0,contains:[{ +className:"literal",begin:/(--request|-X)\s/,contains:[{className:"symbol", +begin:/(get|post|delete|options|head|put|patch|trace|connect)/,end:/\s/, +returnEnd:!0}],returnEnd:!0,relevance:10},{className:"literal",begin:/--/, +end:/[\s"]/,returnEnd:!0,relevance:0},{className:"literal",begin:/-\w/, +end:/[\s"]/,returnEnd:!0,relevance:0},n,{className:"string",begin:/\\"/, +relevance:0},{className:"string",begin:/'/,end:/'/,relevance:0 +},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,{match:/(\/[a-z._-]+)+/}]}}})() +;hljs.registerLanguage("curl",e)})(); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index b84809a..54e671a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,8 +1,147 @@ { "name": "highlightjs-curl", - "version": "1.2.0", - "lockfileVersion": 1, + "version": "1.3.0", + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "highlightjs-curl", + "version": "1.3.0", + "license": "Apache-2.0", + "devDependencies": { + "highlight.js": "^11.3.1", + "jasmine": "^3.10.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/highlight.js": { + "version": "11.3.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.3.1.tgz", + "integrity": "sha512-PUhCRnPjLtiLHZAQ5A/Dt5F8cWZeMyj9KRsACsWT+OD6OP0x6dp5OmT5jdx0JgEyPxPZZIPQpRN2TciUT7occw==", + "dev": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/jasmine": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-3.10.0.tgz", + "integrity": "sha512-2Y42VsC+3CQCTzTwJezOvji4qLORmKIE0kwowWC+934Krn6ZXNQYljiwK5st9V3PVx96BSiDYXSB60VVah3IlQ==", + "dev": true, + "dependencies": { + "glob": "^7.1.6", + "jasmine-core": "~3.10.0" + }, + "bin": { + "jasmine": "bin/jasmine.js" + } + }, + "node_modules/jasmine-core": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.10.1.tgz", + "integrity": "sha512-ooZWSDVAdh79Rrj4/nnfklL3NQVra0BcuhcuWoAwwi+znLDoUeH87AFfeX8s+YeYi6xlv5nveRyaA1v7CintfA==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + } + }, "dependencies": { "balanced-match": { "version": "1.0.0", @@ -47,9 +186,9 @@ } }, "highlight.js": { - "version": "10.7.1", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.1.tgz", - "integrity": "sha512-S6G97tHGqJ/U8DsXcEdnACbirtbx58Bx9CzIVeYli8OuswCfYI/LsXH2EiGcoGio1KAC3x4mmUwulOllJ2ZyRA==", + "version": "11.3.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.3.1.tgz", + "integrity": "sha512-PUhCRnPjLtiLHZAQ5A/Dt5F8cWZeMyj9KRsACsWT+OD6OP0x6dp5OmT5jdx0JgEyPxPZZIPQpRN2TciUT7occw==", "dev": true }, "inflight": { @@ -69,19 +208,19 @@ "dev": true }, "jasmine": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-3.7.0.tgz", - "integrity": "sha512-wlzGQ+cIFzMEsI+wDqmOwvnjTvolLFwlcpYLCqSPPH0prOQaW3P+IzMhHYn934l1imNvw07oCyX+vGUv3wmtSQ==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-3.10.0.tgz", + "integrity": "sha512-2Y42VsC+3CQCTzTwJezOvji4qLORmKIE0kwowWC+934Krn6ZXNQYljiwK5st9V3PVx96BSiDYXSB60VVah3IlQ==", "dev": true, "requires": { "glob": "^7.1.6", - "jasmine-core": "~3.7.0" + "jasmine-core": "~3.10.0" } }, "jasmine-core": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.7.1.tgz", - "integrity": "sha512-DH3oYDS/AUvvr22+xUBW62m1Xoy7tUlY1tsxKEJvl5JeJ7q8zd1K5bUwiOxdH+erj6l2vAMM3hV25Xs9/WrmuQ==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.10.1.tgz", + "integrity": "sha512-ooZWSDVAdh79Rrj4/nnfklL3NQVra0BcuhcuWoAwwi+znLDoUeH87AFfeX8s+YeYi6xlv5nveRyaA1v7CintfA==", "dev": true }, "minimatch": { diff --git a/package.json b/package.json index 91f88e1..7615e3f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "highlightjs-curl", - "version": "1.2.1", + "version": "1.3.0", "author": "John Foster", "description": "Support for using highlight.js to syntax highlight cURL commands.", "main": "src/languages/curl.js", @@ -28,7 +28,7 @@ }, "homepage": "https://github.com/highlightjs/highlightjs-curl#readme", "devDependencies": { - "highlight.js": "^10.7.1", - "jasmine": "^3.7.0" + "highlight.js": "^11.3.1", + "jasmine": "^3.10.0" } } diff --git a/spec/test.html b/spec/test.html index e75de8d..4b1dbb0 100644 --- a/spec/test.html +++ b/spec/test.html @@ -3,8 +3,8 @@ Test highlightjs curl grammar - - + + @@ -20,10 +20,10 @@

Code block

--range 3 -H "Auth: bearer 1234" --header "Accept: ascii" - -O ftp://any.domain.com/public/xss.html + -O ftp://any.domain.com/public/path-to-resource/xss.html

-    curl --request post -u ftpuser:ftppass --proxy-header --range 3 -H "Auth: bearer 1234" --header "Accept: ascii" -O ftp://any.domain.com/public/xss.html https://example.com/v2/endpoint.php
+    curl --request post -u ftpuser:ftppass --proxy-header --range 3 -H "Auth: bearer 1234" --header "Accept: ascii" -O ftp://any.domain.com/public/path-to-resource/xss.html https://example.com/v2/endpoint.php
   
diff --git a/src/languages/curl.js b/src/languages/curl.js index fbe6739..21af811 100644 --- a/src/languages/curl.js +++ b/src/languages/curl.js @@ -6,7 +6,7 @@ */ module.exports = function (hljs) { - var QUOTE_STRING = { + const QUOTE_STRING = { className: 'string', begin: /"/, end: /"/, contains: [ @@ -16,9 +16,10 @@ module.exports = function (hljs) { begin: /\$\(/, end: /\)/, contains: [hljs.BACKSLASH_ESCAPE] } - ] + ], + relevance: 0 }; - var OPTION_REQUEST = { + const OPTION_REQUEST = { className: 'literal', begin: /(--request|-X)\s/, contains: [ @@ -32,31 +33,39 @@ module.exports = function (hljs) { returnEnd: true, relevance: 10 }; - var OPTION = { + const OPTION = { className: 'literal', begin: /--/, end: /[\s"]/, - returnEnd: true + returnEnd: true, + relevance: 0 }; - var OPTION_SINGLE = { + const OPTION_SINGLE = { className: 'literal', begin: /-\w/, end: /[\s"]/, - returnEnd: true + returnEnd: true, + relevance: 0 }; - var ESCAPED_QUOTE = { + const ESCAPED_QUOTE = { className: 'string', - begin: /\\"/ + begin: /\\"/, + relevance: 0 }; - var APOS_STRING = { + const APOS_STRING = { className: 'string', - begin: /'/, end: /'/ + begin: /'/, end: /'/, + relevance: 0 }; - var NUMBER = { + const NUMBER = { className: 'number', variants: [ { begin: hljs.C_NUMBER_RE } ], relevance: 0 }; + // to consume paths to prevent keyword matches inside them + const PATH_MODE = { + match: /(\/[a-z._-]+)+/ + }; return { name: "curl", @@ -72,7 +81,8 @@ module.exports = function (hljs) { APOS_STRING, hljs.APOS_STRING_MODE, hljs.QUOTE_STRING_MODE, - NUMBER + NUMBER, + PATH_MODE ] }; } diff --git a/test/detect/curl/sample.txt b/test/detect/curl/sample.txt index b8aae63..6f10948 100644 --- a/test/detect/curl/sample.txt +++ b/test/detect/curl/sample.txt @@ -1 +1 @@ -curl -X POST -u ftpuser:ftppass --proxy-header --range 3 -H "Auth: bearer 1234" --header "Accept: ascii" -O ftp://any.domain.com/public/xss.html \ No newline at end of file +curl -X POST -u ftpuser:ftppass --proxy-header --range 3 -H "Auth: bearer 1234" --header "Accept: ascii" -O ftp://any.domain.com/public/path-to-resource/xss.html \ No newline at end of file diff --git a/test/markup/curl/sample.expect.txt b/test/markup/curl/sample.expect.txt index fd68602..8fbb066 100644 --- a/test/markup/curl/sample.expect.txt +++ b/test/markup/curl/sample.expect.txt @@ -1 +1 @@ -curl -X POST -u ftpuser:ftppass --proxy-header --range 3 -H "Auth: bearer 1234" --header "Accept: ascii" -O ftp://any.domain.com/public/xss.html \ No newline at end of file +curl -X POST -u ftpuser:ftppass --proxy-header --range 3 -H "Auth: bearer 1234" --header "Accept: ascii" -O ftp://any.domain.com/public/path-to-resource/xss.html \ No newline at end of file diff --git a/test/markup/curl/sample.txt b/test/markup/curl/sample.txt index b8aae63..6f10948 100644 --- a/test/markup/curl/sample.txt +++ b/test/markup/curl/sample.txt @@ -1 +1 @@ -curl -X POST -u ftpuser:ftppass --proxy-header --range 3 -H "Auth: bearer 1234" --header "Accept: ascii" -O ftp://any.domain.com/public/xss.html \ No newline at end of file +curl -X POST -u ftpuser:ftppass --proxy-header --range 3 -H "Auth: bearer 1234" --header "Accept: ascii" -O ftp://any.domain.com/public/path-to-resource/xss.html \ No newline at end of file