<commit_before>/* global atom */

'use strict';

var beautifyJS = require('js-beautify');
var beautifyHTML = require('js-beautify').html;
var beautifyCSS = require('js-beautify').css;
var fs = require('fs');
var path = require('path');
var nopt = require('nopt');
var extend = require('extend');
var _ = require('lodash');

// TODO: Copied from jsbeautify, please update it from time to time
var knownOpts = {
  // Beautifier
  'indent_size': Number,
  'indent_char': String,
  'indent_level': Number,
  'indent_with_tabs': Boolean,
  'preserve_newlines': Boolean,
  'max_preserve_newlines': Number,
  'space_in_paren': Boolean,
  'jslint_happy': Boolean,
  // TODO: expand-strict is obsolete, now identical to expand.  Remove in future version
  'brace_style': ['collapse', 'expand', 'end-expand', 'expand-strict'],
  'break_chained_methods': Boolean,
  'keep_array_indentation': Boolean,
  'unescape_strings': Boolean,
  'wrap_line_length': Number,
  'e4x': Boolean,
  // HTML-only
  'max_char': Number, // obsolete since 1.3.5
  'unformatted': [String, Array],
  'indent_inner_html': [Boolean],
  'indent_scripts': ['keep', 'separate', 'normal'],
  // CLI
  'version': Boolean,
  'help': Boolean,
  'files': [path, Array],
  'outfile': path,
  'replace': Boolean,
  'quiet': Boolean,
  'type': ['js', 'css', 'html'],
  'config': path
};

var Subscriber = require('emissary').Subscriber;
var plugin = module.exports;
Subscriber.extend(plugin);

function verifyExists(fullPath) {
  return fs.existsSync(fullPath) ? fullPath : null;
}

function findRecursive(dir, fileName) {
  var fullPath = path.join(dir, fileName);
  var nextDir = path.dirname(dir);
  var result = verifyExists(fullPath);

  if (!result && (nextDir !== dir)) {
    result = findRecursive(nextDir, fileName);
  }

  return result;
}

function getUserHome() {
  return process.env.HOME || process.env.USERPROFILE;
}

function cleanOptions(data, types) {
  nopt.clean(data, types);
  return data;
}

function getCursors(editor) {
  var cursors = editor.getCursors();
  var posArray = [];
  for (var idx = 0; idx < cursors.length; idx++) {
    var cursor = cursors[idx];
    var bufferPosition = cursor.getBufferPosition();
    posArray.push([bufferPosition.row, bufferPosition.column]);
  }
  return posArray;
}

function setCursors(editor, posArray) {
  for (var idx = 0; idx < posArray.length; idx++) {
    var bufferPosition = posArray[idx];
    if (idx === 0) {
      editor.setCursorBufferPosition(bufferPosition);
      continue;
    }
    editor.addCursorAtBufferPosition(bufferPosition);
  }
}

function beautify() {
  var text;
  var editor = atom.workspace.getActiveEditor();
  var isSelection = !! editor.getSelectedText();
  var softTabs = editor.softTabs;
  var tabLength = editor.getTabLength();

  var beautifyOptions = {
    'indent_size': softTabs ? tabLength : 1,
    'indent_char': softTabs ? ' ' : '\t',
    'indent_with_tabs': !softTabs
  };

  // Look for .jsbeautifierrc in file and home path, check env variables
  var editedFilePath = editor.getPath();
  var rcInRecursiveCwd;
  if (editedFilePath && (rcInRecursiveCwd = findRecursive(path.dirname(
    editedFilePath), '.jsbeautifyrc')) === editedFilePath) {
    rcInRecursiveCwd = null;
  }
  var rcInHomePath;
  if (editedFilePath && (rcInHomePath = verifyExists(path.join(getUserHome() ||
    '', '.jsbeautifyrc'))) === editedFilePath) {
    rcInHomePath = null;
  }

  var externalOptions;

  if (rcInRecursiveCwd) {
    externalOptions = JSON.parse(fs.readFileSync(rcInRecursiveCwd, {
      encoding: 'utf8'
    }));
  } else if (rcInHomePath) {
    externalOptions = JSON.parse(fs.readFileSync(rcInHomePath, {
      encoding: 'utf8'
    }));
  } else {
    externalOptions = {};
  }

  var containsNested = false;
  var collectedConfig = {};
  var key;

  // Check to see if config file uses nested object format to split up js/css/html options
  for (key in externalOptions) {
    if (typeof externalOptions[key] === 'object') {
      containsNested = true;
    }
  }

  // Create a flat object of config options if nested format was used
  if (!containsNested) {
    collectedConfig = externalOptions;
  } else {
    for (key in externalOptions) {
      _.merge(collectedConfig, externalOptions[key]);
    }
  }

  beautifyOptions = extend(collectedConfig, beautifyOptions);
  beautifyOptions = cleanOptions(beautifyOptions, knownOpts);

  if (isSelection) {
    text = editor.getSelectedText();
  } else {
    text = editor.getText();
  }
  var oldText = text;

  switch (editor.getGrammar().name) {
  case 'JavaScript':
    text = beautifyJS(text, beautifyOptions);
    break;
  case 'HTML':
  case 'XML':
    text = beautifyHTML(text, beautifyOptions);
    break;
  case 'CSS':
    text = beautifyCSS(text, beautifyOptions);<commit_msg>Update atom-beautify.js<commit_after>/* global atom */

'use strict';

var beautifyJS = require('js-beautify');
var beautifyHTML = require('js-beautify').html;
var beautifyCSS = require('js-beautify').css;
var fs = require('fs');
var path = require('path');
var nopt = require('nopt');
var extend = require('extend');
var _ = require('lodash');

// TODO: Copied from jsbeautify, please update it from time to time
var knownOpts = {
  // Beautifier
  'indent_size': Number,
  'indent_char': String,
  'indent_level': Number,
  'indent_with_tabs': Boolean,
  'preserve_newlines': Boolean,
  'max_preserve_newlines': Number,
  'space_in_paren': Boolean,
  'jslint_happy': Boolean,
  // TODO: expand-strict is obsolete, now identical to expand.  Remove in future version
  'brace_style': ['collapse', 'expand', 'end-expand', 'expand-strict'],
  'break_chained_methods': Boolean,
  'keep_array_indentation': Boolean,
  'unescape_strings': Boolean,
  'wrap_line_length': Number,
  'e4x': Boolean,
  // HTML-only
  'max_char': Number, // obsolete since 1.3.5
  'unformatted': [String, Array],
  'indent_inner_html': [Boolean],
  'indent_scripts': ['keep', 'separate', 'normal'],
  // CLI
  'version': Boolean,
  'help': Boolean,
  'files': [path, Array],
  'outfile': path,
  'replace': Boolean,
  'quiet': Boolean,
  'type': ['js', 'css', 'html'],
  'config': path
};

var Subscriber = require('emissary').Subscriber;
var plugin = module.exports;
Subscriber.extend(plugin);

function verifyExists(fullPath) {
  return fs.existsSync(fullPath) ? fullPath : null;
}

function findRecursive(dir, fileName) {
  var fullPath = path.join(dir, fileName);
  var nextDir = path.dirname(dir);
  var result = verifyExists(fullPath);

  if (!result && (nextDir !== dir)) {
    result = findRecursive(nextDir, fileName);
  }

  return result;
}

function getUserHome() {
  return process.env.HOME || process.env.USERPROFILE;
}

function cleanOptions(data, types) {
  nopt.clean(data, types);
  return data;
}

function getCursors(editor) {
  var cursors = editor.getCursors();
  var posArray = [];
  for (var idx = 0; idx < cursors.length; idx++) {
    var cursor = cursors[idx];
    var bufferPosition = cursor.getBufferPosition();
    posArray.push([bufferPosition.row, bufferPosition.column]);
  }
  return posArray;
}

function setCursors(editor, posArray) {
  for (var idx = 0; idx < posArray.length; idx++) {
    var bufferPosition = posArray[idx];
    if (idx === 0) {
      editor.setCursorBufferPosition(bufferPosition);
      continue;
    }
    editor.addCursorAtBufferPosition(bufferPosition);
  }
}

function beautify() {
  var text;
  var editor = atom.workspace.getActiveEditor();
  var isSelection = !! editor.getSelectedText();
  var softTabs = editor.softTabs;
  var tabLength = editor.getTabLength();

  var beautifyOptions = {
    'indent_size': softTabs ? tabLength : 1,
    'indent_char': softTabs ? ' ' : '\t',
    'indent_with_tabs': !softTabs
  };

  // Look for .jsbeautifierrc in file and home path, check env variables
  var editedFilePath = editor.getPath();
  var rcInRecursiveCwd;
  if (editedFilePath && (rcInRecursiveCwd = findRecursive(path.dirname(
    editedFilePath), '.jsbeautifyrc')) === editedFilePath) {
    rcInRecursiveCwd = null;
  }
  var rcInHomePath;
  if (editedFilePath && (rcInHomePath = verifyExists(path.join(getUserHome() ||
    '', '.jsbeautifyrc'))) === editedFilePath) {
    rcInHomePath = null;
  }

  var externalOptions;

  if (rcInRecursiveCwd) {
    externalOptions = JSON.parse(fs.readFileSync(rcInRecursiveCwd, {
      encoding: 'utf8'
    }));
  } else if (rcInHomePath) {
    externalOptions = JSON.parse(fs.readFileSync(rcInHomePath, {
      encoding: 'utf8'
    }));
  } else {
    externalOptions = {};
  }

  var containsNested = false;
  var collectedConfig = {};
  var key;

  // Check to see if config file uses nested object format to split up js/css/html options
  for (key in externalOptions) {
    if (typeof externalOptions[key] === 'object') {
      containsNested = true;
    }
  }

  // Create a flat object of config options if nested format was used
  if (!containsNested) {
    collectedConfig = externalOptions;
  } else {
    for (key in externalOptions) {
      _.merge(collectedConfig, externalOptions[key]);
    }
  }

  beautifyOptions = extend(collectedConfig, beautifyOptions);
  beautifyOptions = cleanOptions(beautifyOptions, knownOpts);

  if (isSelection) {
    text = editor.getSelectedText();
  } else {
    text = editor.getText();
  }
  var oldText = text;

  switch (editor.getGrammar().name) {
  case 'JavaScript':
    text = beautifyJS(text, beautifyOptions);
    break;
  case 'HTML (Liquid)':
  case 'HTML':
  case 'XML':
    text = beautifyHTML(text, beautifyOptions);
    break;
  case 'CSS':
    text = beautifyCSS(text, beautifyOptions);
{'fraction_non_alphanumeric': 0.13945507487520797, 'fraction_numerical': 0.0020798668885191347, 'mean_word_length': 4.006246746486205, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7017312', 'n_tokens_mistral': 3187, 'n_tokens_neox': 3154, 'n_words': 765}