gemini_sanitize2 (Go)
//Go言語のコマンドラインツールです。
// gemini_export2 で加工されて出力されたHTMLをダブルサニタイズして、
// 自分の掲示板(Junkerstock)に掲載できるようにする専用ツール。
// sanitize2は、クリップボードに入り、HTMLの出力は無い。
package main
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
)
func main() {
// 1. 引数チェック
if len(os.Args) < 2 {
fmt.Println("HTMLファイルをドラッグ&ドロップしてください。")
fmt.Scanln()
return
}
inputPath := os.Args[1]
fileName := filepath.Base(inputPath)
fmt.Printf("処理中: %s\n", fileName)
// 2. ファイル読み込み
contentBytes, err := ioutil.ReadFile(inputPath)
if err != nil {
fmt.Printf("読み込みエラー: %v\n", err)
fmt.Scanln()
return
}
htmlStr := string(contentBytes)
// ---------------------------------------------------------
// 3. コードブロックのダブルエスケープ処理 (前回のロジックそのまま)
// ---------------------------------------------------------
// <pre ...> ... </pre> の中身を対象にする
rePre := regexp.MustCompile(`(?s)(<pre[^>]*>)(.*?)(</pre>)`)
htmlStr = rePre.ReplaceAllStringFunc(htmlStr, func(match string) string {
parts := rePre.FindStringSubmatch(match)
if len(parts) < 4 {
return match
}
openTag := parts[1]
content := parts[2]
closeTag := parts[3]
// ダブルサニタイズ: & -> &
newContent := strings.ReplaceAll(content, "&", "&")
return openTag + newContent + closeTag
})
// インラインコード <code>...</code> や <span class="fake-inline-code"> も対象
reInline := regexp.MustCompile(`(?s)(<code[^>]*>|<span class="fake-inline-code">)(.*?)(</code>|</span>)`)
htmlStr = reInline.ReplaceAllStringFunc(htmlStr, func(match string) string {
parts := reInline.FindStringSubmatch(match)
if len(parts) < 4 {
return match
}
openTag := parts[1]
content := parts[2]
closeTag := parts[3]
// ダブルサニタイズ: & -> &
newContent := strings.ReplaceAll(content, "&", "&")
return openTag + newContent + closeTag
})
// ---------------------------------------------------------
// 4. クリップボードへ転送 (ご指定の安全なメソッド)
// ---------------------------------------------------------
fmt.Println("変換完了。クリップボードに転送しています...")
err = copyToClipboardSafe(htmlStr)
if err != nil {
fmt.Printf("クリップボード転送エラー: %v\n", err)
fmt.Scanln()
return
}
fmt.Println("--------------------------------------------------")
fmt.Println("成功! 変換結果をクリップボードにコピーしました。")
fmt.Println("そのまま掲示板に貼り付け(Ctrl+V)できます。")
fmt.Println("--------------------------------------------------")
// すぐに閉じるとコピーできたか不安になるため、少し待つかEnter待ちにする
fmt.Println("Enterキーを押して終了します...")
fmt.Scanln()
}
// 最も安全なクリップボード転送方法 (提供いただいたコード)
func copyToClipboardSafe(text string) error {
// PowerShellを起動。コマンドとして「標準入力の内容をクリップボードにセットする」を指定
// -EncodedCommandなどを使うと環境により文字数制限にひっかかるため、パイプ入力を使用
cmd := exec.Command("powershell", "-NoProfile", "-Command", "chcp 65001 >$null; [Console]::In.ReadToEnd() | Set-Clipboard")
// Goの変数(text)を標準入力に流し込む
cmd.Stdin = strings.NewReader(text)
return cmd.Run()
}