ブックマークを復元(Mery 2.7用)

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

スクリーンショット


ダウンロード[編集]

ダウンロード:ブックマークを復元(Mery_2.7用).zip」 (2019/04/07)


ブックマークを復元[編集]

あらかじめ Mery ver 2.6.x 以前の Mery.his ファイルを複製バックアップしてあれば、ver 2.7.0 以降で互換性がなくなって読みこまれなくなっているかもしれない(?)旧ブックマーク情報を復元することができます。

ブックマークを復元したいドキュメントをアクティブにして、このマクロを実行してください。
バックアップファイルにブックマーク情報が残っているかを確認ダイアログに表示します。
復元処理を実行して、デバッグログをアウトプットバーに表示します。

Mery.his のバックアップファイルのファイル名は規定値として Mery.his.old とし、Mery.his と同じフォルダに配置されているものと仮定していますが、ソースコード内の設定項目で任意のフォルダに置いたバックアップファイルを指定できます。

※ 設定項目で任意のバックアップファイルを指定するばあいは、\ 記号を二つ重ねにしたフルパスにしてください (フォルダパスの環境変数は使用できません)。
var hisPath = "C:\\HOGE\\Backup\\MeryHis.bak";	// ( 規定値:"" )
使用上の注意
  • Mery ver 2.7.0 以降のバージョンを起動してブックマーク情報が消えてしまった Mery.his ファイルからは「ブックマークを復元」できません。Mery 本体のバージョンアップ前に Mery.his をバックアップしていなかった場合は、残念ながら対応できません。
  • Mery ver 2.7.0 よりも前に作成・編集したドキュメントを Mery 2.7.0 以降または他のエディタで再編集・更新(文字数・行数の変更)をしている場合は、ブックマーク設定の復元が正しい行にたいしておこなわれないことがあります。
  • 設定項目で任意のバックアップファイルを指定しているとき、バックアップファイルが見つからなかった場合は規定の Mery.his.old ファイルを検索します。復元開始前のダイアログに表示される「履歴ファイルのパス」の部分を確認してから OK/キャンセル を選択してください。


おまけマクロ[編集]

以下のマクロを同梱(Mery の標準機能をツールバーアイコンにするためのマクロ)

  • 「ブックマークを設定/解除」マクロ
  • 「次のブックマーク」マクロ
  • 「前のブックマーク」マクロ
  • 「ブックマークをクリア」マクロ



※ それぞれ専用の「マテリアルデザインっぽいアイコン」入り


リンク[編集]

マクロ作成のきっかけ


マクロライブラリよりブックマーク関連のマクロ


ソースコード[編集]

#title = "ブックマークを復元"
#tooltip = "履歴のバックアップファイルからブックマークを復元する"
#icon = "bookmark_restore.ico"
#language = "JScript"


/**
 * 「ブックマークを復元」 2019/04/01 - 2019/04/07, sukemaru
 * 
 * Mery ver 2.7.0 以降は ver 2.6.x までの従来のブックマーク情報との互換性がなくなるかもしれないので、
 * "Mery.his のバックアップファイル" から旧ブックマーク情報を復元する機能を提供します。
 * 
 * ブックマーク設定を復元したいドキュメントをアクティブにして、このマクロを実行してください。
 * 
 * ※「ブックマークの復元」開始前に表示される確認ダイアログで "Mery.his のバックアップファイル" と
 *   "ブックマークを復元したいドキュメント" のファイルパスと最終更新日時を確認してから
 *   「ブックマークの復元」を実行するか判断してください。
 * 
 * ※ 規定値として、"Mery.his のバックアップファイル" の場所・ファイル名は、
 *   Mery.his ファイルのあるフォルダ内の "Mery.his.old" です (二重拡張子 .his.old )。
 * 
 * ※ 任意のフォルダに任意のファイル名でバックアップしたものを指定できます。
 *   指定されたバックアップファイルがない場合は、規定のファイルを検索します。
 * 
 * ※ このマクロでは、バックアップファイル文字コードが
 *   Mery.his とおなじままの UTF-8 でないと読み込み・検索ができません。
 * 
 * ※ 下記の順に "Mery.his のバックアップファイル" の実在確認をしてから、
 *   バックアップファイル内にドキュメントのブックマーク情報があるかを検索して、
 *   「ブックマークの復元」を実行します。
 *   バックアップファイルが見つからない場合や、ブックマーク情報が見つからない場合は、
 *   ダイアログを表示して「ブックマークの復元」を中止します。
 * 
 *  バックアップファイルの優先順位
 *  ① 設定項目で指定した任意のファイルパス
 *  ② Mery.exe のあるフォルダの Mery.his.old
 *  ③ %AppData% フォルダ配下の Mery\Mery.his.old
 * 
 * ※ ver 2.6.x 以前の Mery から ver 2.7.0 に更新したあとで
 *   対象のドキュメントを編集(文字数や行数の変更)していると、
 *   ブックマーク行がズレてしまうことがあります。
 * 
 * ※ ブックマークの復元操作は "アンドゥ" できません。
 * 
 * ・アウトプットバーに復元処理のログを出力します。
 *   アウトプットバーの表示切替のショートカットキーは [Alt+2]
 * 
 * ・ブックマーク行への移動は、ショートカットキー [F2] / [Shift+F2]
 *   ブックマーク行の設定/解除は、ショートカットキー [Ctrl+F2]
 * 
 * ・「ブックマークの復元」がうまくいかなかった場合は…
 *   編集メニュー >> ブックマーク >> ブックマークをクリア
 * 
 */

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

// ■ "Mery.his のバックアップファイル" の「ファイルパス」
var hisPath = "";	// ( 規定値:"" )

	// ・規定値:"" で Mery.exe のあるフォルダか %AppData% 配下の Mery フォルダ
	//   (Mery.his ファイルのあるフォルダ) から
	//   ファイル名 = "Mery.his.old" を自動検索します

	// ・任意のフォルダにあるファイルを指定する場合はフルパスで
	//   "C:\\HOGE\\Backup\\MeryHis.bak" のように \ を二つ重ねにすること
	//   (フォルダパスの環境変数は使用できません)


// ■ アウトプットバーにログを出力する?
var outputEnable = true;	// (する:true / しない:false)


// ---------- ▼ 実行コード ▼ ---------- //

{ RestoreBookmark(); Quit(); }


// ---------- ▼ 関数 ▼ ---------- //

/**
 * 関数 RestoreBookmark()
 * メイン
 * "Mery.his のバックアップファイル" を読みこんで、ブックマークを復元する
 */
function RestoreBookmark() {
  var docuPath = editor.ActiveDocument.FullName || "「無題」 ドキュメント";
  Output( "「ブックマークを復元」マクロ  (" + DateTimeUTC() + ")\n"
        + "ドキュメントのパス: \"" + docuPath + "\"" );

  // Mery.his のバックアップファイルのパス	※ 仮に「Mery.his.old」としておく
  var Fso = new ActiveXObject( "Scripting.FileSystemObject" );
  if ( hisPath && ! Fso.FileExists( hisPath ) ) {
    Output( "Error: \"" + hisPath + "\" がありません." );
    Alert( hisPath + "  \nがありません。  " );
    hisPath = "";
  }
  if ( ! hisPath ) {
    hisPath = editor.FullName.replace( /\.exe$/i , ".his.old" );
    if ( ! Fso.FileExists( hisPath ) ) {
      var WshShell = new ActiveXObject( "WScript.Shell" );
      hisPath = WshShell.ExpandEnvironmentStrings( "%APPDATA%\\Mery\\Mery.his.old" );
      if ( ! Fso.FileExists( hisPath ) ) {
        Output( "Error: \"\\Mery\\Mery.his.old\" ファイルがありません.\n" );
        AlertQuit( "Mery フォルダに \"Mery.his.old\" ファイルがありません。 " );
      }
    }
  }
  Output( "履歴ファイルのパス: \"" + hisPath + "\"\n" );


  // ファイルの最終更新日時
  var hisModified = " ( 最終更新日時: "
                  +  DateTimeJP( Fso.GetFile( hisPath ).DateLastModified ) + " )"
  var docuModified = document.FullName
                   ? " ( 最終更新日時: "
                     +  DateTimeJP( Fso.GetFile( docuPath ).DateLastModified ) + " )"
                   : " ( 未保存 )";

  // Mery.his のバックアップファイルを読みこむ
  var Adodb = new ActiveXObject( "ADODB.Stream" );
  var adTypeText = 2,  adReadAll = -1;
  Adodb.Type = adTypeText;
  Adodb.Charset = "UTF-8";
  Adodb.Open();
  Adodb.LoadFromFile( hisPath );
  var hisText = Adodb.ReadText( adReadAll ).replace( /\r\n?/g, "\n" ) + "\n\n";
  Adodb.Close();

  // Mery.his のバックアップファイルからドキュメントの履歴情報を参照する
  var hisName = hisPath.replace( /.+(?:\\|\/)([^\\\/]+)$/, "$1" );
  var escapedPath = docuPath.replace( /[.+^=!${}()[\]\/\\]/g, "\\$&" );
      Output( "\"" + hisName + "\" から \"" + escapedPath + "\" の履歴情報を検索 ..." );
  // ドキュメントの履歴情報がなければ search() の戻り値は -1
  var hisSection = hisText.search( new RegExp( "^\\[" + escapedPath + "\\]", "im" ) );
      Output( "\thisSection:\tpos = " + hisSection );
  if ( hisSection < 0 ) {
    Output( "Error:  ∵ hisSection < 0 \t(履歴情報なし)\n" );
    AlertQuit( "\"" + hisName + "\" ファイルに \n\"" 
             + ( document.Name || "「無題」 ドキュメント" )
             + "\" の履歴情報はありません。 " );
  }

  // ブックマーク情報の開始位置と終了位置
  // ブックマークがなければ search() の戻り値は -1
  var bmTop =  hisSection + hisText.slice( hisSection ).search( /^0=\d+$/m );
      Output( "\tbmTop:\t\tpos = " + bmTop );
  // ブックマークがなければ  bmBottom < bmTop
  var bmBottom = hisSection + hisText.slice( hisSection ).search( /\n{2}/ );
      Output( "\tbmBottom:\tpos = " + bmBottom );
  if ( bmTop < hisSection || bmTop > bmBottom ) {
    Output( "Error: ∵ " + ( bmTop < hisSection ? "bmTop < hisSection" : "" )
          + ( bmTop > bmBottom ? "bmTop > bmBottom" : "" )
          + "\t(ブックマーク件数: 0 件)\n" );
    AlertQuit( "\"" + hisName + "\" ファイルに \n\"" 
             + ( document.Name || "「無題」 ドキュメント" )
             + "\" のブックマーク情報はありません。 " );
  }

  // ブックマーク情報を配列形式で取得する
  var bookmarkArray = hisText.slice( bmTop, bmBottom )
                             .replace( /^\d+=(\d+)/gm, "$1" )
                             .split( "\n" );
  if ( ! bookmarkArray[0].length ) {
    bookmarkArray.shift();
  }
  var bmCount = bookmarkArray.length;
      Output( "\tブックマーク情報: [ " + bookmarkArray + " ]" + "\n"
            + "\tブックマーク件数: " + bmCount + " 件." + "\n\n"
            + "\tブックマークを復元 ..." );

  // 「ブックマークの復元」を実行前の確認ダイアログ
  if ( ! Confirm( "履歴ファイルに " + bmCount + " 件のブックマーク情報があります。  " + "\n\n"
                + "・履歴ファイルのパス:\t\"" + hisPath + "\"  \n"
                + hisModified + "\n\n"
                + "・ドキュメントのパス:\t\"" + docuPath + "\"  \n"
                + docuModified + "\n\n"
                + "※ 履歴ファイルの最終更新日時よりもあとで  \n"
                + "  ドキュメントが編集・更新 (文字数や行数の変更) されていると、  \n"
                + "  ブックマークの行番号が正しく復元されないかもしれません。  \n\n"
                + "※ ブックマークの復元操作は \"アンドゥ\" できません。  \n\n\n"
                + "「ブックマークの復元」 を実行しますか?  " ) ) {
    Output( "Exit: 「ブックマークの復元」をキャンセル\n" );
    Quit();
  }

  // すべてのブックマークをクリア
  if ( Confirm( "履歴ファイルから " + bmCount + " 件のブックマーク情報を復元します。  " + "\n"
              + "復元する前に現在のブックマークをすべて解除しますか?  " + "\n\n"
              + "・[OK] なら、現在のブックマーク設定をすべて解除してから  " + "\n"
              + " バックアップファイルのブックマーク情報を復元します。  " + "\n\n"
              + "・[キャンセル] なら、現在のブックマーク設定に  " + "\n"
              + " バックアップファイルのブックマーク情報を追加します。  " ) ) {
    editor.ExecuteCommandByID( 2129 );	// ( MEID_EDIT_CLEAR_BOOKMARK = 2129 )
    Output( "\t現在のブックマーク設定をクリア" );
  }

  // キャレット位置を保存
  var s = document.selection;
  var act = s.GetActivePos();
  var sx = ScrollX,  sy = ScrollY;
  Redraw = false;
  
  // ブックマークを復元する
  for ( var i = 0, y = 0; i < bmCount; i ++ ) {
    if ( ! ( /^[0-9]+$/ ).test( bookmarkArray[i].toString() ) ) {
      Output( "Error: " + ( i + 1 ) + " 件目:\t∵ \""
            + bookmarkArray[i] + "\" is NOT a pos Number"
            + " \t(ブックマーク情報ではない)\n" )
      break;	// 念のため
    }
    s.SetActivePos( bookmarkArray[i] );
    if ( s.GetActivePointY( mePosLogical ) == y ) {
      Output( "\t" + ( i + 1 ) + " 件目のブックマークを復元できません. \t\t\t\t\tpos = "
            + bookmarkArray[i] + "\n" );
      Alert( "最終行まで復元しましたが " + "\n"
           + ( bmCount - i ) + " 件のブックマークを復元できませんでした。 " );
      break;
    }
    s.SetBookmark();
    y = s.GetActivePointY( mePosLogical );
    Output( "\t" + ( i + 1 ) + " 件目\tのブックマークを復元: "
          + "\t論理行 No. = # " + y
          + "\t\tpos = " + bookmarkArray[i]
          + ( i == bmCount - 1 ? "\n" : "" ) );
  }
  Status = " " + i + " 件のブックマークを復元しました。";

  // キャレット位置を復帰
  s.SetActivePos( act );
  ScrollX = sx,  ScrollY = sy;
  Redraw = true;
}

/**
 * 関数 AlertQuit( str )
 * 警告ダイアログをだしてマクロを終了する
 */
function AlertQuit( str ) {
  if ( str ) {
    Status = " " + str.replace( /[\n\t  ]+/g, " " );
    Alert( str );
  }
  Quit();
}

/**
 * 関数 Output( string )
 * アウトプットバーに結果を出力する
 */
function Output( str ) {
  if ( outputEnable ) {	// 出力許可フラグ
    OutputBar.Writeln( str );
  }
}

/**
 * 関数 DateTimeJP( date )
 * 日時を  "YYYY年MM月DD日、hh:mm:ss"  で返す
 */
function DateTimeJP( date ) {
  var dd = new Date( date );
  return dd.getFullYear() + "年"
       + Pad( ( dd.getMonth() + 1 ) + "月"
       + dd.getDate() +"日 " 
       + dd.toLocaleTimeString() );
}

/**
 * 関数 DateTimeUTC( bool )
 * 現在日時を  "YYYY-MM-DD hh:mm:ss UTC+0900"  で返す(年月日の区切り: "-" )
 */
function DateTimeUTC( bool ) {
  var dd = new Date();
  return dd.getFullYear() + "-"
       + Pad( ( dd.getMonth() + 1 ) + "-" 
       + dd.getDate() + " "
       + dd.toLocaleTimeString() )
       + ( bool ? " UTC+0900" : "" );
}

/**
 * 関数 Pad( num )
 * 1ケタの数字をゼロ埋めして2ケタで返す
 */ 
function Pad( num ) {
  return num.toString().replace( /[0-9]+/g, function( $0 ) {
    return $0.length < 2 ? "0" + $0 : $0;
  } ) 
}
スポンサーリンク