|
| 1 | +import sys |
| 2 | +import os |
| 3 | +import platform |
| 4 | +import io |
| 5 | +import getopt |
| 6 | + |
| 7 | +# This is done due to the build system being how it is |
| 8 | +try: |
| 9 | + re = __import__("regex") |
| 10 | +except ImportError: |
| 11 | + import re |
| 12 | +import string |
| 13 | +import errno |
| 14 | +import copy |
| 15 | +import glob |
| 16 | +from jsbeautifier.__version__ import __version__ |
| 17 | +from jsbeautifier.cli import * |
| 18 | +from jsbeautifier.javascript.options import BeautifierOptions |
| 19 | +from jsbeautifier.javascript.beautifier import Beautifier |
| 20 | + |
| 21 | +# |
| 22 | +# The MIT License (MIT) |
| 23 | + |
| 24 | +# Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors. |
| 25 | + |
| 26 | +# Permission is hereby granted, free of charge, to any person |
| 27 | +# obtaining a copy of this software and associated documentation files |
| 28 | +# (the "Software"), to deal in the Software without restriction, |
| 29 | +# including without limitation the rights to use, copy, modify, merge, |
| 30 | +# publish, distribute, sublicense, and/or sell copies of the Software, |
| 31 | +# and to permit persons to whom the Software is furnished to do so, |
| 32 | +# subject to the following conditions: |
| 33 | + |
| 34 | +# The above copyright notice and this permission notice shall be |
| 35 | +# included in all copies or substantial portions of the Software. |
| 36 | + |
| 37 | +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| 38 | +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| 39 | +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| 40 | +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
| 41 | +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
| 42 | +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
| 43 | +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| 44 | +# SOFTWARE. |
| 45 | +# |
| 46 | +# Originally written by Einar Lielmanis et al., |
| 47 | +# Conversion to python by Einar Lielmanis, einar@beautifier.io, |
| 48 | +# Parsing improvement for brace-less and semicolon-less statements |
| 49 | +# by Liam Newman <bitwiseman@beautifier.io> |
| 50 | +# Python is not my native language, feel free to push things around. |
| 51 | +# |
| 52 | +# Use either from command line (script displays its usage when run |
| 53 | +# without any parameters), |
| 54 | +# |
| 55 | +# |
| 56 | +# or, alternatively, use it as a module: |
| 57 | +# |
| 58 | +# import jsbeautifier |
| 59 | +# res = jsbeautifier.beautify('your javascript string') |
| 60 | +# res = jsbeautifier.beautify_file('some_file.js') |
| 61 | +# |
| 62 | +# you may specify some options: |
| 63 | +# |
| 64 | +# opts = jsbeautifier.default_options() |
| 65 | +# opts.indent_size = 2 |
| 66 | +# res = jsbeautifier.beautify('some javascript', opts) |
| 67 | +# |
| 68 | +# |
| 69 | +# Here are the available options: (read source) |
| 70 | + |
| 71 | +__all__ = [ |
| 72 | + "default_options", |
| 73 | + "beautify", |
| 74 | + "beautify_file", |
| 75 | + "usage", |
| 76 | + "main", |
| 77 | +] |
| 78 | + |
| 79 | + |
| 80 | +def default_options(): |
| 81 | + return BeautifierOptions() |
| 82 | + |
| 83 | + |
| 84 | +def beautify(string, opts=default_options()): |
| 85 | + b = Beautifier() |
| 86 | + return b.beautify(string, opts) |
| 87 | + |
| 88 | + |
| 89 | +def beautify_file(file_name, opts=default_options()): |
| 90 | + return process_file(file_name, opts, beautify) |
| 91 | + |
| 92 | + |
| 93 | +def usage(stream=sys.stdout): |
| 94 | + print( |
| 95 | + "jsbeautifier.py@" + __version__ + """ |
| 96 | +
|
| 97 | +Javascript beautifier (https://beautifier.io/) |
| 98 | +
|
| 99 | +Usage: jsbeautifier.py [options] <infile> |
| 100 | +
|
| 101 | + <infile> can be "-", which means stdin. |
| 102 | +
|
| 103 | +Input options: |
| 104 | +
|
| 105 | + -i, --stdin Read input from stdin |
| 106 | +
|
| 107 | +Output options: |
| 108 | +
|
| 109 | + -s, --indent-size=NUMBER Indentation size. (default 4). |
| 110 | + -c, --indent-char=CHAR Character to indent with. (default space). |
| 111 | + -e, --eol=STRING Character(s) to use as line terminators. |
| 112 | + (default first newline in file, otherwise "\\n") |
| 113 | + -t, --indent-with-tabs Indent with tabs, overrides -s and -c |
| 114 | + -d, --disable-preserve-newlines Do not preserve existing line breaks. |
| 115 | + -P, --space-in-paren Add padding spaces within paren, ie. f( a, b ) |
| 116 | + -E, --space-in-empty-paren Add a single space inside empty paren, ie. f( ) |
| 117 | + -j, --jslint-happy More jslint-compatible output |
| 118 | + -a, --space-after-anon-function Add a space before an anonymous function's parens, ie. function () |
| 119 | + --space-after-named-function Add a space before a named function's parens, i.e. function example () |
| 120 | + -b, --brace-style=collapse Brace style (collapse, expand, end-expand, none)(,preserve-inline) |
| 121 | + -k, --keep-array-indentation Keep array indentation. |
| 122 | + --quiet Suppress info about a file if nothing was changed. |
| 123 | + -r, --replace Write output in-place, replacing input |
| 124 | + -o, --outfile=FILE Specify a file to output to (default stdout) |
| 125 | + -f, --keep-function-indentation Do not re-indent function bodies defined in var lines. |
| 126 | + -x, --unescape-strings Decode printable chars encoded in \\xNN notation. |
| 127 | + -X, --e4x Pass E4X xml literals through untouched |
| 128 | + -C, --comma-first Put commas at the beginning of new line instead of end. |
| 129 | + -m, |
| 130 | + --max-preserve-newlines=NUMBER Number of line-breaks to be preserved in one chunk (default 10) |
| 131 | + -O, --operator-position=STRING Set operator position (before-newline, after-newline, preserve-newline) |
| 132 | + -w, --wrap-line-length Attempt to wrap line when it exceeds this length. |
| 133 | + NOTE: Line continues until next wrap point is found. |
| 134 | + -n, --end-with-newline End output with newline |
| 135 | + --indent-empty-lines Keep indentation on empty lines |
| 136 | + --templating List of templating languages (auto,none,django,erb,handlebars,php,smarty,angular) ["auto"] auto = none in JavaScript, all in html |
| 137 | + --editorconfig Enable setting configuration from EditorConfig |
| 138 | +
|
| 139 | +Rarely needed options: |
| 140 | +
|
| 141 | + --eval-code evaluate code if a JS interpreter is |
| 142 | + installed. May be useful with some obfuscated |
| 143 | + script but poses a potential security issue. |
| 144 | +
|
| 145 | + -l, --indent-level=NUMBER Initial indentation level. (default 0). |
| 146 | +
|
| 147 | + -h, --help, --usage Prints this help statement. |
| 148 | + -v, --version Show the version |
| 149 | +
|
| 150 | +""", |
| 151 | + file=stream, |
| 152 | + ) |
| 153 | + if stream == sys.stderr: |
| 154 | + return 1 |
| 155 | + else: |
| 156 | + return 0 |
| 157 | + |
| 158 | + |
| 159 | +def main(): |
| 160 | + argv = sys.argv[1:] |
| 161 | + |
| 162 | + try: |
| 163 | + opts, args = getopt.getopt( |
| 164 | + argv, |
| 165 | + "f:s:c:e:o:rdEPjab:kil:xhtvXnCO:w:m:", |
| 166 | + [ |
| 167 | + "brace-style=", |
| 168 | + "comma-first", |
| 169 | + "disable-preserve-newlines", |
| 170 | + "e4x", |
| 171 | + "editorconfig", |
| 172 | + "end-with-newline", |
| 173 | + "eol=", |
| 174 | + "eval-code", |
| 175 | + "file=", |
| 176 | + "help", |
| 177 | + "indent-char=", |
| 178 | + "indent-empty-lines", |
| 179 | + "indent-level=", |
| 180 | + "indent-size=", |
| 181 | + "indent-with-tabs", |
| 182 | + "jslint-happy", |
| 183 | + "keep-array-indentation", |
| 184 | + "keep-function-indentation", |
| 185 | + "max-preserve-newlines=", |
| 186 | + "operator-position=", |
| 187 | + "outfile=", |
| 188 | + "quiet", |
| 189 | + "replace", |
| 190 | + "space-after-anon-function", |
| 191 | + "space-after-named-function", |
| 192 | + "space-in-empty-paren", |
| 193 | + "space-in-paren", |
| 194 | + "stdin", |
| 195 | + "templating=", |
| 196 | + "unescape-strings", |
| 197 | + "usage", |
| 198 | + "version", |
| 199 | + "wrap-line-length", |
| 200 | + ], |
| 201 | + ) |
| 202 | + except getopt.GetoptError as ex: |
| 203 | + print(ex, file=sys.stderr) |
| 204 | + return usage(sys.stderr) |
| 205 | + |
| 206 | + js_options = default_options() |
| 207 | + |
| 208 | + filepath_params = [] |
| 209 | + filepath_params.extend(args) |
| 210 | + |
| 211 | + outfile_param = "stdout" |
| 212 | + replace = False |
| 213 | + |
| 214 | + for opt, arg in opts: |
| 215 | + if opt in ("--file", "-f"): |
| 216 | + filepath_params.append(arg) |
| 217 | + elif opt in ("--keep-array-indentation", "-k"): |
| 218 | + js_options.keep_array_indentation = True |
| 219 | + elif opt in ("--keep-function-indentation",): |
| 220 | + js_options.keep_function_indentation = True |
| 221 | + elif opt in ("--outfile", "-o"): |
| 222 | + outfile_param = arg |
| 223 | + elif opt in ("--replace", "-r"): |
| 224 | + replace = True |
| 225 | + elif opt in ("--indent-size", "-s"): |
| 226 | + js_options.indent_size = int(arg) |
| 227 | + elif opt in ("--indent-char", "-c"): |
| 228 | + js_options.indent_char = arg |
| 229 | + elif opt in ("--eol", "-e"): |
| 230 | + js_options.eol = arg |
| 231 | + elif opt in ("--indent-with-tabs", "-t"): |
| 232 | + js_options.indent_with_tabs = True |
| 233 | + elif opt in ("--disable-preserve-newlines", "-d"): |
| 234 | + js_options.preserve_newlines = False |
| 235 | + elif opt in ("--max-preserve-newlines", "-m"): |
| 236 | + js_options.max_preserve_newlines = int(arg) |
| 237 | + elif opt in ("--space-in-paren", "-P"): |
| 238 | + js_options.space_in_paren = True |
| 239 | + elif opt in ("--space-in-empty-paren", "-E"): |
| 240 | + js_options.space_in_empty_paren = True |
| 241 | + elif opt in ("--jslint-happy", "-j"): |
| 242 | + js_options.jslint_happy = True |
| 243 | + elif opt in ("--space-after-anon-function", "-a"): |
| 244 | + js_options.space_after_anon_function = True |
| 245 | + elif opt in ("--space-after-named-function",): |
| 246 | + js_options.space_after_named_function = True |
| 247 | + elif opt in ("--eval-code",): |
| 248 | + js_options.eval_code = True |
| 249 | + elif opt in ("--quiet",): |
| 250 | + js_options.keep_quiet = True |
| 251 | + elif opt in ("--brace-style", "-b"): |
| 252 | + js_options.brace_style = arg |
| 253 | + elif opt in ("--unescape-strings", "-x"): |
| 254 | + js_options.unescape_strings = True |
| 255 | + elif opt in ("--e4x", "-X"): |
| 256 | + js_options.e4x = True |
| 257 | + elif opt in ("--end-with-newline", "-n"): |
| 258 | + js_options.end_with_newline = True |
| 259 | + elif opt in ("--comma-first", "-C"): |
| 260 | + js_options.comma_first = True |
| 261 | + elif opt in ("--operator-position", "-O"): |
| 262 | + js_options.operator_position = arg |
| 263 | + elif opt in ("--wrap-line-length ", "-w"): |
| 264 | + js_options.wrap_line_length = int(arg) |
| 265 | + elif opt in ("--indent-empty-lines",): |
| 266 | + js_options.indent_empty_lines = True |
| 267 | + elif opt in ("--templating",): |
| 268 | + js_options.templating = arg.split(",") |
| 269 | + elif opt in ("--stdin", "-i"): |
| 270 | + # stdin is the default if no files are passed |
| 271 | + filepath_params = [] |
| 272 | + elif opt in ("--editorconfig",): |
| 273 | + js_options.editorconfig = True |
| 274 | + elif opt in ("--version", "-v"): |
| 275 | + return print(__version__) |
| 276 | + elif opt in ("--help", "--usage", "-h"): |
| 277 | + return usage() |
| 278 | + |
| 279 | + try: |
| 280 | + filepaths, replace = get_filepaths_from_params(filepath_params, replace) |
| 281 | + for filepath in filepaths: |
| 282 | + if not replace: |
| 283 | + outfile = outfile_param |
| 284 | + else: |
| 285 | + outfile = filepath |
| 286 | + |
| 287 | + js_options = integrate_editorconfig_options( |
| 288 | + filepath, js_options, outfile, "js" |
| 289 | + ) |
| 290 | + |
| 291 | + pretty = beautify_file(filepath, js_options) |
| 292 | + |
| 293 | + write_beautified_output(pretty, js_options, outfile) |
| 294 | + |
| 295 | + except MissingInputStreamError: |
| 296 | + print("Must pipe input or define at least one file.\n", file=sys.stderr) |
| 297 | + usage(sys.stderr) |
| 298 | + return 1 |
| 299 | + |
| 300 | + except UnicodeError as ex: |
| 301 | + print("Error while decoding input or encoding output:", file=sys.stderr) |
| 302 | + print(ex, file=sys.stderr) |
| 303 | + return 1 |
| 304 | + |
| 305 | + except Exception as ex: |
| 306 | + print(ex, file=sys.stderr) |
| 307 | + return 1 |
| 308 | + |
| 309 | + # Success |
| 310 | + return 0 |
| 311 | + |
| 312 | + |
| 313 | +if __name__ == "__main__": |
| 314 | + main() |
0 commit comments