Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

A JavaScript beautifier that can both infer coding style and transform code to reflect that style. You can also set style preferences explicitly in a variety of ways.

License

NotificationsYou must be signed in to change notification settings

jednano/codepainter

 
 

Repository files navigation

Build StatusDependency StatusNPM versionViews

NPM

Code Painter is a JavaScript beautifier that can transform JavaScript filesinto the formatting style of your choice. Style settings can be supplied viapredefined styles, a custom JSON file, command line settings,EditorConfigsettings or it can even be inferred from one or more sample files. For example,you could provide a code snippet from the same project with which the new codeis intended to integrate.

It uses the excellentEsprima parser byAriya Hidayat and hiscontributors — thanks!

The name is inspired by Word's Format Painter, which does a similar job forrich text.

Requirements

Code Painter requiresNode.js version 0.10.6 or above.

Installation

$ npm install codepainter

To access the command globally, do a global install:

$ npm install -g codepainter

*nix users might also have to add the following to their .bashrc file:

PATH=$PATH:/usr/local/share/npm/bin

CLI Usage

You can see the usage in the CLI directly by typingcodepaint orcodepaint --help.

$ codepaint --help  Code Painter beautifies JavaScript.  Usage: codepaint [options] <command>  Commands:    infer [options] <globs>...  Infer formatting style from file(s)    xform [options] <globs>...  Transform file(s) to specified style  Options:    -h, --help     output help information    -V, --version  output version information$ codepaint infer --help  Infer formatting style from file(s)  Usage: infer [options] <globs>...  Options:    -h, --help     output help information    -d, --details  give a detailed report with trend scores    --ini          use ini file format  Examples:    $ codepaint infer "**/*.js"    $ codepaint infer "**/*view.js" "**/*model.js"    $ codepaint infer -d "**/*.js"    $ codepaint infer --ini "**/*.js"$ codepaint xform --help  Transform file(s) to specified formatting style  Usage: xform [options] <globs>...  Options:    -h, --help                 output help information    -i, --infer <glob>         code sample(s) to infer    -p, --predef <name>        cascade predefined style (e.g., idiomatic)    -j, --json <path>          cascade JSON style over predef style    -s, --style <key>=<value>  cascade explicit style over JSON    -e, --editor-config        cascade EditorConfig style over all others  Examples:    $ codepaint xform "**/*.js"    $ codepaint xform "**/*view.js" "**/*model.js"    $ codepaint xform %s "**/*.js" -i sample.js    $ codepaint xform %s "**/*.js" -p idiomatic    $ codepaint xform %s "**/*.js" -j custom.json    $ codepaint xform %s "**/*.js" -s quote_type=null    $ codepaint xform %s "**/*.js" -s indent_style=space -s indent_size=4    $ codepaint xform %s "**/*.js" -e

Library Usage

varcodepaint=require('codepainter');

Library usage is intended to be every bit the same as CLI usage, so you canexpect the same options and arguments that the CLI requires.

.infer(< path|glob|globs|ReadableStream >[,options][,callback])

Example usage:

codepaint.infer('**/**.js',{details:true},function(inferredStyle){console.log(inferredStyle);});

.xform(< path|glob|globs|ReadableStream >[,options][,callback])

Example usage:

codepaint.xform('input.js',{indent_size:4},function(err,xformed,skipped,errored){if(err){throwerr;}console.log('transformed:',xformed);console.log('skipped:',skipped);console.log('errored:',errored);});

The following example infers formatting style fromsample.js and uses thatinferred style to transform all .js files under the current directory.

codepaint.infer('sample.js',function(inferredStyle){codepainter.xform('**/**.js',{style:inferredStyle});});

'sample.js' could also be an array or any readable stream.transform is analias for thexform method. You can use either one.

Great, so that's all nice and simple, but maybe you want to do something withthe output. We start by creating an instance of the Transformer class.

varTransformer=require('codepainter').Transformer;vartransformer=newTransformer();

Now, we can listen to any of the following events:

cascade

Every time one style cascades over another.

transformer.on('cascade',cascade);functioncascade(styleBefore,styleToMerge,styleType){// code here}

transform

Every time a file is transformed.

transformer.on('transform',function(transformed,path){// code here}

error

transformer.on('error',function(err,inputPath){// code here}

end

When all transformations have taken place.

transformer.on('end',function(err,transformed,skipped,errored){// code here}

Of course, none of these events will fire if you don't perform the transform:

transformer.transform(globs, options);

CLI Examples

$ codepaint infer "**/*.js"

Infers formatting style from all .js files under the current directory into asingle JSON object, which you can pipe out to another file if you want. It canthen be used in a transformation (below).

If you want to create an.editorconfig file, use the--ini flag:

$ codepaint infer --ini "**/*.js" > .editorconfig

Moving on to thexform sub-command:

$ codepaint xform "**/*.js"

This doesn't transform any files, but it does show you how many files would beaffected by the glob you've provided. Globs absolutelymust be in quotes oryou will experience unexpected behavior!

$ codepaint xform -i infer.js "**/*.js"

Transforms all .js files under the current directory with the formatting styleinferred from infer.js

$ codepaint xform -p idiomatic "**/*.js"

Transforms all .js files under the current directory with a Code Painterpre-defined style. In this case, Idiomatic. The only other pre-defined stylesavailable at this time are mediawiki and hautelook.

$ codepaint xform -j custom.json "**/*.js"

Transforms all .js files under the current directory with a custom style inJSON format.

$ codepaint xform -s indent_style=space -s indent_size=4 "**/*.js"

Transforms all .js files under the current directory with 2 settings:indent_style=space andindent_size=4. You can specify as many settings asyou want and you can set values tonull to disable them.

$ codepaint xform -e "**/*.js"

Transforms all .js files under the current directory with the EditorConfigsettings defined for each individual file.

Refer toEditorConfig Core Installation for installation instructions andEditorConfig for more information, including how to define and use.editorconfig files.

$ codepaint xform -i infer.js -p idiomatic -j custom.json-s end_of_line=null -e  "**/*.js"

As you can see, you can use as many options as you want. Code Painter willcascade your styles and report how the cascade has been performed, like so:

  Inferred style:   + indent_style = tab   + insert_final_newline = true   + quote_type = auto   + space_after_anonymous_functions = false   + space_after_control_statements = false   + spaces_around_operators = false   + trim_trailing_whitespace = false   + spaces_in_brackets = false  hautelook style:   * indent_style = space   + indent_size = 4   * trim_trailing_whitespace = true   + end_of_line = lf   = insert_final_newline = true   = quote_type = auto   * spaces_around_operators = true   = space_after_control_statements = true   = space_after_anonymous_functions = false   * spaces_in_brackets = false  Supplied JSON file:   * space_after_control_statements = true   = indent_style = space   * indent_size = 3  Inline styles:   x end_of_line = null  Editor Config:   + applied on a file-by-file basis  ...........................  REPORT: 27 files transformed

Supported Style Properties

codepaint:false

Tells CodePainter to skip the file (no formatting). This property reallyonly makes sense if you are using the--editor-config CLI option. Thisallows you to, for example, skip a vendor scripts directory.

EditorConfig properties

indent_style,indent_size,end_of_line,trim_trailing_whitespace andinsert_final_newline.

Refer toEditorConfig's documentation for more information.

quote_type:single,double,auto

Specifies what kind of quoting you would like to use for string literals:

console.log("Hello world!");// becomes console.log('Hello world!');

Adds proper escaping when necessary, obviously.

console.log('Foo "Bar" Baz');// becomes console.log("Foo \"Bar\" Baz");

Theauto setting infers the quoting with a precedence towardsinglemode.

console.log("Foo \"Bar\" Baz");// becomes console.log('Foo "Bar" Baz');console.log('Foo \'Bar\' Baz');// becomes console.log("Foo 'Bar' Baz");

space_after_control_statements:true,false

Specifies whether or not there should be a space between if/for/while andthe following open paren:

If true:

if(x===4){}// becomes if (x === 4) {}

If false:

while(foo()){}// becomes while(foo()) {}

space_after_anonymous_functions:true,false

Specifies whether or not there should be a space between thefunctionkeyword and the following parens in anonymous functions:

function(x){}// becomes function (x) {}

spaces_around_operators:true,false,hybrid

Specifies whether or not there should be spaces around operators such as+,=,+=,>=,!==.

x=4;// becomes x=4;a>=b;// becomes a >= b;a>>2;// becomes a >> 2;

Unary operators!,~,+,- are an exception to the rule; thus, no spacesare added. Also, any non-conditional: operators do not receive a space(i.e., the switch...case operator and property identifiers):

switch(someVar){case'foo' :// becomes case 'foo':varx={foo :'bar'};// becomes {foo: 'bar'}break;}

Hybrid mode is mostly like thetrue setting, except it behaves asfalse on operators*,/,%:

varx=4*2+1/7;// becomes var x = 4*2 + 1/7;

spaces_in_brackets:true,false,hybrid

Specifies whether or not there should be spaces inside brackets, whichincludes(),[],{}. Empty pairs of brackets will always be shortened.

If true:

if(x===4){}// becomes if ( x === 4 ) {}

If false:

if(x===4){}// becomes if (x === 4)

Thehybrid setting mostly reflects Idiomatic style. Refer toIdiomatic Style Manifesto.

Pipes and Redirects

On a unix command-line, you can transform a file from the stdin stream:

$ codepaint xform -s indent_size=2 < input.js

The stdout stream works a bit differently. Since Code Painter can transformmultiple files via glob syntax, it wouldn't make sense to output thetransformations of all those files to a single stream. Instead, only if youare using stdin as input and no-o, --output option is provided will CodePainter send the transformation to the stdout stream:

$ codepaint xform -s indent_size=2 < input.js > output.js

Piping is supported as well:

$ codepaint xform -s indent_size=2 < input.js | othercommand`

Git Clean and Smudge Filters

Because Code Painter supports stdin and stdout streams, as explained above,Git "clean" and "smudge" filters can be used as well.

CAUTION: My personal experience has shown inconsistent results, so use withcaution! Also, please contact me if you figure out how to do this without anyhiccups.

First, change your.gitattributes file to use your new filter. We'll call it"codepaint".

*.js   filter=codepaint

Then, tell Git what the "codepaint" filter does. First, we will convert codeto tabs upon checkout with the "smudge" filter:

$ git config filter.codepaint.smudge "codepaint xform -s indent_style=tab"

Then, upon staging of files with the Git "clean" filter, the style is restoredto spaces and cleaned to reflect any other style preferences you may have set:

$ git config filter.codepaint.clean "codepaint xform -p style.json"

This allows you to work in the indentation of your preference without steppingon anyone's toes and checking in inconsistent indentation. Or maybe you haveyour own preference for spaces around operators? Smudge it to your preferenceand clean it to your company's formatting style.

WARNING: Git "clean" and "smudge" filters are bypassed with GitHub forWindows.

Refer toGit's documentation for more information on Git "smudge" and"clean" filters.

Recommended Use

It is highly recommended that you use the EditorConfig approach to paintingyour code. To do so, do the following:

Place an.editorconfig file at your project root. Refer to thisproject's.editorconfig file for a point of reference as to how thismight look. You can also scatter.editorconfig files elsewherethroughout your project to prevent Code Painter from doing anytransformations (e.g., your vendor scripts folders). In this case, the.editorconfig file would simply read:codepaint = false.

Specify Code Painter in your devDependencies section of your package.json:

{"devDependencies": {"codepainter":"~0.3.15"    }}

Define acodepaint script in the scripts section of your package.json:

{"scripts": {"codepaint":"node node_modules/codepainter/bin/codepaint xform -e **/**.js"    }}

If you have Code Painter installed globally, the command is as simple as:

{"scripts": {"codepaint":"codepaint xform -e **/**.js"    }}

But Code Painter wouldn't install globally by default, so the firstapproach is the recommended one. Then, you can run Code Painter on yourentire project, consistently, with the following command:

$ npm run-script codepaint

Youcould runcodepaint manually every time you want to do it, but youmight find this next.bashrc shortcut more useful. The idea is to runthisgc alias to a newly-definedcodepaint_git_commit function. This,you do instead of runninggit commit. The caveat is that you need tostage your changes withgit add before doing so. This is because thecommand runscodepaint only on staged.js files. Aside from thiscaveat, you can commit things mostly the same as you were used to before.Now,gc can paint your code before a commit and bail-out of the commitif there are issues with the process (e.g., JavaScript parse errors). Theidea of formatting code before a commit is definitely controversial, butif you choose to do so anyway, here's the neat trick to put in your.bashrc file:

# Example usage: gc "initial commit"alias gc=codepaint_git_commitcodepaint_git_commit() {# 1. Gets a list of .js files in git staging and sends the list to CodePainter.# 2. CodePainter with the -e flag applies rules defined in your EditorConfig file(s).# 3. After CodePainter is done, your args are passed to the `git commit` command.    jsfiles=$(git diff --name-only --cached| egrep'\.js$')if [$jsfiles ];then        ./node_modules/codepainter/bin/codepaint xform -e$jsfilesfi    git commit -m"$@"}

You could also compare Code Painter's output with the original file on a Gitpre-commit hook and reject the commit if the files don't match. Let's be realthough. This would happen almostevery time you commit and it would be aroyal pain in your workflow.

There are so many ways you could use Code Painter. How do you prefer to useCode Painter? Feel free to contact me, Jed, with tips or suggestions. Seepackage.json for contact information).

Enforcing

Code Painter can be used to enforce a formatting style in a number of creativeways. To failTravis CI if code does not comply with your organization'sstyle guide, the process would work something like this:

  1. Run Code Painter on the code base.
  2. Fail Travis if any file changes are detected. This encourages developersto run Code Painter before pushing code.

Running Code Painter with Travis is as simple as adding the command to thebefore_script section of your.travis.yml file:

before_script:  -node node_modules/codepainter/bin/codepaint xform -e "**/**.js"

Notice I didn't use the commandnpm run-script codepaint. This is becausethere were issues with the double-quoted glob being processed. If you find away around this, please let me know.

Next, you need to create a node script that exits the node process with anon-zero code if any changes are detected. This, we do withgit diff:

varclc=require('cli-color');varspawn=require('child_process').spawn;vargit=spawn('git',['diff','--name-only']);git.stdout.setEncoding('utf8');git.stdout.on('data',exitWithErrorIfFilesHaveChanged);functionexitWithErrorIfFilesHaveChanged(data){console.log();console.log(clc.red('Error: The following files do not conform to the CompanyX style guide:'));console.log(data);process.exit(1);}

Finally, you can add this script to your.travis.yml file in thescriptsection:

script:  -node gitdiff.js

Violä! Travis should now fail if code does not comply with your organization'sstyle guide.

License

Released under the MIT license.

Bitdeli Badge

About

A JavaScript beautifier that can both infer coding style and transform code to reflect that style. You can also set style preferences explicitly in a variety of ways.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript100.0%

[8]ページ先頭

©2009-2025 Movatter.jp