diff --git a/display.go b/display.go index 5e8cda6..e2bd461 100644 --- a/display.go +++ b/display.go @@ -66,6 +66,54 @@ func (t TreeDisplayer) Display(nodes []*html.Node) { } } +// The
 tag indicates that the text within it should always be formatted
+// as is. See https://github.com/ericchiang/pup/issues/33
+func (t TreeDisplayer) printPre(n *html.Node) {
+	switch n.Type {
+	case html.TextNode:
+		s := n.Data
+		if pupEscapeHTML {
+			// don't escape javascript
+			if n.Parent == nil || n.Parent.DataAtom != atom.Script {
+				s = html.EscapeString(s)
+			}
+		}
+		fmt.Print(s)
+		for c := n.FirstChild; c != nil; c = c.NextSibling {
+			t.printPre(c)
+		}
+	case html.ElementNode:
+		fmt.Printf("<%s", n.Data)
+		for _, a := range n.Attr {
+			val := a.Val
+			if pupEscapeHTML {
+				val = html.EscapeString(val)
+			}
+			fmt.Printf(` %s="%s"`, a.Key, val)
+		}
+		fmt.Print(">")
+		if !isVoidElement(n) {
+			for c := n.FirstChild; c != nil; c = c.NextSibling {
+				t.printPre(c)
+			}
+			fmt.Printf("", n.Data)
+		}
+	case html.CommentNode:
+		data := n.Data
+		if pupEscapeHTML {
+			data = html.EscapeString(data)
+		}
+		fmt.Printf("\n", data)
+		for c := n.FirstChild; c != nil; c = c.NextSibling {
+			t.printPre(c)
+		}
+	case html.DoctypeNode, html.DocumentNode:
+		for c := n.FirstChild; c != nil; c = c.NextSibling {
+			t.printPre(c)
+		}
+	}
+}
+
 // Print a node and all of it's children to `maxlevel`.
 func (t TreeDisplayer) printNode(n *html.Node, level int) {
 	switch n.Type {
@@ -84,6 +132,12 @@ func (t TreeDisplayer) printNode(n *html.Node, level int) {
 		}
 	case html.ElementNode:
 		t.printIndent(level)
+		// TODO: allow pre with color
+		if n.DataAtom == atom.Pre && !pupPrintColor && pupPreformatted {
+			t.printPre(n)
+			fmt.Println()
+			return
+		}
 		if pupPrintColor {
 			tokenColor.Print("<")
 			tagColor.Printf("%s", n.Data)
diff --git a/parse.go b/parse.go
index b70a115..0491743 100644
--- a/parse.go
+++ b/parse.go
@@ -16,6 +16,7 @@ var (
 	pupIn            io.ReadCloser = os.Stdin
 	pupCharset       string        = ""
 	pupMaxPrintLevel int           = -1
+	pupPreformatted  bool          = false
 	pupPrintColor    bool          = false
 	pupEscapeHTML    bool          = true
 	pupIndentString  string        = " "
@@ -55,6 +56,7 @@ Flags
     -n --number        print number of elements selected
     -l --limit         restrict number of levels printed
     -p --plain         don't escape html
+    --pre              preserve preformatted text
     --charset          specify the charset for pup to use
     --version          display version
 `
@@ -87,6 +89,8 @@ func ProcessFlags(cmds []string) (nonFlagCmds []string, err error) {
 			pupPrintColor = true
 		case "-p", "--plain":
 			pupEscapeHTML = false
+		case "--pre":
+			pupPreformatted = true
 		case "-f", "--file":
 			filename := cmds[i+1]
 			pupIn, err = os.Open(filename)