├── .editorconfig ├── .eslintrc.json ├── .gitattributes ├── .gitignore ├── .travis.yml ├── .verb.md ├── CHANGELOG.md ├── LICENSE ├── README.md ├── examples ├── block.js ├── example.js ├── line.js ├── strip.js └── support │ └── helpers.js ├── index.js ├── lib ├── Node.js ├── compile.js ├── languages.js └── parse.js ├── package.json └── test ├── .eslintrc.json ├── HTML.js ├── JavaScript.js ├── expected ├── banner-protected.js ├── banner.js ├── html │ ├── dashes.html │ ├── index.html │ ├── multiline.html │ └── quoted.html ├── other │ ├── AppleScript.txt │ ├── ada.txt │ ├── apl.txt │ ├── c.txt │ ├── haskell.txt │ ├── lua.txt │ ├── matlab.txt │ ├── ocaml.txt │ ├── pascal.txt │ ├── perl.txt │ ├── php.txt │ ├── python.txt │ ├── ruby.txt │ ├── shebang.txt │ ├── sql.txt │ └── swift.txt ├── strip-all.js ├── strip-keep-block.js ├── strip-keep-line.js └── strip-keep-newlines.js ├── fixtures ├── banner.js ├── html │ ├── dashes.html │ ├── index.html │ ├── multiline.html │ └── quoted.html ├── line.js ├── no-comment.js ├── other │ ├── AppleScript.txt │ ├── ada.txt │ ├── apl.txt │ ├── c.txt │ ├── haskell.txt │ ├── lua.txt │ ├── matlab.txt │ ├── ocaml.txt │ ├── pascal.txt │ ├── perl.txt │ ├── php.txt │ ├── python.txt │ ├── ruby.txt │ ├── shebang.txt │ ├── sql.txt │ └── swift.txt ├── quoted-strings.js ├── strip-all.js └── strip-keep-line.js └── other.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org/ 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | 14 | [test/{fixtures,expected}/**] 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "eslint:recommended" 4 | ], 5 | 6 | "env": { 7 | "es6": true, 8 | "node": true 9 | }, 10 | 11 | "parserOptions":{ 12 | "ecmaVersion": 9 13 | }, 14 | 15 | "rules": { 16 | "accessor-pairs": 2, 17 | "arrow-spacing": [2, { "before": true, "after": true }], 18 | "block-spacing": [2, "always"], 19 | "brace-style": [2, "1tbs", { "allowSingleLine": true }], 20 | "comma-dangle": [2, "never"], 21 | "comma-spacing": [2, { "before": false, "after": true }], 22 | "comma-style": [2, "last"], 23 | "constructor-super": 2, 24 | "curly": [2, "multi-line"], 25 | "dot-location": [2, "property"], 26 | "eol-last": 2, 27 | "eqeqeq": [2, "allow-null"], 28 | "generator-star-spacing": [2, { "before": true, "after": true }], 29 | "handle-callback-err": [2, "^(err|error)$" ], 30 | "indent": [2, 2, { "SwitchCase": 1 }], 31 | "key-spacing": [2, { "beforeColon": false, "afterColon": true }], 32 | "keyword-spacing": [2, { "before": true, "after": true }], 33 | "new-cap": [2, { "newIsCap": true, "capIsNew": false }], 34 | "new-parens": 2, 35 | "no-array-constructor": 2, 36 | "no-caller": 2, 37 | "no-class-assign": 2, 38 | "no-cond-assign": 2, 39 | "no-const-assign": 2, 40 | "no-control-regex": 2, 41 | "no-debugger": 2, 42 | "no-delete-var": 2, 43 | "no-dupe-args": 2, 44 | "no-dupe-class-members": 2, 45 | "no-dupe-keys": 2, 46 | "no-duplicate-case": 2, 47 | "no-empty-character-class": 2, 48 | "no-eval": 2, 49 | "no-ex-assign": 2, 50 | "no-extend-native": 2, 51 | "no-extra-bind": 2, 52 | "no-extra-boolean-cast": 2, 53 | "no-extra-parens": [2, "functions"], 54 | "no-fallthrough": 2, 55 | "no-floating-decimal": 2, 56 | "no-func-assign": 2, 57 | "no-implied-eval": 2, 58 | "no-implicit-coercion": 2, 59 | "no-inner-declarations": [2, "functions"], 60 | "no-invalid-regexp": 2, 61 | "no-irregular-whitespace": 2, 62 | "no-iterator": 2, 63 | "no-label-var": 2, 64 | "no-labels": 2, 65 | "no-lone-blocks": 2, 66 | "no-lonely-if": 2, 67 | "no-mixed-spaces-and-tabs": 2, 68 | "no-multi-spaces": 0, 69 | "no-multi-str": 2, 70 | "no-multiple-empty-lines": [2, { "max": 1 }], 71 | "no-native-reassign": 2, 72 | "no-negated-in-lhs": 2, 73 | "no-new": 2, 74 | "no-new-func": 2, 75 | "no-new-object": 2, 76 | "no-new-require": 2, 77 | "no-new-wrappers": 2, 78 | "no-obj-calls": 2, 79 | "no-octal": 2, 80 | "no-octal-escape": 2, 81 | "no-proto": 2, 82 | "no-redeclare": 2, 83 | "no-regex-spaces": 2, 84 | "no-return-assign": 2, 85 | "no-self-compare": 2, 86 | "no-sequences": 2, 87 | "no-shadow-restricted-names": 2, 88 | "no-spaced-func": 2, 89 | "no-sparse-arrays": 2, 90 | "no-this-before-super": 2, 91 | "no-throw-literal": 2, 92 | "no-trailing-spaces": 2, 93 | "no-undef": 2, 94 | "no-undef-init": 2, 95 | "no-unexpected-multiline": 2, 96 | "no-unneeded-ternary": [2, { "defaultAssignment": false }], 97 | "no-unreachable": 2, 98 | "no-unused-expressions": 2, 99 | "no-unused-vars": [2, { "vars": "all", "args": "none" }], 100 | "no-useless-call": 2, 101 | "no-with": 2, 102 | "object-curly-spacing": ["error", "always", { "objectsInObjects": true }], 103 | "one-var": [2, { "initialized": "never" }], 104 | "operator-linebreak": [0, "after", { "overrides": { "?": "before", ":": "before" } }], 105 | "padded-blocks": [0, "never"], 106 | "prefer-const": 2, 107 | "quotes": [2, "single", "avoid-escape"], 108 | "radix": 2, 109 | "semi": [2, "always"], 110 | "semi-spacing": [2, { "before": false, "after": true }], 111 | "space-before-blocks": [2, "always"], 112 | "space-before-function-paren": [2, "never"], 113 | "space-in-parens": [2, "never"], 114 | "space-infix-ops": 2, 115 | "space-unary-ops": [2, { "words": true, "nonwords": false }], 116 | "spaced-comment": [0, "always", { "markers": ["global", "globals", "eslint", "eslint-disable", "*package", "!", ","] }], 117 | "strict": 2, 118 | "use-isnan": 2, 119 | "valid-typeof": 2, 120 | "wrap-iife": [2, "any"], 121 | "yoda": [2, "never"] 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # always ignore files 2 | *.DS_Store 3 | .idea 4 | .vscode 5 | *.sublime-* 6 | 7 | # test related, or directories generated by tests 8 | test/actual 9 | actual 10 | coverage 11 | .nyc* 12 | 13 | # npm 14 | node_modules 15 | npm-debug.log 16 | 17 | # yarn 18 | yarn.lock 19 | yarn-error.log 20 | 21 | # misc 22 | _gh_pages 23 | _draft 24 | _drafts 25 | bower_components 26 | vendor 27 | temp 28 | tmp 29 | TODO.md 30 | package-lock.json -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | os: 3 | - linux 4 | - osx 5 | - windows 6 | language: node_js 7 | node_js: 8 | - node 9 | - '12' 10 | - '10' 11 | -------------------------------------------------------------------------------- /.verb.md: -------------------------------------------------------------------------------- 1 | ## What does this do? 2 | 3 | Takes a string and returns a new string with comments removed. Works with line comments and/or block comments. Optionally removes the first comment only or ignores protected comments. 4 | 5 | Works with: 6 | 7 | {%= languages() %} 8 | 9 | ## Usage 10 | 11 | By default all comments are stripped. 12 | 13 | ```js 14 | const strip = require('{%= name %}'); 15 | const str = strip('const foo = "bar";// this is a comment\n /* me too *\/'); 16 | console.log(str); 17 | // => 'const foo = "bar";\n' 18 | ``` 19 | 20 | For more use-cases see the [tests](./test) 21 | 22 | ## API 23 | {%= strip(apidocs("index.js")) %} 24 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Release history 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) 6 | and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). 7 | 8 |
9 | Guiding Principles 10 | 11 | - Changelogs are for humans, not machines. 12 | - There should be an entry for every single version. 13 | - The same types of changes should be grouped. 14 | - Versions and sections should be linkable. 15 | - The latest version comes first. 16 | - The release date of each versions is displayed. 17 | - Mention whether you follow Semantic Versioning. 18 | 19 |
20 | 21 |
22 | Types of changes 23 | 24 | Changelog entries are classified using the following labels _(from [keep-a-changelog](http://keepachangelog.com/)_): 25 | 26 | - `Added` for new features. 27 | - `Changed` for changes in existing functionality. 28 | - `Deprecated` for soon-to-be removed features. 29 | - `Removed` for now removed features. 30 | - `Fixed` for any bug fixes. 31 | - `Security` in case of vulnerabilities. 32 | 33 |
34 | 35 | 36 | ## [2.0.0] - 2019-09-14 37 | 38 | **Changed** 39 | 40 | - Refactored again to use a custom parser that is much faster and supports a number of different languages. 41 | 42 | ## [1.0.2] - 2018-05-03 43 | 44 | - refactored 45 | - Remove default objectRestSpread plugin #40 allows for user configured plugins 46 | - Merge pull request #42 from tallarium/remove-default-transform 47 | - Merge remote-tracking branch 'origin/master' into refactor 48 | - Merge remote-tracking branch 'origin/master' into refactor 49 | - Merge pull request #44 from jonschlinkert/refactor 50 | 51 | ## [1.0.1] - 2018-03-24 52 | 53 | - feat: Allow users to specify their own babylon plugins 54 | - Merge pull request #40 from briandipalma/patch-1 55 | - adds `allowReturnOutsideFunction` to defaults 56 | 57 | ## [1.0.0] - 2018-03-24 58 | 59 | - adds object-rest-spread plugin 60 | 61 | ## [0.4.4] - 2016-02-14 62 | 63 | - refactor to use babylon 64 | 65 | ## [0.4.3] - 2015-12-25 66 | 67 | - minor tweak 68 | 69 | ## [0.4.2] - 2015-12-11 70 | 71 | - bump extract-comments per issue https://github.com/jonschlinkert/strip-comments/issues/29 72 | - Merge branch 'master' of https://github.com/lebbe/strip-comments into lebbe-master 73 | - Merge branch 'lebbe-master' 74 | 75 | ## [0.4.0] - 2015-11-04 76 | 77 | - adds more test cases 78 | - closes https://github.com/jonschlinkert/strip-comments/issues/18 79 | - Handles comments that are substrings of a later comment 80 | - Merge pull request #28 from epicoxymoron/bugfix/27-discard-is-too-greedy 81 | - adds example 82 | - adds json test 83 | 84 | ## [0.3.4] - 2015-10-22 85 | 86 | - refactored 87 | - expose `first` method. code comments, minor formatting 88 | - allow line/block to be specified as options 89 | - Merge pull request #23 from jonschlinkert/dev 90 | - fixes examples 91 | - adds editorconfig 92 | 93 | ## [0.3.0] - 2014-09-02 94 | 95 | - merge fix from origin 96 | - Merge pull request #13 from mk-pmb/tests_literals_nocomment 97 | - Merge pull request #15 from mk-pmb/tests_literals_snake 98 | - Merge pull request #22 from kgryte/patch-1 99 | - Merge pull request #9 from tunnckoCore/master 100 | - Merge remote-tracking branch 'origin/line-comments' 101 | - Merge remote-tracking branch 'origin/master' 102 | - tests: not a comment: snake-y ASCII art 103 | - tests: string and regexp literals 104 | - adds tests for URLs 105 | - fix globstars 106 | - lint 107 | 108 | ## [0.2.0] - 2014-08-10 109 | 110 | - fixes `use strict` statement 111 | 112 | ## [0.1.6] - 2014-02-13 113 | 114 | - Merge branch 'master' of https://github.com/tunnckoCore/strip-comments into tunnckoCore-master 115 | - Merge branch 'tunnckoCore-master' 116 | - minor formatting 117 | 118 | ## [0.1.0] - 2014-02-10 119 | 120 | - first commit 121 | 122 | [1.0.2]: https://github.com/jonschlinkert/strip-comments/compare/1.0.1...1.0.2 123 | [1.0.1]: https://github.com/jonschlinkert/strip-comments/compare/1.0.0...1.0.1 124 | [1.0.0]: https://github.com/jonschlinkert/strip-comments/compare/0.4.4...1.0.0 125 | [0.4.4]: https://github.com/jonschlinkert/strip-comments/compare/0.4.3...0.4.4 126 | [0.4.3]: https://github.com/jonschlinkert/strip-comments/compare/0.4.2...0.4.3 127 | [0.4.2]: https://github.com/jonschlinkert/strip-comments/compare/0.4.0...0.4.2 128 | [0.4.0]: https://github.com/jonschlinkert/strip-comments/compare/0.3.4...0.4.0 129 | [0.3.4]: https://github.com/jonschlinkert/strip-comments/compare/0.3.0...0.3.4 130 | [0.3.0]: https://github.com/jonschlinkert/strip-comments/compare/0.2.0...0.3.0 131 | [0.2.0]: https://github.com/jonschlinkert/strip-comments/compare/0.1.6...0.2.0 132 | [0.1.6]: https://github.com/jonschlinkert/strip-comments/compare/0.1.0...0.1.6 133 | 134 | [Unreleased]: https://github.com/jonschlinkert/strip-comments/compare/0.1.0...HEAD 135 | [keep-a-changelog]: https://github.com/olivierlacan/keep-a-changelog 136 | 137 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014-present, Jon Schlinkert. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # strip-comments [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=W8YFZ425KND68) [![NPM version](https://img.shields.io/npm/v/strip-comments.svg?style=flat)](https://www.npmjs.com/package/strip-comments) [![NPM monthly downloads](https://img.shields.io/npm/dm/strip-comments.svg?style=flat)](https://npmjs.org/package/strip-comments) [![NPM total downloads](https://img.shields.io/npm/dt/strip-comments.svg?style=flat)](https://npmjs.org/package/strip-comments) [![Build Status](https://travis-ci.org/jonschlinkert/strip-comments.svg?branch=master)](https://travis-ci.org/jonschlinkert/strip-comments) 2 | 3 | > Strip line and/or block comments from a string. Blazing fast, and works with JavaScript, Sass, CSS, Less.js, and a number of other languages. 4 | 5 | Please consider following this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), and consider starring the project to show your :heart: and support. 6 | 7 | - [Install](#install) 8 | - [What does this do?](#what-does-this-do) 9 | - [Usage](#usage) 10 | - [API](#api) 11 | - [About](#about) 12 | 13 | _(TOC generated by [verb](https://github.com/verbose/verb) using [markdown-toc](https://github.com/jonschlinkert/markdown-toc))_ 14 | 15 | ## Install 16 | 17 | Install with [npm](https://www.npmjs.com/) (requires [Node.js](https://nodejs.org/en/) >=10): 18 | 19 | ```sh 20 | $ npm install --save strip-comments 21 | ``` 22 | 23 | ## What does this do? 24 | 25 | Takes a string and returns a new string with comments removed. Works with line comments and/or block comments. Optionally removes the first comment only or ignores protected comments. 26 | 27 | Works with: 28 | 29 | * ada 30 | * apl 31 | * applescript 32 | * c 33 | * csharp 34 | * css 35 | * hashbang 36 | * haskell 37 | * html 38 | * java 39 | * javascript 40 | * less 41 | * lua 42 | * matlab 43 | * ocaml 44 | * pascal 45 | * perl 46 | * php 47 | * python 48 | * ruby 49 | * sass 50 | * shebang 51 | * sql 52 | * swift 53 | * typscript 54 | * xml 55 | 56 | ## Usage 57 | 58 | By default all comments are stripped. 59 | 60 | ```js 61 | const strip = require('strip-comments'); 62 | const str = strip('const foo = "bar";// this is a comment\n /* me too *\/'); 63 | console.log(str); 64 | // => 'const foo = "bar";\n' 65 | ``` 66 | 67 | For more use-cases see the [tests](./test) 68 | 69 | ## API 70 | 71 | ### [strip](index.js#L33) 72 | 73 | Strip all code comments from the given `input`, including protected comments that start with `!`, unless disabled by setting `options.keepProtected` to true. 74 | 75 | **Params** 76 | 77 | * `input` **{String}**: string from which to strip comments 78 | * `options` **{Object}**: optional options, passed to [extract-comments](https://github.com/jonschlinkert/extract-comments) 79 | 80 | - `line` **{Boolean}**: if `false` strip only block comments, default `true` 81 | - `block` **{Boolean}**: if `false` strip only line comments, default `true` 82 | - `keepProtected` **{Boolean}**: Keep ignored comments (e.g. `/*!` and `//!`) 83 | - `preserveNewlines` **{Boolean}**: Preserve newlines after comments are stripped 84 | * `returns` **{String}**: modified input 85 | 86 | **Example** 87 | 88 | ```js 89 | const str = strip('const foo = "bar";// this is a comment\n /* me too */'); 90 | console.log(str); 91 | // => 'const foo = "bar";' 92 | ``` 93 | 94 | ### [.block](index.js#L54) 95 | 96 | Strip only block comments. 97 | 98 | **Params** 99 | 100 | * `input` **{String}**: string from which to strip comments 101 | * `options` **{Object}**: pass `opts.keepProtected: true` to keep ignored comments (e.g. `/*!`) 102 | * `returns` **{String}**: modified string 103 | 104 | **Example** 105 | 106 | ```js 107 | const strip = require('..'); 108 | const str = strip.block('const foo = "bar";// this is a comment\n /* me too */'); 109 | console.log(str); 110 | // => 'const foo = "bar";// this is a comment' 111 | ``` 112 | 113 | ### [.line](index.js#L74) 114 | 115 | Strip only line comments. 116 | 117 | **Params** 118 | 119 | * `input` **{String}**: string from which to strip comments 120 | * `options` **{Object}**: pass `opts.keepProtected: true` to keep ignored comments (e.g. `//!`) 121 | * `returns` **{String}**: modified string 122 | 123 | **Example** 124 | 125 | ```js 126 | const str = strip.line('const foo = "bar";// this is a comment\n /* me too */'); 127 | console.log(str); 128 | // => 'const foo = "bar";\n/* me too */' 129 | ``` 130 | 131 | ### [.first](index.js#L95) 132 | 133 | Strip the first comment from the given `input`. Or, if `opts.keepProtected` is true, the first non-protected comment will be stripped. 134 | 135 | **Params** 136 | 137 | * `input` **{String}** 138 | * `options` **{Object}**: pass `opts.keepProtected: true` to keep comments with `!` 139 | * `returns` **{String}** 140 | 141 | **Example** 142 | 143 | ```js 144 | const output = strip.first(input, { keepProtected: true }); 145 | console.log(output); 146 | // => '//! first comment\nfoo; ' 147 | ``` 148 | 149 | ### [.block](index.js#L116) 150 | 151 | Parses a string and returns a basic CST (Concrete Syntax Tree). 152 | 153 | **Params** 154 | 155 | * `input` **{String}**: string from which to strip comments 156 | * `options` **{Object}**: pass `opts.keepProtected: true` to keep ignored comments (e.g. `/*!`) 157 | * `returns` **{String}**: modified string 158 | 159 | **Example** 160 | 161 | ```js 162 | const strip = require('..'); 163 | const str = strip.block('const foo = "bar";// this is a comment\n /* me too */'); 164 | console.log(str); 165 | // => 'const foo = "bar";// this is a comment' 166 | ``` 167 | 168 | ## About 169 | 170 |
171 | Contributing 172 | 173 | Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). 174 | 175 |
176 | 177 |
178 | Running Tests 179 | 180 | Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command: 181 | 182 | ```sh 183 | $ npm install && npm test 184 | ``` 185 | 186 |
187 | 188 |
189 | Building docs 190 | 191 | _(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_ 192 | 193 | To generate the readme, run the following command: 194 | 195 | ```sh 196 | $ npm install -g verbose/verb#dev verb-generate-readme && verb 197 | ``` 198 | 199 |
200 | 201 | ### Related projects 202 | 203 | You might also be interested in these projects: 204 | 205 | * [code-context](https://www.npmjs.com/package/code-context): Parse a string of javascript to determine the context for functions, variables and comments based… [more](https://github.com/jonschlinkert/code-context) | [homepage](https://github.com/jonschlinkert/code-context "Parse a string of javascript to determine the context for functions, variables and comments based on the code that follows.") 206 | * [extract-comments](https://www.npmjs.com/package/extract-comments): Uses esprima to extract line and block comments from a string of JavaScript. Also optionally… [more](https://github.com/jonschlinkert/extract-comments) | [homepage](https://github.com/jonschlinkert/extract-comments "Uses esprima to extract line and block comments from a string of JavaScript. Also optionally parses code context (the next line of code after a comment).") 207 | * [parse-code-context](https://www.npmjs.com/package/parse-code-context): Fast and simple way to parse code context for use with documentation from code comments… [more](https://github.com/jonschlinkert/parse-code-context) | [homepage](https://github.com/jonschlinkert/parse-code-context "Fast and simple way to parse code context for use with documentation from code comments. Parses context from a single line of JavaScript, for functions, variable declarations, methods, prototype properties, prototype methods etc.") 208 | * [parse-comments](https://www.npmjs.com/package/parse-comments): Parse code comments from JavaScript or any language that uses the same format. | [homepage](https://github.com/jonschlinkert/parse-comments "Parse code comments from JavaScript or any language that uses the same format.") 209 | 210 | ### Contributors 211 | 212 | | **Commits** | **Contributor** | 213 | | --- | --- | 214 | | 82 | [jonschlinkert](https://github.com/jonschlinkert) | 215 | | 4 | [tunnckoCore](https://github.com/tunnckoCore) | 216 | | 2 | [mk-pmb](https://github.com/mk-pmb) | 217 | | 1 | [kgryte](https://github.com/kgryte) | 218 | | 1 | [briandipalma](https://github.com/briandipalma) | 219 | | 1 | [epicoxymoron](https://github.com/epicoxymoron) | 220 | | 1 | [XuluWarrior](https://github.com/XuluWarrior) | 221 | 222 | ### Author 223 | 224 | **Jon Schlinkert** 225 | 226 | * [GitHub Profile](https://github.com/jonschlinkert) 227 | * [Twitter Profile](https://twitter.com/jonschlinkert) 228 | * [LinkedIn Profile](https://linkedin.com/in/jonschlinkert) 229 | 230 | ### License 231 | 232 | Copyright © 2019, [Jon Schlinkert](https://github.com/jonschlinkert). 233 | Released under the [MIT License](LICENSE). 234 | 235 | *** 236 | 237 | _This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on November 13, 2019._ 238 | -------------------------------------------------------------------------------- /examples/block.js: -------------------------------------------------------------------------------- 1 | const strip = require('..'); 2 | const str = strip.block('const foo = "bar";// this is a comment\n /* me too */'); 3 | console.log(str); 4 | // => 'const foo = "bar";// this is a comment' 5 | -------------------------------------------------------------------------------- /examples/example.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | const strip = require('..'); 5 | 6 | const all = fs.readFileSync('test/fixtures/strip-all.js', 'utf8'); 7 | const str = fs.readFileSync('test/fixtures/banner.js', 'utf8'); 8 | 9 | // console.log(strip.first(all)) 10 | // console.log(strip.block(all)); 11 | // console.log(strip.line(all)); 12 | console.log(strip(all)); 13 | -------------------------------------------------------------------------------- /examples/line.js: -------------------------------------------------------------------------------- 1 | const strip = require('..'); 2 | const str = strip.line('const foo = "bar";// this is a comment\n /* me too */'); 3 | console.log(str); 4 | // => 'const foo = "bar";\n /* me too */' 5 | -------------------------------------------------------------------------------- /examples/strip.js: -------------------------------------------------------------------------------- 1 | const strip = require('..'); 2 | const str = strip('const foo = "bar";/* me too */\n// this is a comment'); 3 | console.log(str); 4 | // => 'const foo = "bar";\n' 5 | -------------------------------------------------------------------------------- /examples/support/helpers.js: -------------------------------------------------------------------------------- 1 | const languages = require('../../lib/languages'); 2 | 3 | exports.strip = str => str.split('*\\/').join('*/'); 4 | 5 | // this is used by the readme template to generate the list of languages. 6 | exports.languages = () => { 7 | const omit = new Set(['js', 'ts']); 8 | const keys = Object.keys(languages) 9 | .sort((a, b) => a.localeCompare(b)) 10 | .filter(key => !omit.has(key)); 11 | 12 | return `\n- ${keys.join('\n- ')}`; 13 | }; 14 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * strip-comments 3 | * Copyright (c) 2014-present, Jon Schlinkert. 4 | * Released under the MIT License. 5 | */ 6 | 7 | 'use strict'; 8 | 9 | const compile = require('./lib/compile'); 10 | const parse = require('./lib/parse'); 11 | 12 | /** 13 | * Strip all code comments from the given `input`, including protected 14 | * comments that start with `!`, unless disabled by setting `options.keepProtected` 15 | * to true. 16 | * 17 | * ```js 18 | * const str = strip('const foo = "bar";// this is a comment\n /* me too *\/'); 19 | * console.log(str); 20 | * // => 'const foo = "bar";' 21 | * ``` 22 | * @name strip 23 | * @param {String} `input` string from which to strip comments 24 | * @param {Object} `options` optional options, passed to [extract-comments][extract-comments] 25 | * @option {Boolean} [options] `line` if `false` strip only block comments, default `true` 26 | * @option {Boolean} [options] `block` if `false` strip only line comments, default `true` 27 | * @option {Boolean} [options] `keepProtected` Keep ignored comments (e.g. `/*!` and `//!`) 28 | * @option {Boolean} [options] `preserveNewlines` Preserve newlines after comments are stripped 29 | * @return {String} modified input 30 | * @api public 31 | */ 32 | 33 | const strip = module.exports = (input, options) => { 34 | const opts = { ...options, block: true, line: true }; 35 | return compile(parse(input, opts), opts); 36 | }; 37 | 38 | /** 39 | * Strip only block comments. 40 | * 41 | * ```js 42 | * const strip = require('..'); 43 | * const str = strip.block('const foo = "bar";// this is a comment\n /* me too *\/'); 44 | * console.log(str); 45 | * // => 'const foo = "bar";// this is a comment' 46 | * ``` 47 | * @name .block 48 | * @param {String} `input` string from which to strip comments 49 | * @param {Object} `options` pass `opts.keepProtected: true` to keep ignored comments (e.g. `/*!`) 50 | * @return {String} modified string 51 | * @api public 52 | */ 53 | 54 | strip.block = (input, options) => { 55 | const opts = { ...options, block: true }; 56 | return compile(parse(input, opts), opts); 57 | }; 58 | 59 | /** 60 | * Strip only line comments. 61 | * 62 | * ```js 63 | * const str = strip.line('const foo = "bar";// this is a comment\n /* me too *\/'); 64 | * console.log(str); 65 | * // => 'const foo = "bar";\n/* me too *\/' 66 | * ``` 67 | * @name .line 68 | * @param {String} `input` string from which to strip comments 69 | * @param {Object} `options` pass `opts.keepProtected: true` to keep ignored comments (e.g. `//!`) 70 | * @return {String} modified string 71 | * @api public 72 | */ 73 | 74 | strip.line = (input, options) => { 75 | const opts = { ...options, line: true }; 76 | return compile(parse(input, opts), opts); 77 | }; 78 | 79 | /** 80 | * Strip the first comment from the given `input`. Or, if `opts.keepProtected` is true, 81 | * the first non-protected comment will be stripped. 82 | * 83 | * ```js 84 | * const output = strip.first(input, { keepProtected: true }); 85 | * console.log(output); 86 | * // => '//! first comment\nfoo; ' 87 | * ``` 88 | * @name .first 89 | * @param {String} `input` 90 | * @param {Object} `options` pass `opts.keepProtected: true` to keep comments with `!` 91 | * @return {String} 92 | * @api public 93 | */ 94 | 95 | strip.first = (input, options) => { 96 | const opts = { ...options, block: true, line: true, first: true }; 97 | return compile(parse(input, opts), opts); 98 | }; 99 | 100 | /** 101 | * Parses a string and returns a basic CST (Concrete Syntax Tree). 102 | * 103 | * ```js 104 | * const strip = require('..'); 105 | * const str = strip.block('const foo = "bar";// this is a comment\n /* me too *\/'); 106 | * console.log(str); 107 | * // => 'const foo = "bar";// this is a comment' 108 | * ``` 109 | * @name .block 110 | * @param {String} `input` string from which to strip comments 111 | * @param {Object} `options` pass `opts.keepProtected: true` to keep ignored comments (e.g. `/*!`) 112 | * @return {String} modified string 113 | * @api public 114 | */ 115 | 116 | strip.parse = parse; 117 | -------------------------------------------------------------------------------- /lib/Node.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class Node { 4 | constructor(node) { 5 | this.type = node.type; 6 | if (node.value) this.value = node.value; 7 | if (node.match) this.match = node.match; 8 | this.newline = node.newline || ''; 9 | } 10 | get protected() { 11 | return Boolean(this.match) && this.match[1] === '!'; 12 | } 13 | } 14 | 15 | class Block extends Node { 16 | constructor(node) { 17 | super(node); 18 | this.nodes = node.nodes || []; 19 | } 20 | push(node) { 21 | this.nodes.push(node); 22 | } 23 | get protected() { 24 | return this.nodes.length > 0 && this.nodes[0].protected === true; 25 | } 26 | } 27 | 28 | module.exports = { Node, Block }; 29 | -------------------------------------------------------------------------------- /lib/compile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const compile = (cst, options = {}) => { 4 | const keepProtected = options.safe === true || options.keepProtected === true; 5 | let firstSeen = false; 6 | 7 | const walk = (node, parent) => { 8 | let output = ''; 9 | let inner; 10 | let lines; 11 | 12 | for (const child of node.nodes) { 13 | switch (child.type) { 14 | case 'block': 15 | if (options.first && firstSeen === true) { 16 | output += walk(child, node); 17 | break; 18 | } 19 | 20 | if (options.preserveNewlines === true) { 21 | inner = walk(child, node); 22 | lines = inner.split('\n'); 23 | output += '\n'.repeat(lines.length - 1); 24 | break; 25 | } 26 | 27 | if (keepProtected === true && child.protected === true) { 28 | output += walk(child, node); 29 | break; 30 | } 31 | 32 | firstSeen = true; 33 | break; 34 | case 'line': 35 | if (options.first && firstSeen === true) { 36 | output += child.value; 37 | break; 38 | } 39 | 40 | if (keepProtected === true && child.protected === true) { 41 | output += child.value; 42 | } 43 | 44 | firstSeen = true; 45 | break; 46 | case 'open': 47 | case 'close': 48 | case 'text': 49 | case 'newline': 50 | default: { 51 | output += child.value || ''; 52 | break; 53 | } 54 | } 55 | } 56 | 57 | return output; 58 | }; 59 | 60 | return walk(cst); 61 | }; 62 | 63 | module.exports = compile; 64 | -------------------------------------------------------------------------------- /lib/languages.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.ada = { LINE_REGEX: /^--.*/ }; 4 | exports.apl = { LINE_REGEX: /^⍝.*/ }; 5 | 6 | exports.applescript = { 7 | BLOCK_OPEN_REGEX: /^\(\*/, 8 | BLOCK_CLOSE_REGEX: /^\*\)/ 9 | }; 10 | 11 | exports.csharp = { 12 | LINE_REGEX: /^\/\/.*/ 13 | }; 14 | 15 | exports.haskell = { 16 | BLOCK_OPEN_REGEX: /^\{-/, 17 | BLOCK_CLOSE_REGEX: /^-\}/, 18 | LINE_REGEX: /^--.*/ 19 | }; 20 | 21 | exports.html = { 22 | BLOCK_OPEN_REGEX: /^\n*/, 24 | BLOCK_CLOSE_LOOSE_REGEX: /^(?/, 25 | BLOCK_CLOSE_STRICT_NEWLINE_REGEX: /^(?(\s*\n+|\n*)/, 26 | BLOCK_CLOSE_STRICT_LOOSE_REGEX: /^(?(\s*\n+|\n*)/ 27 | }; 28 | 29 | exports.javascript = { 30 | BLOCK_OPEN_REGEX: /^\/\*\*?(!?)/, 31 | BLOCK_CLOSE_REGEX: /^\*\/(\n?)/, 32 | LINE_REGEX: /^\/\/(!?).*/ 33 | }; 34 | 35 | exports.lua = { 36 | BLOCK_OPEN_REGEX: /^--\[\[/, 37 | BLOCK_CLOSE_REGEX: /^\]\]/, 38 | LINE_REGEX: /^--.*/ 39 | }; 40 | 41 | exports.matlab = { 42 | BLOCK_OPEN_REGEX: /^%{/, 43 | BLOCK_CLOSE_REGEX: /^%}/, 44 | LINE_REGEX: /^%.*/ 45 | }; 46 | 47 | exports.perl = { 48 | LINE_REGEX: /^#.*/ 49 | }; 50 | 51 | exports.php = { 52 | ...exports.javascript, 53 | LINE_REGEX: /^(#|\/\/).*?(?=\?>|\n)/ 54 | }; 55 | 56 | exports.python = { 57 | BLOCK_OPEN_REGEX: /^"""/, 58 | BLOCK_CLOSE_REGEX: /^"""/, 59 | LINE_REGEX: /^#.*/ 60 | }; 61 | 62 | exports.ruby = { 63 | BLOCK_OPEN_REGEX: /^=begin/, 64 | BLOCK_CLOSE_REGEX: /^=end/, 65 | LINE_REGEX: /^#.*/ 66 | }; 67 | 68 | exports.shebang = exports.hashbang = { 69 | LINE_REGEX: /^#!.*/ 70 | }; 71 | 72 | exports.c = exports.javascript; 73 | exports.csharp = exports.javascript; 74 | exports.css = exports.javascript; 75 | exports.java = exports.javascript; 76 | exports.js = exports.javascript; 77 | exports.less = exports.javascript; 78 | exports.pascal = exports.applescript; 79 | exports.ocaml = exports.applescript; 80 | exports.sass = exports.javascript; 81 | exports.sql = exports.ada; 82 | exports.swift = exports.javascript; 83 | exports.ts = exports.javascript; 84 | exports.typscript = exports.javascript; 85 | exports.xml = exports.html; 86 | -------------------------------------------------------------------------------- /lib/parse.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { Node, Block } = require('./Node'); 4 | const languages = require('./languages'); 5 | 6 | const constants = { 7 | ESCAPED_CHAR_REGEX: /^\\./, 8 | QUOTED_STRING_REGEX: /^(['"`])((?:\\\1|[^\1])+?)(\1)/, 9 | NEWLINE_REGEX: /^\r*\n/ 10 | }; 11 | 12 | const parse = (input, options = {}) => { 13 | if (typeof input !== 'string') { 14 | throw new TypeError('Expected input to be a string'); 15 | } 16 | 17 | const cst = new Block({ type: 'root', nodes: [] }); 18 | const stack = [cst]; 19 | const name = (options.language || 'javascript').toLowerCase(); 20 | const lang = languages[name]; 21 | 22 | if (typeof lang === 'undefined') { 23 | throw new Error(`Language "${name}" is not supported by strip-comments`); 24 | } 25 | 26 | const { LINE_REGEX, BLOCK_OPEN_REGEX, BLOCK_CLOSE_REGEX } = lang; 27 | let block = cst; 28 | let remaining = input; 29 | let token; 30 | let prev; 31 | 32 | const source = [BLOCK_OPEN_REGEX, BLOCK_CLOSE_REGEX].filter(Boolean); 33 | let tripleQuotes = false; 34 | 35 | if (source.every(regex => regex.source === '^"""')) { 36 | tripleQuotes = true; 37 | } 38 | 39 | /** 40 | * Helpers 41 | */ 42 | 43 | const consume = (value = remaining[0] || '') => { 44 | remaining = remaining.slice(value.length); 45 | return value; 46 | }; 47 | 48 | const scan = (regex, type = 'text') => { 49 | const match = regex.exec(remaining); 50 | if (match) { 51 | consume(match[0]); 52 | return { type, value: match[0], match }; 53 | } 54 | }; 55 | 56 | const push = node => { 57 | if (prev && prev.type === 'text' && node.type === 'text') { 58 | prev.value += node.value; 59 | return; 60 | } 61 | block.push(node); 62 | if (node.nodes) { 63 | stack.push(node); 64 | block = node; 65 | } 66 | prev = node; 67 | }; 68 | 69 | const pop = () => { 70 | if (block.type === 'root') { 71 | throw new SyntaxError('Unclosed block comment'); 72 | } 73 | stack.pop(); 74 | block = stack[stack.length - 1]; 75 | }; 76 | 77 | /** 78 | * Parse input string 79 | */ 80 | 81 | while (remaining !== '') { 82 | // escaped characters 83 | if ((token = scan(constants.ESCAPED_CHAR_REGEX, 'text'))) { 84 | push(new Node(token)); 85 | continue; 86 | } 87 | 88 | // quoted strings 89 | if (block.type !== 'block' && (!prev || !/\w$/.test(prev.value)) && !(tripleQuotes && remaining.startsWith('"""'))) { 90 | if ((token = scan(constants.QUOTED_STRING_REGEX, 'text'))) { 91 | push(new Node(token)); 92 | continue; 93 | } 94 | } 95 | 96 | // newlines 97 | if ((token = scan(constants.NEWLINE_REGEX, 'newline'))) { 98 | push(new Node(token)); 99 | continue; 100 | } 101 | 102 | // block comment open 103 | if (BLOCK_OPEN_REGEX && options.block && !(tripleQuotes && block.type === 'block')) { 104 | if ((token = scan(BLOCK_OPEN_REGEX, 'open'))) { 105 | push(new Block({ type: 'block' })); 106 | push(new Node(token)); 107 | continue; 108 | } 109 | } 110 | 111 | // block comment close 112 | if (BLOCK_CLOSE_REGEX && block.type === 'block' && options.block) { 113 | if ((token = scan(BLOCK_CLOSE_REGEX, 'close'))) { 114 | token.newline = token.match[1] || ''; 115 | push(new Node(token)); 116 | pop(); 117 | continue; 118 | } 119 | } 120 | 121 | // line comment 122 | if (LINE_REGEX && block.type !== 'block' && options.line) { 123 | if ((token = scan(LINE_REGEX, 'line'))) { 124 | push(new Node(token)); 125 | continue; 126 | } 127 | } 128 | 129 | // Plain text (skip "C" since some languages use "C" to start comments) 130 | if ((token = scan(/^[a-zABD-Z0-9\t ]+/, 'text'))) { 131 | push(new Node(token)); 132 | continue; 133 | } 134 | 135 | push(new Node({ type: 'text', value: consume(remaining[0]) })); 136 | } 137 | 138 | return cst; 139 | }; 140 | 141 | module.exports = parse; 142 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "strip-comments", 3 | "description": "Strip line and/or block comments from a string. Blazing fast, and works with JavaScript, Sass, CSS, Less.js, and a number of other languages.", 4 | "version": "2.0.1", 5 | "homepage": "https://github.com/jonschlinkert/strip-comments", 6 | "author": "Jon Schlinkert (https://github.com/jonschlinkert)", 7 | "repository": "jonschlinkert/strip-comments", 8 | "bugs": { 9 | "url": "https://github.com/jonschlinkert/strip-comments/issues" 10 | }, 11 | "license": "MIT", 12 | "files": [ 13 | "index.js", 14 | "lib" 15 | ], 16 | "main": "index.js", 17 | "engines": { 18 | "node": ">=10" 19 | }, 20 | "scripts": { 21 | "test": "mocha", 22 | "cover": "nyc --reporter=text --reporter=html mocha" 23 | }, 24 | "devDependencies": { 25 | "gulp-format-md": "^2.0.0", 26 | "mocha": "^6.2.2", 27 | "nyc": "^14.1.1" 28 | }, 29 | "keywords": [ 30 | "ada comments", 31 | "apl comments", 32 | "applescript comments", 33 | "block comment", 34 | "block", 35 | "block-comment", 36 | "c comments", 37 | "code comment", 38 | "comment", 39 | "comments", 40 | "csharp comments", 41 | "css comments", 42 | "css", 43 | "hashbang comments", 44 | "haskell comments", 45 | "html comments", 46 | "java comments", 47 | "javascript comments", 48 | "javascript", 49 | "js", 50 | "less comments", 51 | "less css", 52 | "less", 53 | "less.js", 54 | "lessjs", 55 | "line comment", 56 | "line comments", 57 | "line", 58 | "line-comment", 59 | "line-comments", 60 | "lua comments", 61 | "matlab comments", 62 | "ocaml comments", 63 | "pascal comments", 64 | "perl comments", 65 | "php comments", 66 | "python comments", 67 | "remove", 68 | "ruby comments", 69 | "sass comments", 70 | "sass", 71 | "shebang comments", 72 | "sql comments", 73 | "strip", 74 | "swift comments", 75 | "typscript comments", 76 | "xml comments" 77 | ], 78 | "verb": { 79 | "toc": true, 80 | "layout": "default", 81 | "tasks": [ 82 | "readme" 83 | ], 84 | "plugins": [ 85 | "gulp-format-md" 86 | ], 87 | "helpers": [ 88 | "./examples/support/helpers.js" 89 | ], 90 | "related": { 91 | "list": [ 92 | "code-context", 93 | "extract-comments", 94 | "parse-code-context", 95 | "parse-comments" 96 | ] 97 | }, 98 | "lint": { 99 | "reflinks": true 100 | } 101 | } 102 | } -------------------------------------------------------------------------------- /test/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "../.eslintrc.json" 4 | ], 5 | "env": { 6 | "mocha": true 7 | } 8 | } -------------------------------------------------------------------------------- /test/HTML.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * strip-comments 3 | * 4 | * Copyright (c) 2014-2018, Jon Schlinkert. 5 | * Released under the MIT license. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const fs = require('fs'); 11 | const path = require('path'); 12 | const assert = require('assert'); 13 | const strip = require('../index'); 14 | 15 | const fixture = path.join.bind(path, __dirname, 'fixtures/html'); 16 | const expected = path.join.bind(path, __dirname, 'expected/html'); 17 | const read = src => fs.readFileSync(src, 'utf-8').replace(/\r*\n/g, '\n'); 18 | 19 | describe('HTML comments', () => { 20 | it('should strip HTML comments.', () => { 21 | const actual = strip('No comment', { language: 'html' }); 22 | assert.strictEqual(actual, 'No comment'); 23 | }); 24 | 25 | it('should not strip comments inside quoted strings.', () => { 26 | const input = 'No ""comment'; 27 | const actual = strip(input, { language: 'html' }); 28 | assert.strictEqual(actual, input); 29 | }); 30 | 31 | it('should not strip comment _parts_ inside quoted strings.', () => { 32 | const name = 'quoted'; 33 | const input = read(fixture(`${name}.html`)); 34 | const output = read(expected(`${name}.html`)); 35 | const actual = strip(input, { language: 'html' }); 36 | assert.strictEqual(actual, output); 37 | }); 38 | 39 | it('should strip multiline comments', () => { 40 | const name = 'multiline'; 41 | const input = read(fixture(`${name}.html`)); 42 | const output = read(expected(`${name}.html`)); 43 | const actual = strip(input, { language: 'html' }); 44 | assert.strictEqual(actual, output); 45 | }); 46 | 47 | it('should strip comments with only dashes', () => { 48 | const name = 'dashes'; 49 | const input = read(fixture(`${name}.html`)); 50 | const output = read(expected(`${name}.html`)); 51 | const actual = strip(input, { language: 'html' }); 52 | assert.strictEqual(actual, output); 53 | }); 54 | }); 55 | -------------------------------------------------------------------------------- /test/JavaScript.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * strip-comments 3 | * 4 | * Copyright (c) 2014-2018, Jon Schlinkert. 5 | * Released under the MIT license. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const fs = require('fs'); 11 | const path = require('path'); 12 | const assert = require('assert'); 13 | const strip = require('../index'); 14 | 15 | const tests = path.join.bind(path, __dirname); 16 | const read = src => fs.readFileSync(src, 'utf-8').replace(/\r*\n/g, '\n');; 17 | 18 | describe('JavaScript comments', () => { 19 | it('should strip all comments', () => { 20 | const actual = strip("'foo'; // this is a comment\n/* me too */ var abc = 'xyz';"); 21 | assert.strictEqual(actual, '\'foo\'; \n var abc = \'xyz\';'); 22 | }); 23 | 24 | it('should work on unclosed (invalid) blocks', () => { 25 | const actual = strip("'foo'; /* I am invalid "); 26 | assert.strictEqual(actual, '\'foo\'; '); 27 | }); 28 | 29 | it('should strip line comments', () => { 30 | const actual = strip.line('foo // this is a comment\n/* me too */'); 31 | const expected = 'foo \n/* me too */'; 32 | assert.strictEqual(actual, expected); 33 | }); 34 | 35 | it('should not mistake escaped slashes for comments', () => { 36 | // see https://github.com/jonschlinkert/extract-comments/issues/12 37 | const expected = "'foo/bar'.replace(/o\\//, 'g')"; 38 | const actual = strip.line(expected); 39 | assert.deepEqual(actual, expected); 40 | }); 41 | 42 | it('should strip block comments', () => { 43 | const actual = strip.block('foo // this is a comment\n/* me too */'); 44 | const expected = 'foo // this is a comment\n'; 45 | assert.strictEqual(actual, expected); 46 | }); 47 | 48 | // see https://github.com/jonschlinkert/strip-comments/issues/31 49 | it('should only strip the first comment', () => { 50 | const expected = read(tests('expected/banner.js')); 51 | const fixture = read(tests('fixtures/banner.js')); 52 | const actual = strip.first(fixture); 53 | assert.strictEqual(actual, expected); 54 | }); 55 | 56 | // see https://github.com/jonschlinkert/strip-comments/issues/31 57 | it('should strip the first non-protected comment', () => { 58 | const expected = read(tests('expected/banner-protected.js')); 59 | const fixture = read(tests('fixtures/banner.js')); 60 | const actual = strip.first(fixture, { keepProtected: true }); 61 | assert.strictEqual(actual, expected); 62 | }); 63 | 64 | // see https://github.com/jonschlinkert/strip-comments/issues/21 65 | it('should not strip non-comments in quoted strings 2', () => { 66 | const expected = read(tests('fixtures/quoted-strings.js')); 67 | const actual = strip(expected); 68 | assert.equal(actual, expected); 69 | }); 70 | 71 | // see https://github.com/jonschlinkert/strip-comments/issues/18 72 | it('should not hang on unclosed comments', () => { 73 | const expected = 'if (accept == \'video/*\') {'; 74 | const actual = strip(expected); 75 | // fails because using `esprima` under the hood 76 | assert.equal(actual, expected); 77 | }); 78 | 79 | it('should not mangle json', () => { 80 | const expected = read(path.join(__dirname, '..', 'package.json')); 81 | const before = JSON.parse(expected); 82 | const res = strip(expected); 83 | const after = JSON.parse(res); 84 | assert.deepEqual(before, after); 85 | }); 86 | 87 | it('should strip all but not `/*/`', () => { 88 | const actual = strip("/* I will be stripped */\nvar path = '/this/should/*/not/be/stripped';"); 89 | const expected = "var path = '/this/should/*/not/be/stripped';"; 90 | assert.strictEqual(actual, expected); 91 | }); 92 | 93 | it('should strip all but not globstars `/**/*` #1', () => { 94 | const actual = strip("var path = './do/not/strip/globs/**/*.js';"); 95 | const expected = "var path = './do/not/strip/globs/**/*.js';"; 96 | assert.strictEqual(actual, expected); 97 | }); 98 | 99 | it('should strip all but not globstars `/**/` #2 and `//!` line comments (safe: true)', () => { 100 | const actual = strip('var partPath = \'./path/*/to/scripts/**/\'; //! line comment', { safe: true }); 101 | const expected = 'var partPath = \'./path/*/to/scripts/**/\'; //! line comment'; 102 | assert.strictEqual(actual, expected); 103 | }); 104 | 105 | it('should strip all but not `/*/*something` from anywhere', () => { 106 | const actual = strip('var partPath = \'./path/*/*something/test.txt\';'); 107 | const expected = 'var partPath = \'./path/*/*something/test.txt\';'; 108 | assert.strictEqual(actual, expected); 109 | }); 110 | 111 | it('should strip all but not `/*/*something/*.js` from anywhere (globstar-like)', () => { 112 | const actual = strip('var partPath = \'./path/*/*something/*.js\';'); 113 | const expected = "var partPath = './path/*/*something/*.js';"; 114 | assert.strictEqual(actual, expected); 115 | }); 116 | 117 | it('should leave alone code without any comments', () => { 118 | const fixture = read(tests('fixtures/no-comment.js')); 119 | const actual = strip(fixture); 120 | const expected = fixture; 121 | assert.strictEqual(actual, expected); 122 | }); 123 | 124 | // see https://github.com/jonschlinkert/strip-comments/issues/27 125 | it('should not break on comments that are substrings of a later comment', () => { 126 | const actual = strip([ 127 | '// this is a substring', 128 | '// this is a substring of a larger comment', 129 | 'someCode();', 130 | 'someMoreCode();' 131 | ].join('\n')); 132 | const expected = [ 133 | '', 134 | '', 135 | 'someCode();', 136 | 'someMoreCode();' 137 | ].join('\n'); 138 | assert.strictEqual(actual, expected); 139 | }); 140 | }); 141 | 142 | describe('error handling:', () => { 143 | it('should throw TypeError when a string is not passed', () => { 144 | const fixture = () => strip(123); 145 | assert.throws(fixture, TypeError); 146 | assert.throws(fixture, /expected input to be a string/i); 147 | }); 148 | 149 | it('should throw TypeError when a string is not passed to `.block`', () => { 150 | const fixture = () => strip.block(123); 151 | assert.throws(fixture, TypeError); 152 | assert.throws(fixture, /expected input to be a string/i); 153 | }); 154 | 155 | it('should throw TypeError when a string is not passed to `.line`', () => { 156 | const fixture = () => strip.line(123); 157 | assert.throws(fixture, TypeError); 158 | assert.throws(fixture, /expected input to be a string/i); 159 | }); 160 | 161 | it('should not throw on empty string, returns empty string', () => { 162 | const actual = strip(''); 163 | const expected = ''; 164 | assert.strictEqual(typeof actual, 'string'); 165 | assert.strictEqual(actual, expected, 'expect empty string on empty string passed'); 166 | }); 167 | }); 168 | 169 | describe('strip all or empty:', () => { 170 | it('should strip all multiline, singleline, block and line comments', () => { 171 | const fixture = read(tests('fixtures/strip-all.js')); 172 | const expected = read(tests('expected/strip-all.js')); 173 | const actual = strip(fixture); 174 | assert.strictEqual(actual, expected); 175 | }); 176 | 177 | it('should not strip !important block comments', () => { 178 | const fixture = read(tests('fixtures/strip-all.js')); 179 | const actual = strip.block(fixture, { safe: true }); 180 | const expected = read(tests('expected/strip-keep-block.js')); 181 | assert.strictEqual(actual, expected); 182 | }); 183 | 184 | it('should strip only all line comments that not starts with `//!` (safe:true)', () => { 185 | const fixture = read(tests('fixtures/strip-keep-line.js')); 186 | const actual = strip.line(fixture, { safe: true }); 187 | const expected = read(tests('expected/strip-keep-line.js')); 188 | assert.strictEqual(actual, expected); 189 | }); 190 | }); 191 | 192 | describe('strip all keep newlines:', () => { 193 | it('should strip all comments, but keep newlines', () => { 194 | const fixture = read(tests('fixtures/strip-all.js')); 195 | const expected = read(tests('expected/strip-keep-newlines.js')); 196 | const actual = strip(fixture, { preserveNewlines: true }); 197 | assert.strictEqual(actual, expected); 198 | }); 199 | }); 200 | 201 | describe('block comments:', () => { 202 | it('should strip block comments from a function', () => { 203 | const actual = strip.block('var bar = function(/* this is a comment*/) {return;};'); 204 | const expected = 'var bar = function() {return;};'; 205 | assert.strictEqual(actual, expected); 206 | }); 207 | 208 | it('should strip block comments before and from a function', () => { 209 | const actual = strip.block('/* this is a comment */\nvar bar = function(/*this is a comment*/) {return;};'); 210 | const expected = 'var bar = function() {return;};'; 211 | assert.strictEqual(actual, expected); 212 | }); 213 | 214 | it('should strip block comments before, after and from a function', () => { 215 | const actual = strip.block('/* this is a comment */var bar = function(/*this is a comment*/) {return;};\n/* this is a comment*/'); 216 | const expected = 'var bar = function() {return;};\n'; 217 | assert.strictEqual(actual, expected); 218 | }); 219 | }); 220 | 221 | describe('line comments:', () => { 222 | it('should strip line comments', () => { 223 | const actual = strip.line('// this is a line comment\nvar bar = function(/*this is a comment*/) {return;};'); 224 | const expected = '\nvar bar = function(/*this is a comment*/) {return;};'; 225 | assert.strictEqual(actual, expected); 226 | }); 227 | 228 | it('should strip line comments with leading whitespace', () => { 229 | const actual = strip.line(' // this should be stripped'); 230 | const expected = ' '; 231 | assert.strictEqual(actual, expected); 232 | }); 233 | 234 | it('should not strip line comments in quoted strings', () => { 235 | const actual = strip.line('var foo = "//this is not a comment";'); 236 | const expected = 'var foo = "//this is not a comment";'; 237 | assert.strictEqual(actual, expected); 238 | }); 239 | 240 | it('should strip line comments after quoted strings', () => { 241 | const actual = strip.line('var foo = "//this is not a comment"; //this should be stripped'); 242 | const expected = 'var foo = "//this is not a comment"; '; 243 | assert.strictEqual(actual, expected); 244 | }); 245 | 246 | it('should not be whitespace sensitive', () => { 247 | const actual = strip.line('var foo = "//this is not a comment"; // this should be stripped'); 248 | const expected = 'var foo = "//this is not a comment"; '; 249 | assert.strictEqual(actual, expected); 250 | }); 251 | 252 | it('should not strip URLs in a quoted string', () => { 253 | const actual = strip.line('var foo = "http://github.com"; // this should be stripped'); 254 | const expected = 'var foo = "http://github.com"; '; 255 | assert.strictEqual(actual, expected); 256 | }); 257 | 258 | it('should strip URLs in a line comment', () => { 259 | const actual = strip.line('// http://github.com"'); 260 | const expected = ''; 261 | assert.strictEqual(actual, expected); 262 | }); 263 | 264 | it('should strip URLs in a block comment', () => { 265 | const actual = strip.block('/**\n* http://github.com\n *\n */'); 266 | const expected = ''; 267 | assert.strictEqual(actual, expected); 268 | }); 269 | 270 | it('should strip line comments before a function, and not block comments', () => { 271 | const actual = strip.line('/* this is a comment */\n//this is a comment\nvar bar = function(/*this is a comment*/) {return;};'); 272 | const expected = '/* this is a comment */\n\nvar bar = function(/*this is a comment*/) {return;};'; 273 | assert.strictEqual(actual, expected); 274 | }); 275 | 276 | it('should strip line comments before and after a function, and not block comments', () => { 277 | const actual = strip.line('/* this is a comment */\n//this is a comment\nvar bar = function(/*this is a comment*/) {return;};\n//this is a line comment'); 278 | const expected = '/* this is a comment */\n\nvar bar = function(/*this is a comment*/) {return;};\n'; 279 | assert.strictEqual(actual, expected); 280 | }); 281 | }); 282 | 283 | describe('performance', () => { 284 | it('should not timeout', () => { 285 | const actual = strip(` 286 | console.log(tpl\` 287 | 123 288 | \`); 289 | ${Array(10).fill('console.log(/^http:\\/\\//.test("1"));').join('\n')}\n 290 | ${Array(100).fill('console.log("1");').join('\n')}\n 291 | `); 292 | const expected = actual; 293 | assert.strictEqual(actual, expected); 294 | }).timeout(500) 295 | }); 296 | -------------------------------------------------------------------------------- /test/expected/banner-protected.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * update-banner 3 | * 4 | * Copyright (c) 2015, Jon Schlinkert. 5 | * Licensed under the MIT License. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | 11 | function someFunction() { 12 | // body... 13 | } -------------------------------------------------------------------------------- /test/expected/banner.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | /** 5 | * Another comment 6 | */ 7 | 8 | function someFunction() { 9 | // body... 10 | } -------------------------------------------------------------------------------- /test/expected/html/dashes.html: -------------------------------------------------------------------------------- 1 | All 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | Gone 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /test/expected/html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Document 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /test/expected/html/multiline.html: -------------------------------------------------------------------------------- 1 |

text

2 | 3 |

More text

4 | 5 | -------------------------------------------------------------------------------- /test/expected/html/quoted.html: -------------------------------------------------------------------------------- 1 | 12.1.6 Comments 2 | Comments must have the following format: 3 | 4 | The string "", or "--!>", nor end with the string "". 7 | 8 | The text is allowed to end with the string " 17 | 18 | 4.6 Block comments 19 | Block comments are typically found within functions, between 'chunks' of code. They also appear in other parts of code, for example at the start of chunks of data. There are a number of common approaches to block comments, several of which are discussed below. 20 | 21 | 4.6.1 Comment size 22 | There are about three different classifications of block comment, depending on its size: 23 | 24 | A single line comment will commonly describe a simple item. 25 | A multiple line comment, up to about 5 lines will summarize a more complex item or set of items. 26 | A longer comment will describe even more, although this is now tending towards a major header comment. 27 | Generally, it must be remembered that a block comment has a cost in vertical space and should give value for money. For example, it may be overkill for a block comment to be bigger than the chunk of function code that it describes. 28 | 29 | 4.6.2 Positioning the comment 30 | A block comment usually describes code below it. This association can be made clearer by using some method to explicitly associate it more closely with the code that it describes. 31 | 32 | Using blank lines 33 | A simple principle is to use a blank line above the comment to physically place it closer to the line below than the line above: 34 | 35 | 36 | 37 | ResetParms(); 38 | 39 | 40 | for ( Win = 0; Win < NofWins; Win++ ) 41 | CloseWin( Win ); 42 | 43 | 44 | 45 | This, however, causes a possible problem where the comment and the code are not immediately distiguishable. A solution, at the cost of more vertical space, is to put a blank line below the comment: 46 | 47 | 48 | 49 | ResetParms(); 50 | 51 | 52 | 53 | for ( Win = 0; Win < NofWins; Win++ ) 54 | CloseWin( Win ); 55 | 56 | 57 | 58 | Indenting the comment 59 | A common method of positioning is to vertically align the comment with the current indent level. This helps to associate the comment with the code below, and preserves the line of indentation. However, this reduces the amount of horizontal space available for comment, particularly at deeper levels of nesting, and may make it more difficult to distinguish between comments and code: 60 | 61 | 62 | 63 | ResetParms(); 64 | 65 | 66 | for ( Win = 0; Win < NofWins; Win++ ) 67 | CloseWin( Win ); 68 | 69 | 70 | 71 | 4.6.3 Enclosing the comment 72 | When block comments cover multiple lines, it is only necessary to use the opening and closing comment tokens. This, however, can result in the limits of the comment becoming less than immediately obvious: 73 | 74 | 75 | 76 | 77 | 78 | 79 | CheckNodes( DB_Nodes ); 80 | 81 | 82 | 83 | A simple principle that can be used in most cases to clarify the limits of multi-line comments, is to put the closing '*/' directly under the opening '*/' (in a similar manner to braces). 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | CheckNodes( DB_Nodes ); 92 | 93 | 94 | 95 | However, reading each line from the left, it is still not immediately clear which line is a comment and which line is not, particularly if the comment is long, and contains blank lines. 96 | 97 | Enclosing from the left 98 | In the previous example, you can clearly delimit the comment one line at a time by making the first character that is read an asterisk. This is using the principle of explicitness to say each time, "This is a comment. It is not code." 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | CheckNodes( DB_Nodes ); 107 | 108 | 109 | 110 | There are several common variant on this, such as putting the opening '/*' on a line by itself, thus ensuring an almost-blank line before the comment and enabling easier line insertion after it. Also, the asterisk may be always put in column two or two asterisks can be used on text lines, to emphasize the comment and to be tidy in having two comment characters per line. Some horizontal space can be saved by using spaces instead of tabs to separate the text from the asterisk: 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | CheckNodes( DB_Nodes ); 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | Enclosing from above 128 | An alternative or an addition to white space as a method of distinguishing comments from code is to put a bar above the comment, but not below it. This dissociates the comment from the code above, whilst emphasizing its association with the code below. 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | CheckNodes( DB_Nodes ); 138 | 139 | 140 | 141 | Enclosing from below 142 | The comment can be dissociated more from the code below by putting a bar below it too. It is being tidy to keep it the same length as the top line. The dissociation can be further emphasized with a blank line between the comment and the code: 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | CheckNodes( DB_Nodes ); 153 | 154 | 155 | 156 | Note that the final '*/' is no longer below the opening '/*'. This is not so important as the limits of the comment block are very clear, although there is a danger of missing the final '/', resulting in the code below being commented out. 157 | 158 | A status comment, which describes the code above it, can be enclosed at the bottom, but not the top, to emphasize its association. 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | Enclosing from the right 171 | The final step is now to tidily fill in the right hand side of the box, although this may be considered to be more trouble than it is worth, as it makes editing the comment text less easy. 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | A simplification of the rules about where to place the '/*' and '*/' tokens is to insist that all comments should have matching tokens on the same line. Thus all comment lines are automatically enclosed from the right and the left. 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | With this rule, enclosure from the top and bottom may still be optional. The right hand margin may stay justified or may collapse to a ragged right margin, which eases editing but is not as tidy: 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 4.6.4 Delimiters 206 | Comments need not be used for text comments: they may also be used to separate out distinct pieces of code. 207 | 208 | Separating chunks 209 | Drawing lines across the page not only separates the code from the comment, but also separates individual chunks of code, making the chunks easier to see and understand. As these are effectively single-line block comments, they can include simple comments: 210 | 211 | 212 | 213 | 214 | 215 | for ( FileNo = 0; FileNo < NofFilesOpen; FileNo++ ) 216 | { 217 | ErrNo = CloseFile( FileHandle[FileNo] ); 218 | if ( ErrNo != 0 ) 219 | { 220 | FileError( ErrNo ); 221 | } 222 | } 223 | 224 | 225 | 226 | printf( "System closing down,\n" ); 227 | printf( "Remove all tapes and secure in safe.\n"); 228 | 229 | 230 | ... 231 | 232 | 233 | 234 | Multi-line block comments can also a similar scheme, whereby the text in the line is an effective summary for the comment block. 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | ----------------------------------------------------------------------> 244 | 245 | Data/Code delimiters 246 | It can be difficult to immediately find the beginning of the code at the start of a function. For example, a reader might miss the first statement (which may be mistaken for a data declaration). 247 | 248 | 249 | 250 | int 251 | ReadDoorStatus( S_DOOR *Door ) 252 | 253 | { 254 | int DoorType; 255 | int LockType; 256 | DoorType = WOOD; 257 | 258 | LockType = Door->Lock; <------ reader may read code from here! 259 | 260 | 261 | 262 | However, if we put a line across at the start of the data and code sections, no mistakes may be made, and the start of the data and code sections can instantly be found. 263 | 264 | 265 | 266 | int 267 | ReadDoorStatus( S_DOOR *Door ) 268 | 269 | { 270 | 271 | 272 | int DoorType; 273 | int LockType; 274 | 275 | 276 | 277 | DoorType = WOOD; 278 | LockType = Door->Lock; 279 | 280 | 281 | 282 | Delimiter 'weight' 283 | The 'weight' of the delimiter can be used to indicate importance of the section of code or data that is being delimited. The symbols used may be for single line delimiters, or to bound multi-line comment blocks. 284 | 285 | A simple scheme would be: 286 | 287 | Asterisks () Major sections, eg. functions, data areas. 288 | 289 | Equals () Major sub-sections 290 | 291 | Minus () Minor sub-sections 292 | 293 | e.g. 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | -------------------------------------------------------------------------------- /test/expected/other/haskell.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | putStrLn "Wikipedia" 4 | -------------------------------------------------------------------------------- /test/expected/other/lua.txt: -------------------------------------------------------------------------------- 1 | Lua 2 | The Lua programming language uses double-hyphens, `--`, for single line comments in a similar way to Ada, Eiffel, Haskell, SQL and VHDL languages. Lua also has block comments, which start with `--[[` and run until a closing `]]` 3 | 4 | For example: 5 | 6 | 7 | print(20) 8 | A common technique to comment out a piece of code,[44] is to enclose the code between `--[[` and `--]]`, as below: 9 | 10 | 11 | 12 | In this case, it's possible to reactivate the code by adding a single hyphen to the first line: 13 | 14 | 15 | print(10) 16 | 17 | 18 | In the first example, the `--[[` in the first line starts a long comment, and the two hyphens in the last line are still inside that comment. In the second example, the sequence `---[[` starts an ordinary, single-line comment, so that the first and the last lines become independent comments. In this case, the print is outside comments. In this case, the last line becomes an independent comment, as it starts with `--`. 19 | 20 | Long comments in Lua can be more complex than these, as you can read in the section called "Long strings" c.f. Programming in Lua. 21 | -------------------------------------------------------------------------------- /test/expected/other/matlab.txt: -------------------------------------------------------------------------------- 1 | MATLAB 2 | In MATLAB's programming language, the '%' character indicates a single-line comment. Multi line comments are also available via `%{` and `%}` brackets and can be nested, e.g. 3 | 4 | 5 | d = [0 -1 0]; 6 | 7 | 8 | seq = d .* (x - c).^n ./(factorial(n)) 9 | 10 | 11 | approx = sum(seq) 12 | -------------------------------------------------------------------------------- /test/expected/other/ocaml.txt: -------------------------------------------------------------------------------- 1 | OCaml 2 | OCaml uses nestable comments, which is useful when commenting a code block. 3 | 4 | codeLine 5 | -------------------------------------------------------------------------------- /test/expected/other/pascal.txt: -------------------------------------------------------------------------------- 1 | 2 | columnDifference := testColumn - column; 3 | if (row + columnDifference = testRow) or 4 | ....... 5 | -------------------------------------------------------------------------------- /test/expected/other/perl.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | my $s = "Wikipedia"; 4 | print $s . "\n"; 5 | -------------------------------------------------------------------------------- /test/expected/other/php.txt: -------------------------------------------------------------------------------- 1 | PHP supports 'C', 'C++' and Unix shell-style (Perl style) comments. For example: 2 | 3 | 8 | The "one-line" comment styles only comment to the end of the line or the current block of PHP code, whichever comes first. This means that HTML code after `// ... ?>` or `# ... ?>` WILL be printed: ?> breaks out of PHP mode and returns to HTML mode, and `//` or `#` cannot influence that. If the asp_tags configuration directive is enabled, it behaves the same with `// %>` and `# %>`. However, the tag doesn't break out of PHP mode in a one-line comment. 9 | 10 |

This is an example

11 |

The header above will say 'This is an example'.

12 | 'C' style comments end at the first `*/` encountered. Make sure you don't nest 'C' style comments. It is easy to make this mistake if you are trying to comment out a large block of code. 13 | 14 | 16 | -------------------------------------------------------------------------------- /test/expected/other/python.txt: -------------------------------------------------------------------------------- 1 | Python 2 | Inline comments in Python use the hash ('#') character, as in the two examples in this code: 3 | 4 | 5 | print("Hello World!") 6 | Block comments, as defined in this article, don't technically exist in Python.[49] A bare string literal represented by a triple-quoted string can be used[50] but is not ignored by the interpreter in the same way that "#" comment is. In the examples below, the triple double-quoted strings act in this way as comments, but are also treated as docstrings: 7 | 8 | 9 | 10 | class MyClass(object): 11 | 12 | 13 | def my_method(self): 14 | 15 | 16 | def my_function(): 17 | 18 | -------------------------------------------------------------------------------- /test/expected/other/ruby.txt: -------------------------------------------------------------------------------- 1 | Ruby 2 | Comments in Ruby. 3 | 4 | Single line commenting: (line starts with hash "#") 5 | 6 | puts "This is not a comment" 7 | 8 | 9 | 10 | puts "This is not a comment" 11 | Multi-line commenting: (comments goes between keywords "begin" and "end") 12 | 13 | puts "This is not a comment" 14 | 15 | 16 | 17 | puts "This is not a comment" 18 | -------------------------------------------------------------------------------- /test/expected/other/shebang.txt: -------------------------------------------------------------------------------- 1 | 2 | Hello world! 3 | -------------------------------------------------------------------------------- /test/expected/other/sql.txt: -------------------------------------------------------------------------------- 1 | SQL 2 | Comments in SQL are in single-line-only form, when using two dashes: 3 | 4 | 5 | 6 | SELECT COUNT(*) 7 | FROM Authors 8 | WHERE Authors.name = 'Smith'; 9 | 10 | -------------------------------------------------------------------------------- /test/expected/other/swift.txt: -------------------------------------------------------------------------------- 1 | Swift 2 | Single-line comments begin with two forward-slashes (`//`): 3 | 4 | 5 | Multiline comments start with a forward-slash followed by an asterisk (`/*`) and end with an asterisk followed by a forward-slash (`*/`): 6 | 7 | Multiline comments in Swift can be nested inside other multiline comments. You write nested comments by starting a multiline comment block and then starting a second multiline comment within the first block. The second block is then closed, followed by the first block: 8 | 9 | -------------------------------------------------------------------------------- /test/expected/strip-all.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var foo = function() {}; 4 | 5 | var bar = function() {}; 6 | 7 | var baz = '//bar baz not a comment'; 8 | 9 | 10 | var qux = function() { 11 | 12 | 13 | var some = true; 14 | 15 | var fafa = true; 16 | 17 | var but = 'not'; 18 | }; 19 | 20 | 21 | 22 | var fun = false; 23 | var path = '/path/to/*/something/that/not/be/stripped.js'; 24 | var globstar = '/path//to//globstar/not/be/stripped/**/*.js'; -------------------------------------------------------------------------------- /test/expected/strip-keep-block.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * strip this multiline 3 | * block comment 4 | */ 5 | 'use strict'; 6 | 7 | /**! 8 | * and this multiline 9 | * block comment 10 | */ 11 | var foo = function() {}; 12 | 13 | var bar = function() {}; 14 | 15 | var baz = '//bar baz not a comment'; 16 | 17 | // this single-line line comment 18 | var qux = function() { 19 | // this multiline 20 | // line comment 21 | var some = true; 22 | //this 23 | var fafa = true; //and this 24 | // var also = 'that'; 25 | var but = 'not'; //! that comment 26 | }; 27 | 28 | // also this multiline 29 | // line comment 30 | var fun = false; 31 | var path = '/path/to/*/something/that/not/be/stripped.js'; 32 | var globstar = '/path//to//globstar/not/be/stripped/**/*.js'; -------------------------------------------------------------------------------- /test/expected/strip-keep-line.js: -------------------------------------------------------------------------------- 1 | /** 2 | * this block comment 3 | * will not be striped 4 | */ 5 | 6 | 'use strict'; 7 | 8 | //! and this multiline 9 | //! block comment 10 | var foo = function(/* and these single-line block comment */) {}; 11 | 12 | /** 13 | * and this 14 | * multiline block 15 | * comment 16 | */ 17 | var bar = function(/* and that */) {}; 18 | 19 | 20 | var baz = function() { 21 | 22 | 23 | var some = true; 24 | 25 | var fafa = true; 26 | 27 | var but = 'not'; //! that comment 28 | }; 29 | 30 | var path = '/path/to/*/something/that/not/be/stripped.js'; 31 | var globstar = '/path/to/globstar/not/be/stripped/**/*.js'; 32 | -------------------------------------------------------------------------------- /test/expected/strip-keep-newlines.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 'use strict'; 6 | 7 | 8 | 9 | 10 | 11 | var foo = function() {}; 12 | 13 | 14 | 15 | 16 | 17 | 18 | var bar = function() {}; 19 | 20 | var baz = '//bar baz not a comment'; 21 | 22 | 23 | var qux = function() { 24 | 25 | 26 | var some = true; 27 | 28 | var fafa = true; 29 | 30 | var but = 'not'; 31 | }; 32 | 33 | 34 | 35 | var fun = false; 36 | var path = '/path/to/*/something/that/not/be/stripped.js'; 37 | var globstar = '/path//to//globstar/not/be/stripped/**/*.js'; -------------------------------------------------------------------------------- /test/fixtures/banner.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * update-banner 3 | * 4 | * Copyright (c) 2015, Jon Schlinkert. 5 | * Licensed under the MIT License. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | /** 11 | * Another comment 12 | */ 13 | 14 | function someFunction() { 15 | // body... 16 | } -------------------------------------------------------------------------------- /test/fixtures/html/dashes.html: -------------------------------------------------------------------------------- 1 | All 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | Gone 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /test/fixtures/html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Document 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /test/fixtures/html/multiline.html: -------------------------------------------------------------------------------- 1 |

text

2 | 7 |

More text

8 | 13 | -------------------------------------------------------------------------------- /test/fixtures/html/quoted.html: -------------------------------------------------------------------------------- 1 | 12.1.6 Comments 2 | Comments must have the following format: 3 | 4 | The string "", or "--!>", nor end with the string "". 7 | 8 | The text is allowed to end with the string " and . 9 | -------------------------------------------------------------------------------- /test/fixtures/line.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | // ------------------------- 3 | // This is the comment body. 4 | // ------------------------- 5 | const foo = 'bar'; // another line 6 | -------------------------------------------------------------------------------- /test/fixtures/no-comment.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | process.stdout.write('string literals: '); 4 | console.dir({ 5 | str0: ''', 6 | str1: """, 7 | str2: ". // ' \\ . // ' \\ .", 8 | }); 9 | 10 | process.stdout.write('RegExp literals: '); 11 | console.dir({ 12 | regexp0: /I'm the easiest in Chomsky hierarchy!/, 13 | }); 14 | -------------------------------------------------------------------------------- /test/fixtures/other/AppleScript.txt: -------------------------------------------------------------------------------- 1 | (* test diagonals *) 2 | columnDifference := testColumn - column; 3 | if (row + columnDifference = testRow) or 4 | ....... 5 | -------------------------------------------------------------------------------- /test/fixtures/other/ada.txt: -------------------------------------------------------------------------------- 1 | Ada 2 | The Ada programming language uses '--' to indicate a comment up to the end of the line. 3 | 4 | For example: 5 | 6 | -- the air traffic controller task takes requests for takeoff and landing 7 | task type Controller (My_Runway: Runway_Access) is 8 | -- task entries for synchronous message passing 9 | entry Request_Takeoff (ID: in Airplane_ID; Takeoff: out Runway_Access); 10 | entry Request_Approach(ID: in Airplane_ID; Approach: out Runway_Access); 11 | end Controller; 12 | -------------------------------------------------------------------------------- /test/fixtures/other/apl.txt: -------------------------------------------------------------------------------- 1 | ⍝ Now add the numbers: 2 | c←a+b ⍝ addition 3 | -------------------------------------------------------------------------------- /test/fixtures/other/c.txt: -------------------------------------------------------------------------------- 1 | CHAPTER 4 : Commenting 2 | PART 2 : COMMENTING AND NAMING 3 | 4 | CHAPTER 4 : Commenting 5 | 4.1 Commenting fundamentals 6 | 4.2 Comment types 7 | 4.3 Header comments 8 | 4.4 File Header comment 9 | 4.5 Function header comments 10 | 4.6 Block comments 11 | 4.7 Trailing comments 12 | 4.8 Commenting data 13 | 4.9 The preprocessor and comments 14 | 4.10 Summary 15 | 16 | <--Prev page | Next page --> 17 | 18 | 4.6 Block comments 19 | Block comments are typically found within functions, between 'chunks' of code. They also appear in other parts of code, for example at the start of chunks of data. There are a number of common approaches to block comments, several of which are discussed below. 20 | 21 | 4.6.1 Comment size 22 | There are about three different classifications of block comment, depending on its size: 23 | 24 | A single line comment will commonly describe a simple item. 25 | A multiple line comment, up to about 5 lines will summarize a more complex item or set of items. 26 | A longer comment will describe even more, although this is now tending towards a major header comment. 27 | Generally, it must be remembered that a block comment has a cost in vertical space and should give value for money. For example, it may be overkill for a block comment to be bigger than the chunk of function code that it describes. 28 | 29 | 4.6.2 Positioning the comment 30 | A block comment usually describes code below it. This association can be made clearer by using some method to explicitly associate it more closely with the code that it describes. 31 | 32 | Using blank lines 33 | A simple principle is to use a blank line above the comment to physically place it closer to the line below than the line above: 34 | 35 | 36 | 37 | ResetParms(); 38 | 39 | /* Close all remaining open windows */ 40 | for ( Win = 0; Win < NofWins; Win++ ) 41 | CloseWin( Win ); 42 | 43 | 44 | 45 | This, however, causes a possible problem where the comment and the code are not immediately distiguishable. A solution, at the cost of more vertical space, is to put a blank line below the comment: 46 | 47 | 48 | 49 | ResetParms(); 50 | 51 | /* Close all remaining open windows */ 52 | 53 | for ( Win = 0; Win < NofWins; Win++ ) 54 | CloseWin( Win ); 55 | 56 | 57 | 58 | Indenting the comment 59 | A common method of positioning is to vertically align the comment with the current indent level. This helps to associate the comment with the code below, and preserves the line of indentation. However, this reduces the amount of horizontal space available for comment, particularly at deeper levels of nesting, and may make it more difficult to distinguish between comments and code: 60 | 61 | 62 | 63 | ResetParms(); 64 | 65 | /* Close all remaining open windows */ 66 | for ( Win = 0; Win < NofWins; Win++ ) 67 | CloseWin( Win ); 68 | 69 | 70 | 71 | 4.6.3 Enclosing the comment 72 | When block comments cover multiple lines, it is only necessary to use the opening and closing comment tokens. This, however, can result in the limits of the comment becoming less than immediately obvious: 73 | 74 | 75 | 76 | /* Check for all corrupt nodes and add these to the 77 | Bad Data list. Any clear nodes found are added to the 78 | Free Data list. */ 79 | CheckNodes( DB_Nodes ); 80 | 81 | 82 | 83 | A simple principle that can be used in most cases to clarify the limits of multi-line comments, is to put the closing '*/' directly under the opening '*/' (in a similar manner to braces). 84 | 85 | 86 | 87 | /* Check for all corrupt nodes and add these to the 88 | Bad Data list. Any clear nodes found are added to the 89 | Free Data list. 90 | */ 91 | CheckNodes( DB_Nodes ); 92 | 93 | 94 | 95 | However, reading each line from the left, it is still not immediately clear which line is a comment and which line is not, particularly if the comment is long, and contains blank lines. 96 | 97 | Enclosing from the left 98 | In the previous example, you can clearly delimit the comment one line at a time by making the first character that is read an asterisk. This is using the principle of explicitness to say each time, "This is a comment. It is not code." 99 | 100 | 101 | 102 | /* Check for all corrupt nodes and add these to the 103 | * Bad Data list. Any clear nodes found are added to the 104 | * Free Data list. 105 | */ 106 | CheckNodes( DB_Nodes ); 107 | 108 | 109 | 110 | There are several common variant on this, such as putting the opening '/*' on a line by itself, thus ensuring an almost-blank line before the comment and enabling easier line insertion after it. Also, the asterisk may be always put in column two or two asterisks can be used on text lines, to emphasize the comment and to be tidy in having two comment characters per line. Some horizontal space can be saved by using spaces instead of tabs to separate the text from the asterisk: 111 | 112 | 113 | 114 | /* 115 | ** Check for all corrupt nodes and add these to the 116 | ** Bad Data list. Any clear nodes found are added to the 117 | ** Free Data list. 118 | */ 119 | CheckNodes( DB_Nodes ); 120 | /* 121 | * Alternative comment block format.. 122 | * ..which puts one asterisk always in column 2 123 | */ 124 | 125 | 126 | 127 | Enclosing from above 128 | An alternative or an addition to white space as a method of distinguishing comments from code is to put a bar above the comment, but not below it. This dissociates the comment from the code above, whilst emphasizing its association with the code below. 129 | 130 | 131 | 132 | /*********************************************************** 133 | * Check for all corrupt nodes and add these to the 134 | * Bad Data list. Any clear nodes found are added to the 135 | * Free Data list. 136 | */ 137 | CheckNodes( DB_Nodes ); 138 | 139 | 140 | 141 | Enclosing from below 142 | The comment can be dissociated more from the code below by putting a bar below it too. It is being tidy to keep it the same length as the top line. The dissociation can be further emphasized with a blank line between the comment and the code: 143 | 144 | 145 | 146 | /************************************************************ 147 | * Check for all corrupt nodes and add these to the 148 | * Bad Data list. Any clear nodes found are added to the 149 | * Free Data list. 150 | ************************************************************/ 151 | 152 | CheckNodes( DB_Nodes ); 153 | 154 | 155 | 156 | Note that the final '*/' is no longer below the opening '/*'. This is not so important as the limits of the comment block are very clear, although there is a danger of missing the final '/', resulting in the code below being commented out. 157 | 158 | A status comment, which describes the code above it, can be enclosed at the bottom, but not the top, to emphasize its association. 159 | 160 | 161 | 162 | /* 163 | * All open databases have now been closed, with all 164 | * signs of corruption reported to the corrupt data 165 | * log. It is now safe to shut the system down. 166 | ************************************************************/ 167 | 168 | 169 | 170 | Enclosing from the right 171 | The final step is now to tidily fill in the right hand side of the box, although this may be considered to be more trouble than it is worth, as it makes editing the comment text less easy. 172 | 173 | 174 | 175 | /************************************************************ 176 | * Check for all corrupt nodes and add these to the * 177 | * Bad Data list. Any clear nodes found are added to the * 178 | * Free Data list. * 179 | *************************************************************/ 180 | 181 | 182 | 183 | A simplification of the rules about where to place the '/*' and '*/' tokens is to insist that all comments should have matching tokens on the same line. Thus all comment lines are automatically enclosed from the right and the left. 184 | 185 | 186 | 187 | /************************************************************/ 188 | /* Check for all corrupt nodes and add these to the */ 189 | /* Bad Data list. Any clear nodes found are added to the */ 190 | /* Free Data list. */ 191 | /************************************************************/ 192 | 193 | 194 | 195 | With this rule, enclosure from the top and bottom may still be optional. The right hand margin may stay justified or may collapse to a ragged right margin, which eases editing but is not as tidy: 196 | 197 | 198 | 199 | /* Check for all corrupt nodes and add these to the */ 200 | /* Bad Data list. Any clear nodes found are added to the */ 201 | /* Free Data list. */ 202 | 203 | 204 | 205 | 4.6.4 Delimiters 206 | Comments need not be used for text comments: they may also be used to separate out distinct pieces of code. 207 | 208 | Separating chunks 209 | Drawing lines across the page not only separates the code from the comment, but also separates individual chunks of code, making the chunks easier to see and understand. As these are effectively single-line block comments, they can include simple comments: 210 | 211 | 212 | 213 | /*---- Close all open files ---------------------------------------*/ 214 | 215 | for ( FileNo = 0; FileNo < NofFilesOpen; FileNo++ ) 216 | { 217 | ErrNo = CloseFile( FileHandle[FileNo] ); 218 | if ( ErrNo != 0 ) 219 | { 220 | FileError( ErrNo ); 221 | } 222 | } 223 | 224 | /*---- Print shutdown message ------------------------------------*/ 225 | 226 | printf( "System closing down,\n" ); 227 | printf( "Remove all tapes and secure in safe.\n"); 228 | 229 | /*---- Lock terminal off ------------------------------------------*/ 230 | ... 231 | 232 | 233 | 234 | Multi-line block comments can also a similar scheme, whereby the text in the line is an effective summary for the comment block. 235 | 236 | 237 | 238 | /*---- Check window status ----------------------------------------- 239 | * All windows (including closed ones) must now be checked 240 | * to ensure all outstanding actions have been completed. 241 | *-------------------------------------------------------------------*/ 242 | 243 | ----------------------------------------------------------------------> 244 | 245 | Data/Code delimiters 246 | It can be difficult to immediately find the beginning of the code at the start of a function. For example, a reader might miss the first statement (which may be mistaken for a data declaration). 247 | 248 | 249 | 250 | int 251 | ReadDoorStatus( S_DOOR *Door ) 252 | 253 | { 254 | int DoorType; /* Door construction - WOOD, METAL, etc. */ 255 | int LockType; /* Make of lock - CHUBB, YALE, etc. */ 256 | DoorType = WOOD; /* set default for door construction */ 257 | 258 | LockType = Door->Lock; <------ reader may read code from here! 259 | 260 | 261 | 262 | However, if we put a line across at the start of the data and code sections, no mistakes may be made, and the start of the data and code sections can instantly be found. 263 | 264 | 265 | 266 | int 267 | ReadDoorStatus( S_DOOR *Door ) 268 | 269 | { 270 | /*---- Data --------------------------------------------------------*/ 271 | 272 | int DoorType; /* Door construction - WOOD, METAL, etc. */ 273 | int LockType; /* Make of lock - CHUBB, YALE, etc. */ 274 | 275 | /*---- Code --------------------------------------------------------*/ 276 | 277 | DoorType = WOOD; /* set default for door construction */ 278 | LockType = Door->Lock; 279 | 280 | 281 | 282 | Delimiter 'weight' 283 | The 'weight' of the delimiter can be used to indicate importance of the section of code or data that is being delimited. The symbols used may be for single line delimiters, or to bound multi-line comment blocks. 284 | 285 | A simple scheme would be: 286 | 287 | Asterisks (/********/) Major sections, eg. functions, data areas. 288 | 289 | Equals (/*======*/) Major sub-sections 290 | 291 | Minus (/*------*/) Minor sub-sections 292 | 293 | e.g. 294 | 295 | 296 | 297 | /******************************************************************** 298 | * FireOnEnemy( ShipType ) 299 | ... 300 | 301 | /*==== Prepare cannon for firing ===================================*/ 302 | 303 | /*---- Load cannon -------------------------------------------------*/ 304 | ... 305 | 306 | /*---- Open gun port doors -----------------------------------------*/ 307 | ... 308 | 309 | /*==== Fire and retract cannon =====================================*/ 310 | ... 311 | -------------------------------------------------------------------------------- /test/fixtures/other/haskell.txt: -------------------------------------------------------------------------------- 1 | {- this is a comment 2 | on more lines -} 3 | -- and this is a comment on one line 4 | putStrLn "Wikipedia" -- this is another comment 5 | -------------------------------------------------------------------------------- /test/fixtures/other/lua.txt: -------------------------------------------------------------------------------- 1 | Lua 2 | The Lua programming language uses double-hyphens, `--`, for single line comments in a similar way to Ada, Eiffel, Haskell, SQL and VHDL languages. Lua also has block comments, which start with `--[[` and run until a closing `]]` 3 | 4 | For example: 5 | 6 | --[[A multi-line 7 | long comment 8 | ]] 9 | print(20) -- print the result 10 | A common technique to comment out a piece of code,[44] is to enclose the code between `--[[` and `--]]`, as below: 11 | 12 | --[[ 13 | print(10) 14 | --]] 15 | -- no action (commented out) 16 | In this case, it's possible to reactivate the code by adding a single hyphen to the first line: 17 | 18 | ---[[ 19 | print(10) 20 | --]] 21 | --> 10 22 | In the first example, the `--[[` in the first line starts a long comment, and the two hyphens in the last line are still inside that comment. In the second example, the sequence `---[[` starts an ordinary, single-line comment, so that the first and the last lines become independent comments. In this case, the print is outside comments. In this case, the last line becomes an independent comment, as it starts with `--`. 23 | 24 | Long comments in Lua can be more complex than these, as you can read in the section called "Long strings" c.f. Programming in Lua. 25 | -------------------------------------------------------------------------------- /test/fixtures/other/matlab.txt: -------------------------------------------------------------------------------- 1 | MATLAB 2 | In MATLAB's programming language, the '%' character indicates a single-line comment. Multi line comments are also available via `%{` and `%}` brackets and can be nested, e.g. 3 | 4 | % These are the derivatives for each term 5 | d = [0 -1 0]; 6 | 7 | %{ 8 | %{ 9 | (Example of a nested comment, indentation is for cosmetics (and ignored).) 10 | %} 11 | We form the sequence, following the Taylor formula. 12 | Note that we're operating on a vector. 13 | %} 14 | seq = d .* (x - c).^n ./(factorial(n)) 15 | 16 | % We add-up to get the Taylor approximation 17 | approx = sum(seq) 18 | -------------------------------------------------------------------------------- /test/fixtures/other/ocaml.txt: -------------------------------------------------------------------------------- 1 | OCaml 2 | OCaml uses nestable comments, which is useful when commenting a code block. 3 | 4 | codeLine(* comment level 1(*comment level 2*)*) 5 | -------------------------------------------------------------------------------- /test/fixtures/other/pascal.txt: -------------------------------------------------------------------------------- 1 | (* test diagonals *) 2 | columnDifference := testColumn - column; 3 | if (row + columnDifference = testRow) or 4 | ....... 5 | -------------------------------------------------------------------------------- /test/fixtures/other/perl.txt: -------------------------------------------------------------------------------- 1 | # A simple example 2 | # 3 | my $s = "Wikipedia"; # Sets the variable s to "Wikipedia". 4 | print $s . "\n"; # Add a newline character after printing 5 | -------------------------------------------------------------------------------- /test/fixtures/other/php.txt: -------------------------------------------------------------------------------- 1 | PHP supports 'C', 'C++' and Unix shell-style (Perl style) comments. For example: 2 | 3 | 10 | The "one-line" comment styles only comment to the end of the line or the current block of PHP code, whichever comes first. This means that HTML code after `// ... ?>` or `# ... ?>` WILL be printed: ?> breaks out of PHP mode and returns to HTML mode, and `//` or `#` cannot influence that. If the asp_tags configuration directive is enabled, it behaves the same with `// %>` and `# %>`. However, the tag doesn't break out of PHP mode in a one-line comment. 11 | 12 |

This is an example

13 |

The header above will say 'This is an example'.

14 | 'C' style comments end at the first `*/` encountered. Make sure you don't nest 'C' style comments. It is easy to make this mistake if you are trying to comment out a large block of code. 15 | 16 | 21 | -------------------------------------------------------------------------------- /test/fixtures/other/python.txt: -------------------------------------------------------------------------------- 1 | Python 2 | Inline comments in Python use the hash ('#') character, as in the two examples in this code: 3 | 4 | # This program prints "Hello World" to the screen 5 | print("Hello World!") # Note the new syntax 6 | Block comments, as defined in this article, don't technically exist in Python.[49] A bare string literal represented by a triple-quoted string can be used[50] but is not ignored by the interpreter in the same way that "#" comment is. In the examples below, the triple double-quoted strings act in this way as comments, but are also treated as docstrings: 7 | 8 | """ 9 | Assuming this is file mymodule.py, then this string, being the 10 | first statement in the file, will become the "mymodule" module's 11 | docstring when the file is imported. 12 | """ 13 | 14 | class MyClass(object): 15 | """The class's docstring""" 16 | 17 | def my_method(self): 18 | """The method's docstring""" 19 | 20 | def my_function(): 21 | """The function's docstring""" 22 | -------------------------------------------------------------------------------- /test/fixtures/other/ruby.txt: -------------------------------------------------------------------------------- 1 | Ruby 2 | Comments in Ruby. 3 | 4 | Single line commenting: (line starts with hash "#") 5 | 6 | puts "This is not a comment" 7 | 8 | # this is a comment 9 | 10 | puts "This is not a comment" 11 | Multi-line commenting: (comments goes between keywords "begin" and "end") 12 | 13 | puts "This is not a comment" 14 | 15 | =begin 16 | 17 | whatever goes in these lines 18 | 19 | is just for the human reader 20 | 21 | =end 22 | 23 | puts "This is not a comment" 24 | -------------------------------------------------------------------------------- /test/fixtures/other/shebang.txt: -------------------------------------------------------------------------------- 1 | #!/bin/cat 2 | Hello world! 3 | -------------------------------------------------------------------------------- /test/fixtures/other/sql.txt: -------------------------------------------------------------------------------- 1 | SQL 2 | Comments in SQL are in single-line-only form, when using two dashes: 3 | 4 | -- This is a single line comment 5 | -- followed by a second line 6 | SELECT COUNT(*) 7 | FROM Authors 8 | WHERE Authors.name = 'Smith'; -- Note: we only want 'smith' 9 | -- this comment appears after SQL code 10 | -------------------------------------------------------------------------------- /test/fixtures/other/swift.txt: -------------------------------------------------------------------------------- 1 | Swift 2 | Single-line comments begin with two forward-slashes (`//`): 3 | 4 | // This is a comment. 5 | Multiline comments start with a forward-slash followed by an asterisk (`/*`) and end with an asterisk followed by a forward-slash (`*/`): 6 | 7 | /* This is also a comment 8 | but is written over multiple lines. */ 9 | Multiline comments in Swift can be nested inside other multiline comments. You write nested comments by starting a multiline comment block and then starting a second multiline comment within the first block. The second block is then closed, followed by the first block: 10 | 11 | /* This is the start of the first multiline comment. 12 | /* This is the second, nested multiline comment. */ 13 | This is the end of the first multiline comment. */ 14 | -------------------------------------------------------------------------------- /test/fixtures/quoted-strings.js: -------------------------------------------------------------------------------- 1 | window.amino_cec_callback = function (tag, source, destination, body) { 2 | debug("///////////// cec_callback ////////////////////"); 3 | debug(tag + " " + source + " " + destination + " " + body); 4 | debug("///////////// cec_callback ////////////////////"); 5 | }; 6 | 7 | const foo = { 8 | "config": { 9 | "properties": { 10 | "device_id": { 11 | "type": "string", 12 | "title": "Device ID", 13 | "label": { 14 | "$ref": "/rpcs/device_ids#thermostats/*/{name}" 15 | }, 16 | "oneOf": [{ 17 | "$ref": "/rpcs/device_ids#thermostats/*/{device_id}" 18 | }] 19 | } 20 | }, 21 | "required": ["device_id"], 22 | "disposition": ["device_id"] 23 | } 24 | }; -------------------------------------------------------------------------------- /test/fixtures/strip-all.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * strip this multiline 3 | * block comment 4 | */ 5 | 'use strict'; 6 | 7 | /**! 8 | * and this multiline 9 | * block comment 10 | */ 11 | var foo = function(/* and these single-line block comment */) {}; 12 | 13 | /** 14 | * and this 15 | * multiline block 16 | * comment 17 | */ 18 | var bar = function(/* and that */) {}; 19 | 20 | var baz = '//bar baz not a comment'; 21 | 22 | // this single-line line comment 23 | var qux = function() { 24 | // this multiline 25 | // line comment 26 | var some = true; 27 | //this 28 | var fafa = true; //and this 29 | // var also = 'that'; 30 | var but = 'not'; //! that comment 31 | }; 32 | 33 | // also this multiline 34 | // line comment 35 | var fun = false; 36 | var path = '/path/to/*/something/that/not/be/stripped.js'; 37 | var globstar = '/path//to//globstar/not/be/stripped/**/*.js'; -------------------------------------------------------------------------------- /test/fixtures/strip-keep-line.js: -------------------------------------------------------------------------------- 1 | /** 2 | * this block comment 3 | * will not be striped 4 | */ 5 | 6 | 'use strict'; 7 | 8 | //! and this multiline 9 | //! block comment 10 | var foo = function(/* and these single-line block comment */) {}; 11 | 12 | /** 13 | * and this 14 | * multiline block 15 | * comment 16 | */ 17 | var bar = function(/* and that */) {}; 18 | 19 | //will be removed 20 | var baz = function() { 21 | // this multiline 22 | // line comment 23 | var some = true; 24 | // will be 25 | var fafa = true; 26 | // var removed = 'yes'; 27 | var but = 'not'; //! that comment 28 | }; 29 | 30 | var path = '/path/to/*/something/that/not/be/stripped.js'; 31 | var globstar = '/path/to/globstar/not/be/stripped/**/*.js'; 32 | -------------------------------------------------------------------------------- /test/other.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * strip-comments 3 | * 4 | * Copyright (c) 2014-2018, Jon Schlinkert. 5 | * Released under the MIT license. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const fs = require('fs'); 11 | const path = require('path'); 12 | const assert = require('assert'); 13 | const strip = require('../index'); 14 | 15 | const fixture = path.join.bind(path, __dirname, 'fixtures/other'); 16 | const expected = path.join.bind(path, __dirname, 'expected/other'); 17 | const read = src => fs.readFileSync(src, 'utf-8').replace(/\r*\n/g, '\n');; 18 | 19 | describe('other languages', () => { 20 | it('should strip Ada comments', () => { 21 | const name = 'ada'; 22 | const input = read(fixture(`${name}.txt`)); 23 | const output = read(expected(`${name}.txt`)); 24 | const actual = strip(input, { language: name, preserveNewlines: true }); 25 | assert.strictEqual(actual, output); 26 | }); 27 | 28 | it('should strip APL comments', () => { 29 | const name = 'apl'; 30 | const input = read(fixture(`${name}.txt`)); 31 | const output = read(expected(`${name}.txt`)); 32 | const actual = strip(input, { language: name, preserveNewlines: true }); 33 | assert.strictEqual(actual, output); 34 | }); 35 | 36 | it('should strip C comments', () => { 37 | const name = 'c'; 38 | const input = read(fixture(`${name}.txt`)); 39 | const output = read(expected(`${name}.txt`)); 40 | const actual = strip(input, { language: name, preserveNewlines: true }); 41 | assert.strictEqual(actual, output); 42 | }); 43 | 44 | it('should strip AppleScript comments', () => { 45 | const name = 'AppleScript'; 46 | const input = read(fixture(`${name}.txt`)); 47 | const output = read(expected(`${name}.txt`)); 48 | const actual = strip(input, { language: name }); 49 | assert.strictEqual(actual, output); 50 | }); 51 | 52 | it('should strip Haskell comments', () => { 53 | const name = 'haskell'; 54 | const input = read(fixture(`${name}.txt`)); 55 | const output = read(expected(`${name}.txt`)); 56 | const actual = strip(input, { language: name }); 57 | assert.strictEqual(actual, output); 58 | }); 59 | 60 | it('should strip Lua comments', () => { 61 | const name = 'lua'; 62 | const input = read(fixture(`${name}.txt`)); 63 | const output = read(expected(`${name}.txt`)); 64 | const actual = strip(input, { language: name }); 65 | assert.strictEqual(actual, output); 66 | }); 67 | 68 | it('should strip MATLAB comments', () => { 69 | const name = 'matlab'; 70 | const input = read(fixture(`${name}.txt`)); 71 | const output = read(expected(`${name}.txt`)); 72 | const actual = strip(input, { language: name }); 73 | assert.strictEqual(actual, output); 74 | }); 75 | 76 | it('should strip OCaml comments', () => { 77 | const name = 'ocaml'; 78 | const input = read(fixture(`${name}.txt`)); 79 | const output = read(expected(`${name}.txt`)); 80 | const actual = strip(input, { language: name }); 81 | assert.strictEqual(actual, output); 82 | }); 83 | 84 | it('should strip Pascal comments', () => { 85 | const name = 'pascal'; 86 | const input = read(fixture(`${name}.txt`)); 87 | const output = read(expected(`${name}.txt`)); 88 | const actual = strip(input, { language: name }); 89 | assert.strictEqual(actual, output); 90 | }); 91 | 92 | it('should strip PHP comments', () => { 93 | const name = 'php'; 94 | const input = read(fixture(`${name}.txt`)); 95 | const output = read(expected(`${name}.txt`)); 96 | const actual = strip(input, { language: name }); 97 | assert.strictEqual(actual, output); 98 | }); 99 | 100 | it('should strip Perl comments', () => { 101 | const name = 'perl'; 102 | const input = read(fixture(`${name}.txt`)); 103 | const output = read(expected(`${name}.txt`)); 104 | const actual = strip(input, { language: name }); 105 | assert.strictEqual(actual, output); 106 | }); 107 | 108 | it('should strip Python comments', () => { 109 | const name = 'python'; 110 | const input = read(fixture(`${name}.txt`)); 111 | const output = read(expected(`${name}.txt`)); 112 | const actual = strip(input, { language: name }); 113 | assert.strictEqual(actual, output); 114 | }); 115 | 116 | it('should strip Ruby comments', () => { 117 | const name = 'ruby'; 118 | const input = read(fixture(`${name}.txt`)); 119 | const output = read(expected(`${name}.txt`)); 120 | const actual = strip(input, { language: name }); 121 | assert.strictEqual(actual, output); 122 | }); 123 | 124 | it('should strip shebang comments', () => { 125 | const name = 'shebang'; 126 | const input = read(fixture(`${name}.txt`)); 127 | const output = read(expected(`${name}.txt`)); 128 | const actual = strip(input, { language: name }); 129 | assert.strictEqual(actual, output); 130 | }); 131 | 132 | it('should strip SQL comments', () => { 133 | const name = 'sql'; 134 | const input = read(fixture(`${name}.txt`)); 135 | const output = read(expected(`${name}.txt`)); 136 | const actual = strip(input, { language: name }); 137 | assert.strictEqual(actual, output); 138 | }); 139 | 140 | it('should strip Swift comments', () => { 141 | const name = 'swift'; 142 | const input = read(fixture(`${name}.txt`)); 143 | const output = read(expected(`${name}.txt`)); 144 | const actual = strip(input, { language: name }); 145 | assert.strictEqual(actual, output); 146 | }); 147 | }); 148 | --------------------------------------------------------------------------------