Exemplo n.º 1
0
// Writes code blocks to the buffer.
func (self *Formatter) writeCodeBlock(node xml.Node) {
	block := []byte(strings.Trim(node.Content(), "\n\r\v"))
	node.SetContent("")

	if len(block) == 0 {
		return
	}
	self.buf.Write(block)
	self.buf.Write([]byte{'\n', '\n'})
}
Exemplo n.º 2
0
// Writes text blocks to the buffer.
func (self *Formatter) writeBlock(node xml.Node, prefix string) {
	block := []byte(strings.TrimSpace(node.Content()))
	node.SetContent("")

	if len(block) == 0 {
		return
	}
	// Position of last space, line break and max length.
	sp, br, max := 0, 0, 79-len(prefix)
	self.buf.WriteString(prefix)

	for i, c := range block {
		// Break line if exceeded max length and the position of the last space
		// is greater than the position of the last line break. Don't break very
		// long words.
		if i-br > max && sp > br {
			self.buf.WriteByte('\n')
			br = sp
			// Only the first line is prefixed.
			for j := 0; j < len(prefix); j++ {
				self.buf.WriteByte(' ')
			}
		}
		if whitespace[c] {
			// The last character was a space, so ignore this one.
			if sp == i {
				sp++
				br++
				continue
			}
			// Write the last word to the buffer, append a space and update
			// the position of the last space.
			if sp > br {
				self.buf.WriteByte(' ')
			}
			self.buf.Write(block[sp:i])
			sp = i + 1
		}
	}

	// Write the last word to the buffer.
	if sp < len(block) {
		if sp > br {
			self.buf.WriteByte(' ')
		}
		self.buf.Write(block[sp:])
	}

	// Close block with 2 breaks.
	self.buf.Write([]byte{'\n', '\n'})
}
Exemplo n.º 3
0
// Formats the content of inline elements and writes the content of block
// elements to the buffer.
func (self *Formatter) handleNode(node xml.Node) {
	name := node.Name()

	switch {
	case ignore[name]:
		// Remove ignored elements.
		node.SetContent("")
	case name == "pre":
		// Treat pre elements as code blocks.
		self.writeCodeBlock(node)
	case heading[name]:
		// Headings are prefixed with "# ".
		self.writeBlock(node, "# ")
	case name == "li":
		// List items are prefixed with "- ".
		self.writeBlock(node, "- ")
	case name == "br":
		// Preserve explicit line breaks.
		node.SetContent("\n")
	case italic[name]:
		// Wrap italic elements with /.
		node.SetContent("/" + node.Content() + "/")
	case bold[name]:
		// Wrap bold elements with *.
		node.SetContent("*" + node.Content() + "*")
	case name == "img":
		// Collect the src of images and replace them with (alt)[url index]
		alt, src := node.Attr("alt"), node.Attr("src")

		if len(alt) > 0 && len(src) > 0 {
			node.SetContent(fmt.Sprintf("(%s)[%d]", alt, len(self.links)))
			self.links = append(self.links, src)
		}
	case name == "a":
		// Collect the href and and the url index.
		href, content := node.Attr("href"), node.Content()

		if len(href) > 0 && len(content) > 0 {
			node.SetContent(fmt.Sprintf("%s[%d]", content, len(self.links)))
			self.links = append(self.links, href)
		}
	case block[name]:
		// Write the content of block elements to the buffer.
		self.writeBlock(node, "")
	}
}