I created a handy tool to escape HTML characters, especially for pasting code in a blog like this.
Usage: ./escapehtml [dest_dir]
If the source is a directory, the tool will scan the whole directory and escape each file found and output the escaped string to stdout (if dest_dir isn't specified) or to a file (if dest_dir is specified).
escapehtml.go
package main
import (
"fmt"
"os"
"errors"
"path/filepath"
"io/ioutil"
"html"
"strings"
)
func printUsage() {
fmt.Println("Usage:", os.Args[0],
"<source_file/source_dir>", "[dest_dir]")
}
func errorMessage(s string) string {
return "Error: " + s
}
type fileType struct {
directory bool
regularFile bool
}
func fileExists(path string) (*fileType, error) {
file, err := os.Open(path)
if err != nil {
if os.IsNotExist(err) {
return nil, errors.New(
errorMessage(path + " does not exist"))
}
}
defer file.Close()
fileInfo, err := file.Stat()
if err != nil {
return nil, err
}
if fileInfo.IsDir() {
return &fileType{directory: true}, nil
}
return &fileType{regularFile: true}, nil
}
func validateArgs() (bool, error) {
if len(os.Args) != 2 && len(os.Args) != 3 {
return false, nil
}
if _, err := fileExists(os.Args[1]); err != nil {
return false, err
}
if len(os.Args) == 3 {
ft, _ := fileExists(os.Args[2])
if ft != nil && !ft.directory {
return false, errors.New(
errorMessage(os.Args[2] + " must be a directory"))
}
}
return true, nil
}
func printHeader(header string) {
fmt.Println(strings.Repeat("=", 72))
fmt.Println(header)
fmt.Println(strings.Repeat("=", 72))
}
func escapeHTML(srcPath string, destPath string) {
filepath.Walk(srcPath,
func(path string, info os.FileInfo, err error) error {
if info.IsDir() {
return nil
}
b, err := ioutil.ReadFile(path)
if err != nil {
return nil
}
escapedString := html.EscapeString(string(b))
if destPath == "" {
printHeader(path)
fmt.Println(escapedString)
} else {
if ft, _ := fileExists(destPath); ft == nil {
if e := os.MkdirAll(destPath, 0775); e != nil {
errors.New("Unable to create directory: " +
destPath)
} else {
fmt.Println("Creating directory: " + destPath)
}
}
newPath := filepath.Join(destPath,
filepath.Base(path) + ".txt")
fmt.Println("Creating", newPath)
e := ioutil.WriteFile(newPath, []byte(escapedString), 0644)
if e != nil {
return e
}
}
return nil
})
}
func main() {
if valid, err := validateArgs(); !valid {
if err != nil {
fmt.Println(err)
os.Exit(1)
} else {
printUsage()
os.Exit(1)
}
}
srcPath := os.Args[1]
destPath := ""
if len(os.Args) == 3 {
destPath = os.Args[2]
}
escapeHTML(srcPath, destPath)
}
To build it, just type
go build escapehtml.go
No comments:
Post a Comment