2013年11月25日月曜日

KateでHTML/XMLをフォーマット

前回に引き続き、今度はHTML/XMLのフォーマット(整形)のためのKate用Scriptを書いてみました。

beautifyHTML.js
/* kate-script
 * author: akirattii, <tanaka.akira.2006@gmail.com>
 * license: BSD
 * revision: 1
 * kate-version: 3.11.2
 * type: commands
 * functions: beautify
 */
require("range.js");

function help(cmd) {
  if (cmd == "beautify") {
    return i18n("beautify");
  }
}

function action(cmd) {
  var a = new Object();
  if (cmd == "beautify") {
    a.text = i18n("beautify");
    a.icon = "";
    a.category = "HTML/XML";
    a.interactive = false;
    a.shortcut = "";
  }
  return a;
}

function beautify() {
  var selectionRange = view.selection();
  if (view.hasSelection()) {
    if (selectionRange.isValid()) {
      var fromLine = selectionRange.start.line;
      var toLine = selectionRange.end.line;
      var fromColumn = selectionRange.start.column;
      var toColumn = selectionRange.end.column;
      
      var newCode = _formatXML(view.selectedText(), 2);

      document.editBegin();
      document.removeText(fromLine, fromColumn, toLine, toColumn);
      document.insertText(fromLine, fromColumn, newCode);
      document.editEnd();
    }
  }
}


function _formatXML(text, step) {

  var ar = text.replace(/>\s{0,}</g, "><")
    .replace(/</g, "~::~<")
    .replace(/xmlns\:/g, "~::~xmlns:")
    .replace(/xmlns\=/g, "~::~xmlns=")
    .split('~::~');
  var len = ar.length;
  var inComment = false;
  var deep = 0;
  var str = '';
  var ix = 0;
  var shift = _createShiftArr(step);

  for (ix = 0; ix < len; ix++) {
    // start comment or <![CDATA[...]]> or <!DOCTYPE //
    if (ar[ix].search(/<!/) > -1) {
      str += shift[deep] + ar[ix];
      inComment = true;
      // end comment  or <![CDATA[...]]> //
      if (ar[ix].search(/-->/) > -1 || ar[ix].search(/\]>/) > -1 || ar[ix].search(/!DOCTYPE/) > -1) {
        inComment = false;
      }
    } else
    // end comment  or <![CDATA[...]]> //
    if (ar[ix].search(/-->/) > -1 || ar[ix].search(/\]>/) > -1) {
      str += ar[ix];
      inComment = false;
    } else
    // <elm></elm> //
    if (/^<\w/.exec(ar[ix - 1]) && /^<\/\w/.exec(ar[ix]) && /^<[\w:\-\.\,]+/.exec(ar[ix - 1]) == /^<\/[\w:\-\.\,]+/.exec(ar[ix])[0].replace('/', '')) {
      str += ar[ix];
      if (!inComment) deep--;
    } else
    // <elm> //
    if (ar[ix].search(/<\w/) > -1 && ar[ix].search(/<\//) == -1 && ar[ix].search(/\/>/) == -1) {
      str = !inComment ? str += shift[deep++] + ar[ix] : str += ar[ix];
    } else
    // <elm>...</elm> //
    if (ar[ix].search(/<\w/) > -1 && ar[ix].search(/<\//) > -1) {
      str = !inComment ? str += shift[deep] + ar[ix] : str += ar[ix];
    } else
    // </elm> //
    if (ar[ix].search(/<\//) > -1) {
      str = !inComment ? str += shift[--deep] + ar[ix] : str += ar[ix];
    } else
    // <elm/> //
    if (ar[ix].search(/\/>/) > -1) {
      str = !inComment ? str += shift[deep] + ar[ix] : str += ar[ix];
    } else
    // <? xml ... ?> //
    if (ar[ix].search(/<\?/) > -1) {
      str += shift[deep] + ar[ix];
    } else
    // xmlns //
    if (ar[ix].search(/xmlns\:/) > -1 || ar[ix].search(/xmlns\=/) > -1) {
      str += shift[deep] + ar[ix];
    } else {
      str += ar[ix];
    }
  }
  return (str[0] == '\n') ? str.slice(1) : str;
}

function _createShiftArr(step) {

  var space = '    ';

  if (isNaN(parseInt(step))) { // argument is string
    space = step;
  } else { // argument is integer
    switch (step) {
    case 1:
      space = ' ';
      break;
    case 2:
      space = '  ';
      break;
    case 3:
      space = '   ';
      break;
    case 4:
      space = '    ';
      break;
    case 5:
      space = '     ';
      break;
    case 6:
      space = '      ';
      break;
    case 7:
      space = '       ';
      break;
    case 8:
      space = '        ';
      break;
    case 9:
      space = '         ';
      break;
    case 10:
      space = '          ';
      break;
    case 11:
      space = '           ';
      break;
    case 12:
      space = '            ';
      break;
    }
  }

  var shift = ['\n']; // array of shifts
  for (ix = 0; ix < 100; ix++) {
    shift.push(shift[ix] + space);
  }
  return shift;
}

これを例によって
/usr/share/kde4/apps/katepart/script/commands
にコピーして、Kateを再起動すればOK。

KateでHTMLファイルを開いて、フォーマットしたい箇所を選択し、

Tools > Scripts > HTML/XML > beautify

を実行すればHTMLがフォーマットされます。

0 件のコメント:

コメントを投稿