サクラエディタのJavaScriptマクロで、ツイートの絶対年月日がブレイクする位置に区切りの見出しをつける
// datekaiseki.js
// 全選択してテキストを取得
Editor.SelectAll();
var text = Editor.GetSelectedString();
// 改行コードで分割して1行ずつ処理
var lines = text.split(/\r?\n/);
var result = [];
// 英語の月名を数値に変換するマッピング
var monthMap = {
"Jan": 0, "Feb": 1, "Mar": 2, "Apr": 3, "May": 4, "Jun": 5,
"Jul": 6, "Aug": 7, "Sep": 8, "Oct": 9, "Nov": 10, "Dec": 11
};
// 月の数値から英語の短縮名へ変換する配列
var monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
var lastDate = null; // 直前の行のDateオブジェクトを記録
var firstDateForLine = null; // 各行の中で最初に見つかった日時(日付見出し用)
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
firstDateForLine = null;
// 「·」または「·」のどちらにもマッチするように正規表現を修正
var timeRegex = /([A-Z][a-z]{2})\s+(\d{1,2}),\s+(\d{4})\s*(?:\·|·)\s*(\d{1,2}):(\d{2})\s*(AM|PM)\s*UTC/gi;
line = line.replace(timeRegex, function(match, monthEn, dayStr, yearStr, hourStr, minStr, ampmStr) {
var dayNum = parseInt(dayStr, 10);
var yearNum = parseInt(yearStr, 10);
var hourNum = parseInt(hourStr, 10);
var minNum = parseInt(minStr, 10);
var ampm = ampmStr.toUpperCase();
var monthNum = monthMap[monthEn];
if (monthNum === undefined) {
return match; // マッチしない場合はそのまま返す
}
// 12時間表記を24時間表記に変換
if (ampm === "PM" && hourNum < 12) {
hourNum += 12;
} else if (ampm === "AM" && hourNum === 12) {
hourNum = 0;
}
// UTCとしてDateオブジェクトを作成し、+9時間(JST)を加算する
var utcMillis = Date.UTC(yearNum, monthNum, dayNum, hourNum, minNum, 0);
var jstDate = new Date(utcMillis + (9 * 60 * 60 * 1000));
var jstYear = jstDate.getUTCFullYear();
var jstMonth = jstDate.getUTCMonth();
var jstDay = jstDate.getUTCDate();
var jstHour24 = jstDate.getUTCHours();
var jstMin = jstDate.getUTCMinutes();
// 24時間表記から再び12時間表記(AM/PM)とJST文字列を復元
var jstAmpm = jstHour24 >= 12 ? "PM" : "AM";
var jstHour12 = jstHour24 % 12;
if (jstHour12 === 0) jstHour12 = 12;
var minStrFormatted = ("0" + jstMin).slice(-2);
// 置換用の新しい日時文字列を生成
var newDateTimeStr = monthNames[jstMonth] + " " + jstDay + ", " + jstYear + " · " + jstHour12 + ":" + minStrFormatted + " " + jstAmpm + " JST";
// 行内で最初に見つかった日時を日付見出しの基準として保持
if (firstDateForLine === null) {
firstDateForLine = new Date(jstYear, jstMonth, jstDay);
}
return newDateTimeStr;
});
// 日付見出しの判定・挿入処理
var targetDateForHeading = firstDateForLine;
if (targetDateForHeading === null) {
// 時刻パターンに一致しない行は日付のみのパターンがないかフォールバック確認
var fallbackMatch = line.match(/([A-Z][a-z]{2})\s+(\d{1,2}),\s+(\d{4})/);
if (fallbackMatch) {
var monthEn = fallbackMatch[1];
var dayNum = parseInt(fallbackMatch[2], 10);
var yearNum = parseInt(fallbackMatch[3], 10);
var monthNum = monthMap[monthEn];
if (monthNum !== undefined) {
targetDateForHeading = new Date(yearNum, monthNum, dayNum);
}
}
}
if (targetDateForHeading !== null) {
var currentDate = targetDateForHeading;
if (lastDate === null) {
var yearStr = currentDate.getFullYear();
var monthStr = ("0" + (currentDate.getMonth() + 1)).slice(-2);
result.push("## " + yearStr + "-" + monthStr + "-");
} else {
var diffTime = currentDate.getTime() - lastDate.getTime();
var diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));
if (diffDays > 0) {
for (var d = 0; d < diffDays; d++) {
var targetDate = new Date(lastDate.getTime());
targetDate.setDate(targetDate.getDate() + d + 1);
var yearStr = targetDate.getFullYear();
var monthStr = ("0" + (targetDate.getMonth() + 1)).slice(-2);
if (d < diffDays - 1) {
result.push("## " + yearStr + "-" + monthStr + "-|なし");
} else {
result.push("## " + yearStr + "-" + monthStr + "-");
}
}
}
}
lastDate = currentDate;
}
// 処理済みの行を追加
result.push(line);
}
// 編集中のテキストを更新
Editor.InsText(result.join("\r\n"));
// 選択状態を解除してクリップボードにコピー
Editor.SelectAll(0);
Editor.Copy(0);
【欠点1】:月初あたりの初回ツイート日以前において[ツイートなし=見出しなし]は人間が判断して補う必要がある
- 例えば、## 2019-09-06が初回ツイートなしだとしたら、[## 2019-09-(01)|なし][## 2019-09-(02)|なし][## 2019-09-(03)|なし][## 2019-09-(04)|なし][## 2019-09-(05)|なし]を人間が手動で補う。
- (01)~(05)は、連番マクロhiduke.jsを使うなら、打ち込む必要はない。[## 2019-09-]を5行分挿入しておくだけでよい。
【欠点2】:月末あたりの最終ツイート日以降において[ツイートなし=見出しなし]は人間が判断して補う必要がある
- 例えば、## 2019-09-30がツイートなしだとしたら、## 2019-09-29があれば、そこで見出しが止まっているので、## 2019-09-30を人間が手で補う必要がある。
- 連番マクロhiduke.jsを使うなら、[## 2019-09-]までしか打ち込む必要がない。