Skip to content

Commit 773f4f7

Browse files
committed
Htmlize
1 parent 22573f2 commit 773f4f7

File tree

5 files changed

+204
-1
lines changed

5 files changed

+204
-1
lines changed

ccat.go

+8
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ func (p PlainTextPrinter) Print(r io.Reader, w io.Writer) error {
4242
return err
4343
}
4444

45+
type HtmlPrinter struct {
46+
ColorPalettes ColorPalettes
47+
}
48+
49+
func (c HtmlPrinter) Print(r io.Reader, w io.Writer) error {
50+
return HtmlPrint(r, w, c.ColorPalettes)
51+
}
52+
4553
func CCat(fname string, p CCatPrinter, w io.Writer) error {
4654
var r io.Reader
4755

html.go

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
"sort"
7+
"strings"
8+
)
9+
10+
type HtmlCodes map[string]string
11+
12+
func (c HtmlCodes) String() string {
13+
var cc []string
14+
for k, _ := range c {
15+
if k == "" {
16+
continue
17+
}
18+
19+
cc = append(cc, k)
20+
}
21+
sort.Strings(cc)
22+
23+
var s []string
24+
for _, ss := range cc {
25+
s = append(s, Htmlize(ss, ss))
26+
}
27+
28+
return strings.Join(s, ", ")
29+
}
30+
31+
var htmlCodes = HtmlCodes{
32+
"": "",
33+
"reset": `</span>`,
34+
"bold": `<span class="bold">`,
35+
"faint": `<span class="faint">`,
36+
"standout": `<span class="standout">`,
37+
"underline": `<span class="underline">`,
38+
"blink": `<span class="blink">`,
39+
"overline": `<span class="overline">`,
40+
}
41+
42+
func init() {
43+
darkHtmls := []string{
44+
"black",
45+
"darkred",
46+
"darkgreen",
47+
"brown",
48+
"darkblue",
49+
"purple",
50+
"teal",
51+
"lightgray",
52+
}
53+
54+
lightHtmls := []string{
55+
"darkgray",
56+
"red",
57+
"green",
58+
"yellow",
59+
"blue",
60+
"fuchsia",
61+
"turquoise",
62+
"white",
63+
}
64+
65+
for i, x := 0, 30; i < len(darkHtmls); i, x = i+1, x+1 {
66+
htmlCodes[darkHtmls[i]] = fmt.Sprintf(`<span class="%s">`, darkHtmls[i])
67+
htmlCodes[lightHtmls[i]] = fmt.Sprintf(`<span class="%s">`, lightHtmls[i])
68+
}
69+
70+
htmlCodes["darkteal"] = htmlCodes["turquoise"]
71+
htmlCodes["darkyellow"] = htmlCodes["brown"]
72+
htmlCodes["fuscia"] = htmlCodes["fuchsia"]
73+
htmlCodes["white"] = htmlCodes["bold"]
74+
}
75+
76+
func Htmlize(attr, text string) string {
77+
if attr == "" {
78+
return text
79+
}
80+
81+
result := new(bytes.Buffer)
82+
83+
if strings.HasPrefix(attr, "+") && strings.HasSuffix(attr, "+") {
84+
result.WriteString(htmlCodes["blink"])
85+
attr = strings.TrimPrefix(attr, "+")
86+
attr = strings.TrimSuffix(attr, "+")
87+
}
88+
89+
if strings.HasPrefix(attr, "*") && strings.HasSuffix(attr, "*") {
90+
result.WriteString(htmlCodes["bold"])
91+
attr = strings.TrimPrefix(attr, "*")
92+
attr = strings.TrimSuffix(attr, "*")
93+
}
94+
95+
if strings.HasPrefix(attr, "_") && strings.HasSuffix(attr, "_") {
96+
result.WriteString(htmlCodes["underline"])
97+
attr = strings.TrimPrefix(attr, "_")
98+
attr = strings.TrimSuffix(attr, "_")
99+
}
100+
101+
result.WriteString(htmlCodes[attr])
102+
result.WriteString(text)
103+
result.WriteString(htmlCodes["reset"])
104+
105+
return result.String()
106+
}

main.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ type ccatCmd struct {
1616
BG string
1717
Color string
1818
ColorCodes mapValue
19+
HTML bool
1920
ShowPalette bool
2021
ShowVersion bool
2122
}
@@ -61,7 +62,9 @@ Value of color can be %s
6162
}
6263

6364
var printer CCatPrinter
64-
if c.Color == "always" {
65+
if c.HTML {
66+
printer = HtmlPrinter{colorPalettes}
67+
} else if c.Color == "always" {
6568
printer = ColorPrinter{colorPalettes}
6669
} else if c.Color == "never" {
6770
printer = PlainTextPrinter{}
@@ -91,6 +94,7 @@ func main() {
9194
Long: "Colorize FILE(s), or standard input, to standard output.",
9295
Example: `$ ccat FILE1 FILE2 ...
9396
$ ccat --bg=dark FILE1 FILE2 ... # dark background
97+
$ ccat --html # output html
9498
$ ccat -G String="_darkblue_" -G Plaintext="darkred" FILE # set color codes
9599
$ ccat --palette # show palette
96100
$ ccat # read from standard input
@@ -116,6 +120,7 @@ Examples:
116120
rootCmd.PersistentFlags().StringVarP(&ccatCmd.BG, "bg", "", "light", `set to "light" or "dark" depending on the terminal's background`)
117121
rootCmd.PersistentFlags().StringVarP(&ccatCmd.Color, "color", "C", "auto", `colorize the output; value can be "never", "always" or "auto"`)
118122
rootCmd.PersistentFlags().VarP(&ccatCmd.ColorCodes, "color-code", "G", `set color codes`)
123+
rootCmd.PersistentFlags().BoolVarP(&ccatCmd.HTML, "html", "", false, `output html`)
119124
rootCmd.PersistentFlags().BoolVarP(&ccatCmd.ShowPalette, "palette", "", false, `show color palettes`)
120125
rootCmd.PersistentFlags().BoolVarP(&ccatCmd.ShowVersion, "version", "v", false, `show version`)
121126

printer.go

+36
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package main
33
import (
44
"fmt"
55
"io"
6+
"sort"
67
"strings"
78

89
"github.com/jingweno/ccat/Godeps/_workspace/src/github.com/sourcegraph/syntaxhighlight"
@@ -143,3 +144,38 @@ func (p Printer) Print(w io.Writer, kind syntaxhighlight.Kind, tokText string) e
143144

144145
return err
145146
}
147+
148+
func HtmlPrint(r io.Reader, w io.Writer, palettes ColorPalettes) error {
149+
keys := []string{}
150+
for k := range htmlCodes {
151+
keys = append(keys, k)
152+
}
153+
sort.Strings(keys)
154+
w.Write([]byte("<style>\n"))
155+
for _, s := range keys {
156+
if s == "" {
157+
continue
158+
}
159+
w.Write([]byte(fmt.Sprintf(".%s { color: %s; }\n", s, s)))
160+
}
161+
w.Write([]byte("</style>\n"))
162+
w.Write([]byte("<pre>\n"))
163+
err := syntaxhighlight.Print(syntaxhighlight.NewScannerReader(r), w, HtmlCodePrinter{palettes})
164+
w.Write([]byte("\n</pre>\n"))
165+
return err
166+
}
167+
168+
type HtmlCodePrinter struct {
169+
ColorPalettes ColorPalettes
170+
}
171+
172+
func (p HtmlCodePrinter) Print(w io.Writer, kind syntaxhighlight.Kind, tokText string) error {
173+
c := p.ColorPalettes.Get(kind)
174+
if len(c) > 0 {
175+
tokText = Htmlize(c, tokText)
176+
}
177+
178+
_, err := io.WriteString(w, tokText)
179+
180+
return err
181+
}

printer_test.go

+48
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,51 @@ func TestCPrint(t *testing.T) {
1919
t.Errorf("output is wrong: %s", s)
2020
}
2121
}
22+
23+
func TestHtmlPrint(t *testing.T) {
24+
r := bytes.NewBufferString("hello")
25+
var w bytes.Buffer
26+
27+
err := HtmlPrint(r, &w, LightColorPalettes)
28+
if err != nil {
29+
t.Errorf("error should be nil, but it's %s", err)
30+
}
31+
32+
expect := `<style>
33+
.black { color: black; }
34+
.blink { color: blink; }
35+
.blue { color: blue; }
36+
.bold { color: bold; }
37+
.brown { color: brown; }
38+
.darkblue { color: darkblue; }
39+
.darkgray { color: darkgray; }
40+
.darkgreen { color: darkgreen; }
41+
.darkred { color: darkred; }
42+
.darkteal { color: darkteal; }
43+
.darkyellow { color: darkyellow; }
44+
.faint { color: faint; }
45+
.fuchsia { color: fuchsia; }
46+
.fuscia { color: fuscia; }
47+
.green { color: green; }
48+
.lightgray { color: lightgray; }
49+
.overline { color: overline; }
50+
.purple { color: purple; }
51+
.red { color: red; }
52+
.reset { color: reset; }
53+
.standout { color: standout; }
54+
.teal { color: teal; }
55+
.turquoise { color: turquoise; }
56+
.underline { color: underline; }
57+
.white { color: white; }
58+
.yellow { color: yellow; }
59+
</style>
60+
<pre>
61+
<span class="darkblue">hello</span>
62+
</pre>
63+
`
64+
65+
s := w.String()
66+
if s != expect {
67+
t.Errorf("output is wrong: %s", s)
68+
}
69+
}

0 commit comments

Comments
 (0)