examples/html: Read from stdin and write to stdout
This commit is contained in:
		
							parent
							
								
									36c2086c82
								
							
						
					
					
						commit
						5af1acbd54
					
				
							
								
								
									
										129
									
								
								examples/html.go
									
									
									
									
									
								
							
							
						
						
									
										129
									
								
								examples/html.go
									
									
									
									
									
								
							@ -7,76 +7,77 @@ package main
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"html"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"io"
 | 
			
		||||
	"os"
 | 
			
		||||
 | 
			
		||||
	"git.sr.ht/~adnano/go-gemini"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	text := gemini.Text{
 | 
			
		||||
		gemini.LineHeading1("Hello, world!"),
 | 
			
		||||
		gemini.LineText("This is a gemini text document."),
 | 
			
		||||
	hw := HTMLWriter{
 | 
			
		||||
		out: os.Stdout,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	html := textToHTML(text)
 | 
			
		||||
	fmt.Print(html)
 | 
			
		||||
	gemini.ParseLines(os.Stdin, hw.Handle)
 | 
			
		||||
	hw.Finish()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// textToHTML returns the Gemini text response as HTML.
 | 
			
		||||
func textToHTML(text gemini.Text) string {
 | 
			
		||||
	var b strings.Builder
 | 
			
		||||
	var pre bool
 | 
			
		||||
	var list bool
 | 
			
		||||
	for _, l := range text {
 | 
			
		||||
		if _, ok := l.(gemini.LineListItem); ok {
 | 
			
		||||
			if !list {
 | 
			
		||||
				list = true
 | 
			
		||||
				fmt.Fprint(&b, "<ul>\n")
 | 
			
		||||
			}
 | 
			
		||||
		} else if list {
 | 
			
		||||
			list = false
 | 
			
		||||
			fmt.Fprint(&b, "</ul>\n")
 | 
			
		||||
		}
 | 
			
		||||
		switch l := l.(type) {
 | 
			
		||||
		case gemini.LineLink:
 | 
			
		||||
			url := html.EscapeString(l.URL)
 | 
			
		||||
			name := html.EscapeString(l.Name)
 | 
			
		||||
			if name == "" {
 | 
			
		||||
				name = url
 | 
			
		||||
			}
 | 
			
		||||
			fmt.Fprintf(&b, "<p><a href='%s'>%s</a></p>\n", url, name)
 | 
			
		||||
		case gemini.LinePreformattingToggle:
 | 
			
		||||
			pre = !pre
 | 
			
		||||
			if pre {
 | 
			
		||||
				fmt.Fprint(&b, "<pre>\n")
 | 
			
		||||
			} else {
 | 
			
		||||
				fmt.Fprint(&b, "</pre>\n")
 | 
			
		||||
			}
 | 
			
		||||
		case gemini.LinePreformattedText:
 | 
			
		||||
			fmt.Fprintf(&b, "%s\n", html.EscapeString(string(l)))
 | 
			
		||||
		case gemini.LineHeading1:
 | 
			
		||||
			fmt.Fprintf(&b, "<h1>%s</h1>\n", html.EscapeString(string(l)))
 | 
			
		||||
		case gemini.LineHeading2:
 | 
			
		||||
			fmt.Fprintf(&b, "<h2>%s</h2>\n", html.EscapeString(string(l)))
 | 
			
		||||
		case gemini.LineHeading3:
 | 
			
		||||
			fmt.Fprintf(&b, "<h3>%s</h3>\n", html.EscapeString(string(l)))
 | 
			
		||||
		case gemini.LineListItem:
 | 
			
		||||
			fmt.Fprintf(&b, "<li>%s</li>\n", html.EscapeString(string(l)))
 | 
			
		||||
		case gemini.LineQuote:
 | 
			
		||||
			fmt.Fprintf(&b, "<blockquote>%s</blockquote>\n", html.EscapeString(string(l)))
 | 
			
		||||
		case gemini.LineText:
 | 
			
		||||
			if l == "" {
 | 
			
		||||
				fmt.Fprint(&b, "<br>\n")
 | 
			
		||||
			} else {
 | 
			
		||||
				fmt.Fprintf(&b, "<p>%s</p>\n", html.EscapeString(string(l)))
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if pre {
 | 
			
		||||
		fmt.Fprint(&b, "</pre>\n")
 | 
			
		||||
	}
 | 
			
		||||
	if list {
 | 
			
		||||
		fmt.Fprint(&b, "</ul>\n")
 | 
			
		||||
	}
 | 
			
		||||
	return b.String()
 | 
			
		||||
type HTMLWriter struct {
 | 
			
		||||
	out  io.Writer
 | 
			
		||||
	pre  bool
 | 
			
		||||
	list bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *HTMLWriter) Handle(line gemini.Line) {
 | 
			
		||||
	if _, ok := line.(gemini.LineListItem); ok {
 | 
			
		||||
		if !h.list {
 | 
			
		||||
			h.list = true
 | 
			
		||||
			fmt.Fprint(h.out, "<ul>\n")
 | 
			
		||||
		}
 | 
			
		||||
	} else if h.list {
 | 
			
		||||
		h.list = false
 | 
			
		||||
		fmt.Fprint(h.out, "</ul>\n")
 | 
			
		||||
	}
 | 
			
		||||
	switch line := line.(type) {
 | 
			
		||||
	case gemini.LineLink:
 | 
			
		||||
		url := html.EscapeString(line.URL)
 | 
			
		||||
		name := html.EscapeString(line.Name)
 | 
			
		||||
		if name == "" {
 | 
			
		||||
			name = url
 | 
			
		||||
		}
 | 
			
		||||
		fmt.Fprintf(h.out, "<p><a href='%s'>%s</a></p>\n", url, name)
 | 
			
		||||
	case gemini.LinePreformattingToggle:
 | 
			
		||||
		h.pre = !h.pre
 | 
			
		||||
		if h.pre {
 | 
			
		||||
			fmt.Fprint(h.out, "<pre>\n")
 | 
			
		||||
		} else {
 | 
			
		||||
			fmt.Fprint(h.out, "</pre>\n")
 | 
			
		||||
		}
 | 
			
		||||
	case gemini.LinePreformattedText:
 | 
			
		||||
		fmt.Fprintf(h.out, "%s\n", html.EscapeString(string(line)))
 | 
			
		||||
	case gemini.LineHeading1:
 | 
			
		||||
		fmt.Fprintf(h.out, "<h1>%s</h1>\n", html.EscapeString(string(line)))
 | 
			
		||||
	case gemini.LineHeading2:
 | 
			
		||||
		fmt.Fprintf(h.out, "<h2>%s</h2>\n", html.EscapeString(string(line)))
 | 
			
		||||
	case gemini.LineHeading3:
 | 
			
		||||
		fmt.Fprintf(h.out, "<h3>%s</h3>\n", html.EscapeString(string(line)))
 | 
			
		||||
	case gemini.LineListItem:
 | 
			
		||||
		fmt.Fprintf(h.out, "<li>%s</li>\n", html.EscapeString(string(line)))
 | 
			
		||||
	case gemini.LineQuote:
 | 
			
		||||
		fmt.Fprintf(h.out, "<blockquote>%s</blockquote>\n", html.EscapeString(string(line)))
 | 
			
		||||
	case gemini.LineText:
 | 
			
		||||
		if line == "" {
 | 
			
		||||
			fmt.Fprint(h.out, "<br>\n")
 | 
			
		||||
		} else {
 | 
			
		||||
			fmt.Fprintf(h.out, "<p>%s</p>\n", html.EscapeString(string(line)))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *HTMLWriter) Finish() {
 | 
			
		||||
	if h.pre {
 | 
			
		||||
		fmt.Fprint(h.out, "</pre>\n")
 | 
			
		||||
	}
 | 
			
		||||
	if h.list {
 | 
			
		||||
		fmt.Fprint(h.out, "</ul>\n")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user