昇順で並び替え/降順で並び替え

提供: MeryWiki
ナビゲーションに移動 検索に移動

昇順/降順 トグル[編集]

ショートカットキーやツールバーアイコンの削減用に Mery のインストーラ/ZIP に同梱されている「昇順で並び替え」マクロと「降順で並び替え」マクロをひとつにまとめてみました。

連続で実行すると  昇順 → 降順 → 昇順 → 降順 → ...  でトグルします。
もとの並び順に戻す場合は Undo(Ctrl+Z)してください。

  • 並べ替えした選択範囲内のブックマークは解除されます。
  • 並べ替えのルールを細かく指定したいばあいは「行並べ替え」マクロが便利です。

ソースコード[編集]

  • 2020/05/04: 行数を詰めました
#title = "昇順/降順 トグル"
#tooltip = "昇順で並べ替え/降順で並べ替え"
// #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",145

// --------------------------------------------------------
// 昇順で並べ替え/降順で並べ替え
// Original Copyright (c) Kuro. All Rights Reserved.
// www: https://www.haijin-boys.com/
// --------------------------------------------------------
// Modified by sukemaru, (2019/06/03 - 2020/05/04)
// --------------------------------------------------------

var s = document.selection;

// 選択範囲がなければ文書全体を範囲選択
if ( s.IsEmpty ) {
  s.SelectAll();
}
var act = s.GetActivePos();
var anc = s.GetAnchorPos();

// 昇順で並べ替え
var st = s.Text.replace( /\n?$/, "" ).split( "\n" )
               .sort()
               .join( "\n" ) + RegExp["$&"];
}

// すでに昇順だった場合は降順で並べ替え
if ( st == s.Text ) { {
  st = st.replace( /\n?$/, "" ).split( "\n" )
         .reverse()
         .join( "\n" ) + RegExp["$&"];
}

if ( st != s.Text ) {
  s.Text = st;
}

// 選択範囲を復帰
s.SetActivePos( act );
s.SetAnchorPos( anc );

昇順/降順トグル + 文字列反転[編集]

GetKeyState.exe(キー状態取得実行ファイル)」を利用した「文字列の順番を逆に書き出す」マクロ(あいうえお ⇔ おえういあ)との統合バージョンです。

  • Ctrl キーを押しながらマクロを実行したときは、選択範囲内の文字列を反転します。
  • 設定項目の追加により、行の並べ替え(昇順/降順トグル)機能では行頭の半角数字を数値で評価してソートできます。
  • 並べ替えした選択範囲内のブックマークは解除されます。
  • 文字列反転モードでは『テキスト整形』マクロの「文字を逆順並べ」コマンド(masme氏, 2017/06/25)のコードを移植させていただきました(結合文字への対応)。

マクロライブラリ の「GetKeyState.exe(キー状態取得実行ファイル)」のページから ZIP 書庫をダウンロードし、解凍した中の実行ファイル GetKeyState.exe を Mery インストールフォルダ内の Macros フォルダに配置してください。

  • GetKeyState.exe を導入していない場合は「文字列反転」機能が使用できなくなります(昇順/降順トグルの機能のみ利用できます)。

設定項目[編集]

  • 選択範囲がないとき: autoSelection
選択範囲がない状態でマクロを実行したときに自動的に範囲選択してから並べ替えをします。
  • 0: なにもしない(自動選択なし)
  • 1: カーソル位置の単語を自動選択
  • 2: カーソル位置の行全体(表示行)を自動選択
  • 3: カーソル位置の行全体(論理行)を自動選択
  • 4: 文書全体を自動選択
※ 1 ~ 3 で自動選択をするのは「文字列反転モード」のときのみ。
※ 選択範囲があるときは、開始/終了 位置の拡張はしません。
※ 初期値は 1 になっています。
  • 行並べ替えのとき、行頭の半角数字を正の整数値で評価してソート: digitsAsNumber
行頭の半角数字を正の整数値で評価して 昇順/降順 で並べ替えをします。
  • true:  1 < 002 < 3 < 10 < 020 (数値順)
  • false: 002 < 020 < 1 < 10 < 3 (文字順 @ unicode)
※ ただし、いずれの場合でも小数点やカンマ(桁区切り)などの記号以下は文字列あつかい(行頭の数字の最初の整数部分以外は文字列あつかい)。
e.g. 2.15 < 2.2 < 3.0.0 < 4'100 < 4,000 < 4.300 < 300 < 4200
e.g. 1 - 002 < 1 - 020 < 1 - 1 < 1 - 10 < 1 - 3
※ 半角ハイフン-マイナスが付いている場合は数字部分のみを数値あつかい
e.g. -1 < -2 < -10 < 0 < 1 < 2 < 10
※ 行頭に字下げ、開きカッコ、ビュレット、矢印、通貨記号、ギリシャ文字、ローマ数字などの前置記号が半角数字の前にあっても可(半角数字より前に通常の文字列があるばあいは、半角数字もすべて文字列あつかい)。
※ 半角数字より前の部分が完全一致しないばあいは、数値として評価しません。
  • Ctrl キーで「文字列反転モード」ON: charModeEnable
  • true: Ctrl キーで「文字列を1文字単位で反転」モードに
e.g. あいうえお ⇒ おえういあ
  • false: つねに論理行単位での「昇順/降順 トグル」で並べ替え
※ 「文字列反転モード」をいっさい使用しない(外部実行ファイル GetKeyState.exe による Ctrlキーの ON/OFF 判定をしないことで、「昇順/降順 トグル」機能の起動を高速化)
  • 「文字列反転モード」のときに行の並び順も入れ替える: reverseVertical
  • true: 行の並び順(上下関係)も反転
e.g.	「あいうえお」	⇒	」こけくきか「
     	「かきくけこ」	⇒	」おえういあ「
  • false: 行の並び順は入れ替えない
e.g.	「あいうえお」	⇒	」おえういあ「
     	「かきくけこ」	⇒	」こけくきか「
  • GetKeyState.exe のフルパスを指定: gksPath
未指定 gksPath = "" なら、Mery インストールフォルダの Macros\GetKeyState.exe
※ GetKeyState.exe なしのときも gksPath = "" にします(「文字列反転モード」は利用できません)。
※ パス指定での区切り文字の \ 記号は、ふたつがさね \\ で記述してください。

ソースコード[編集]

ダウンロード >> 「ファイル:昇順/降順トグル + 文字列反転.zip」(アイコン入り)

※ このマクロは実行コードに shift_JIS の範囲外の文字を使用しています

#title = "昇順/降順トグル + 文字列反転"
#tooltip = "昇順で並べ替え/降順で並べ替え / Ctrl キーで文字列反転"
//#icon = "Mery用 マテリアルデザインっぽいアイコン.icl",145
//#icon = "sort_by_alpha_a_to_z.ico"

var start = new Date();	// 所要時間計測(開始)

/**
 * --------------------------------------------------------
 * 昇順で並べ替え/降順で並べ替え/文字列反転
 * sukemaru, 2020/05/04
 * --------------------------------------------------------
 * 論理行単位での 昇順/降順 で並べ替え、
 * または1文字単位での文字列の反転を実行します。
 * 
 * ※ 1文字単位で文字列を反転する機能には GetKeyState.exe が必用です。
 *   GetKeyState.exe がない場合は、論理行単位での 昇順/降順 で並べ替えしかできません。
 * ※ 文字列反転モードでは、『テキスト整形』マクロ(masme氏)
 *   https://www.haijin-boys.com/wiki/テキスト整形#並べ替え
 *   の「文字を逆順並べ」コマンド(2017/06/25)のコードを移植させていただきました。
 */

// ---------- ▼ 設定項目 ▼ ---------- //

// ■ 選択範囲がないとき
var autoSelection = 1;
	/**
	 * 0: なにもしない
	 * 1: カーソル位置の単語を自動選択
	 * 2: カーソル位置の行全体(表示行)を自動選択
	 * 3: カーソル位置の行全体(論理行)を自動選択
	 * 4: 文書全体を自動選択
	 * ※ 1~3 で自動選択をするのは「文字列反転モード」が ON のときのみ。
	 * ※ 選択範囲があるとき、開始/終了 位置の拡張はしません。
	 */

// ■ 行並べ替えのとき、行頭の半角数字を正の整数値で評価してソート
var digitsAsNumber = true;
	/**
	 * true:	1  <  002  <  3  <  10  <  020	(数値順)
	 * false:	002  <  020  <  1  <  10  <  3	(文字順 @ unicode)
	 * ※ ただし、いずれの場合でも小数点やカンマ(桁区切り)などの記号以下は文字列あつかい
	 *    (行頭の数字の最初の整数部分以外は文字列あつかい)
	 * ※ 半角ハイフン-マイナスが付いている場合は数字部分のみを数値あつかい
	 * ※ 行頭に字下げ、開きカッコ、ビュレットなどの前置記号が半角数字の前にあっても可
	 *   (数字より前に通常の文字列があるばあいは、半角数字もすべて文字列あつかい)
	 * ※ 数字より前の部分が完全一致しないばあいは、数値として評価しない
	 */

// ■ Ctrl キーで「文字列反転モード」ON
var charModeEnable = true;
	/**
	 * true のばあい、Ctrl キーで「文字列を1文字単位で反転」
	 *   e.g.	「あいうえお」	→	」おえういあ「
	 * false のばあい、論理行単位での 昇順/降順 で並べ替えのみ(高速)。
	 */

// ■「文字列反転モード」のときに行の並び順も入れ替える?
var reverseVertical = false;
	/**
	 * true:	「あいうえお」	→	」こけくきか「
	 *      	「かきくけこ」	→	」おえういあ「
	 * 
	 * false:	「あいうえお」	→	」おえういあ「
	 *       	「かきくけこ」	→	」こけくきか「
	 */

// ■ GetKeyState.exe のフルパスを指定する場合
var gksPath = "";
	/**
	 * 未指定 "" なら、Mery インストールフォルダの Macros\GetKeyState.exe
	 * ※ GetKeyState.exe なしのときも "" にすること。
	 * ※ パス指定での区切り文字の \ 記号はふたつがさね「\\」で記述すること。
	 */

// ---------- ▲ 設定項目 ▲ ---------- //

var d = editor.ActiveDocument,  s = d.selection;
var isEmpty = s.IsEmpty;

if ( d.ReadOnly ) {
  Status = " このドキュメントは書き換え禁止です。";
}
else if ( isEmpty && (
autoSelection == 0 || ( ! charModeEnable && autoSelection < 4 )
) ) {
  Status = " 選択範囲がありません。";
}

else {
  // GetKeyState.exe で Ctrl キーの状態を取得
  var charMode;
  var Fso = new ActiveXObject( "Scripting.FileSystemObject" );
  var WshShell = new ActiveXObject( "WScript.Shell" );
  var gks = gksPath || editor.FullName.replace( /[^\\]+$/, "Macros\\GetKeyState.exe" );
  if ( charModeEnable && Fso.FileExists( gks )
  && WshShell.Run( "\"" + gks + "\" Ctrl", 0, true ) != 0 ) {
    charMode = true;	// 文字列反転モードの確定
  }

  editor.ExecuteCommandByID( MEID_WINDOW_ACTIVE_PANE = 2189 );
  Redraw = false;
  var sx = ScrollX,  sy = ScrollY;
  var ay = s.GetActivePointY( mePosLogical );
  var pos = isEmpty ? s.GetActivePos() : -1;

  // 非選択時には自動選択
  if ( isEmpty ) {
    if ( charMode && autoSelection == 1 ) {
      s.SelectWord();
      if ( s.GetActivePointY( mePosLogical ) != ay ) {
        s.SetActivePos( pos );
      }
    }
    else if ( charMode && ( autoSelection == 2 || autoSelection == 3 ) ) {
      var posMode = autoSelection - 1;
      s.StartOfLine( false, posMode );
      s.EndOfLine( true, posMode );
    }
    else if ( autoSelection == 4 ) { s.SelectAll(); }
  }
  var st = tmp = s.Text;	// 確定した選択範囲を取得

  if ( st ) {
    var reg1 = /\n?$/,  n = st.match( reg1 );
    var anc = s.GetAnchorPos(),  act = s.GetActivePos();

    // 文字列を1文字単位で反転
    if ( charMode ) {
      Status = " 文字列を反転";

      // 『テキスト整形』マクロの「文字を逆順並べ」コマンド(masme氏, 2017/06/25)
      var regX = new RegExp( /[\x00-\x1F\x7F-\x9F\xAD\u2028\u2029\uFEFF]|(?:(?:\uD83C[\uDDE6-\uDDFF]){2}|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\s\S])(?:[\u0300-\u036F\u1AB0-\u1AFF\u1DC0-\u1DFF\u20D0-\u20FF\u3099\u309A\uFE20-\uFE2F\u200C\u200D\u180B-\u180D\uFE00-\uFE0F]|\uDB40[\uDD00-\uDDEF]|\uD83C[\uDFFB-\uDFFF])*/g ); 
      tmp = st.replace( /[^\n]+/g, function( str ) {
        return str.match( regX ).reverse().join( "" );
      } );

      if ( reverseVertical ) {
        tmp = tmp.replace( reg1, "" ).split( "\n" ).reverse().join( "\n" ) + n;
      }
    }

    else {
      // 昇順で並べ替え	
      Status = " 昇順で並べ替え";

      // 数値評価での行頭の字下げ、開きカッコ、ローマ数字、前置記号などの確認・比較
      // ※ 数字より前の字下げや文字列が完全に一致しないときは、数字も文字列あつかいとする
      // ※ $ \ 以外の通貨記号とギリシャ文字は数字の直前の1文字にかぎる
      var reg2 = /^([\t  ]*["#$'(*+,\-.\/:;<=>@[\\^_{§±¶×‐–—―’‘“”†‡•‣‥…※⁃Ⅰ-ⅿ←↑→↓⇒⇔∴∵⋮⋯■□▲△▼▽◆◇○●◦★☆☜☞⦅〈《「『【〔〖〘〚〝〜・+-(<@[{~⦅「・]*[¢£¥Α-ω€⏀¢£$¥]?[\t  ]*)([0-9]+)/;
      // ※閉じカッコ調整	}])’’””⦆〉》」』】〕〗〙〛〟)>]}⦆」

      tmp = st.replace( reg1, "" ).split( "\n" )
              .sort( function( a, b ) {
                  var aa = reg2.exec( a ),  a1 = aa ? aa[1] : "";
                  var bb = reg2.exec( b ),  b1 = bb ? bb[1] : "";
                  var a2 = a,  b2 = b;
                  if ( digitsAsNumber && aa && bb && a1 == b1 ) {
                    a2 = + aa[2];  b2 = + bb[2];
                  }
                  return ( a2 !== a && a2 != b2 ) ? a2 - b2
                       : ( a < b ) ? -1
                       : ( a > b ) ? 1
                       : 0;
              } )
              .join( "\n" ) + n;

      // すでに昇順だった場合は降順で並べ替え(反転)
      if ( tmp == st ) {
        Status = " 降順で並べ替え";
        tmp = st.replace( reg1, "" ).split( "\n" )
                .reverse()
                .join( "\n" ) + n;
      }
    }
  }

  // 並べ替え(または文字列反転)を実行
  if ( tmp != st ) {
    s.Text = tmp;
    // 選択範囲を復帰
    s.SetActivePos( charMode ? act : anc );
    s.SetActivePos( charMode ? anc : act, true );
  }
  // 並べ替え なし
  else {
    Status = " 並べ替えませんでした。";
    if ( pos >= 0 ) { s.SetActivePos( pos ); }
  }
  ScrollX = sx;  ScrollY = sy;
  Redraw = true;

  var elapsedSec = ( ( new Date() - start ) / 1000 ).toFixed( 3 );
  Status += " [ " + elapsedSec.replace( /\./, ". " ) + " 秒 ]";
}
スポンサーリンク