gemini_sanitize (Go)
//Go言語のコマンドラインツールです。
// gemini_export2 で加工されて出力されたHTMLをダブルサニタイズして、
// 自分の掲示板(Junkerstock)に掲載できるようにする専用ツール。
// sanitizeは、HTMLの出力をおこなう。 2はクリップボード出力だけ。
package main
import (
"fmt"
"io/ioutil"
"os"
"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> の中身を対象にする
// (?s) は改行を含んでマッチさせるオプション
rePre := regexp.MustCompile(`(?s)(<pre[^>]*>)(.*?)(</pre>)`)
// ReplaceAllStringFunc で、マッチした箇所ごとに処理を行う
htmlStr = rePre.ReplaceAllStringFunc(htmlStr, func(match string) string {
// マッチした文字列を「開始タグ」「中身」「終了タグ」に分割
parts := rePre.FindStringSubmatch(match)
if len(parts) < 4 {
return match
}
openTag := parts[1] // <pre class="...">
content := parts[2] // 中身
closeTag := parts[3] // </pre>
// ★ダブルサニタイズ処理★
// 中身にある "&" を "&" に置換する。
// これにより "<" は "<" に、 ">" は ">" になる。
// HTMLタグの "<" や ">" は変換されないため、シンタックスハイライト等は壊れない。
newContent := strings.ReplaceAll(content, "&", "&")
return openTag + newContent + closeTag
})
// インラインのコードブロック <code>...</code> や <span class="fake-inline-code"> も同様に処理
// class="fake-inline-code" または単なる <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. 保存 (_pastetype を付与)
outputDir := filepath.Dir(inputPath)
ext := filepath.Ext(fileName)
baseName := strings.TrimSuffix(fileName, ext)
outputName := baseName + "_pastetype" + ext
outputPath := filepath.Join(outputDir, outputName)
err = ioutil.WriteFile(outputPath, []byte(htmlStr), 0644)
if err != nil {
fmt.Printf("保存エラー: %v\n", err)
fmt.Scanln()
return
}
fmt.Println("完了しました。")
fmt.Printf("生成ファイル: %s\n", outputName)
fmt.Scanln()
}