Markdown 向け、タスクリスト (* []) のチェック状態をトグル

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

Markdown でのタスクリスト記号 (* [ ] / * [x]) のチェック状態をトグルします。

複数行選択及びマルチカーソル機能に対応しています。

#title = "Markdown タスクリストのチェックをトグル"
Redraw = false;
BeginUndoGroup();

var sel = Document.Selection;

if (sel.Mode === meModeMulti) {
  doMultiAction(main);
} else {
  main();
}

function main() {
  if (Document.Selection.IsEmpty) {
    var actX = sel.GetActivePointX(mePosLogical);
    var actY = sel.GetActivePointY(mePosLogical);
    toggleCheck(actY);
    sel.SetActivePoint(mePosLogical, actX, actY);
  } else {
    var topX = Document.Selection.GetTopPointX(mePosLogical);
    var bottomX = Document.Selection.GetBottomPointX(mePosLogical);
    var topY = Document.Selection.GetTopPointY(mePosLogical);
    var bottomY = Document.Selection.GetBottomPointY(mePosLogical);
    var ignoreY = 0;
    if (bottomX === 1) {
      ignoreY = bottomY;
    }
    for (var y = topY; y <= bottomY; y++) {
      if (y === ignoreY) {
        continue;
      }
      sel.SetActivePoint(mePosLogical, 1, y);
      toggleCheck(y);
    }
    Document.Selection.SetAnchorPoint(mePosLogical, topX, topY);
    Document.Selection.SetActivePoint(mePosLogical, bottomX, bottomY, true);
  }
}

function toggleCheck(y) {
  var lineText = Document.GetLine(y, meGetLineWithNewLines);
  var checked = lineText.match(/^\s*[*-] \[x]/);
  var unchecked = lineText.match(/^\s*[*-] \[ ]/);
  if (checked || unchecked) {
    sel.SelectLine();
    sel.Delete();
    if (checked) {
      sel.Text = lineText.replace(/^(\s*[*-] )\[x]/, '$1[ ]');
    } else {
      sel.Text = lineText.replace(/^(\s*[*-] )\[ ]/, '$1[x]');
    }
  }
}

function doMultiAction(fn) {
  var d = document,
    s = d.selection;
  s.Mode = meModeMulti;
  // ① まず、GetActivePos と GetAnchorPos で複数選択のリストを作成します
  var selections = [{s: s.GetAnchorPos(), e: s.GetActivePos()}];
  if (s.Count > 0) {
    selections = [];
    for (var i = 0; i < s.Count; i++)
      selections.push({s: s.GetActivePos(i), e: s.GetAnchorPos(i)});
  }
  var p = 0;
  var q = 0;
  for (var i = 0; i < selections.length; i++) {
    // ② そのリストを上から順に SetActivePos で、「シングルカーソル」で範囲選択します。この段階で複数選択は解除され、通常のマクロ操作が可能となります
    s.SetActivePos(selections[i].s + p);
    s.SetActivePos(selections[i].e + p, true);
    q = d.TextLength;
    // ③ <ここで通常のマクロの機能を使って普通に編集などを行います>
    fn();
    p += d.TextLength - q;
    // ④ 処理を行った後の選択範囲をリストに反映し、これをリストの最後まで繰り返します
    selections[i] = {s: s.GetAnchorPos(), e: s.GetActivePos()};
  }
  // ⑤ そのリストを上から順に document.selection.AddPos(StartPos, EndPos) で複数選択として復元します
  for (var i = 0; i < selections.length; i++)
    s.AddPos(selections[i].s, selections[i].e);
}
スポンサーリンク