mirror of
https://github.com/gohugoio/hugo.git
synced 2024-07-05 08:42:12 +00:00
Continue with TOC integration and page refactor. Updated a few tests to match new generated output.
This commit is contained in:
parent
f45c6bc38a
commit
1da3fd039a
|
@ -38,6 +38,7 @@ type Page struct {
|
|||
rawContent []byte
|
||||
Content template.HTML
|
||||
Summary template.HTML
|
||||
TableOfContents template.HTML
|
||||
Truncated bool
|
||||
plain string // TODO should be []byte
|
||||
Params map[string]interface{}
|
||||
|
@ -75,7 +76,7 @@ type Pages []*Page
|
|||
|
||||
func (p *Page) Plain() string {
|
||||
if len(p.plain) == 0 {
|
||||
p.plain = StripHTML(StripShortcodes(string(p.rawContent)))
|
||||
p.plain = StripHTML(StripShortcodes(string(p.renderBytes(p.rawContent))))
|
||||
}
|
||||
return p.plain
|
||||
}
|
||||
|
@ -96,6 +97,10 @@ func (p *Page) setSummary() {
|
|||
}
|
||||
}
|
||||
|
||||
func stripEmptyNav(in []byte) []byte {
|
||||
return bytes.Replace(in, []byte("<nav>\n</nav>\n\n"), []byte(``), -1)
|
||||
}
|
||||
|
||||
func bytesToHTML(b []byte) template.HTML {
|
||||
return template.HTML(string(b))
|
||||
}
|
||||
|
@ -104,16 +109,27 @@ func (p *Page) renderBytes(content []byte) []byte {
|
|||
return renderBytes(content, p.guessMarkupType())
|
||||
}
|
||||
|
||||
func (p *Page) renderString(content string) []byte {
|
||||
return renderBytes([]byte(content), p.guessMarkupType())
|
||||
func (p *Page) renderContent(content []byte) []byte {
|
||||
return renderBytesWithTOC(content, p.guessMarkupType())
|
||||
}
|
||||
|
||||
func renderBytesWithTOC(content []byte, pagefmt string) []byte {
|
||||
switch pagefmt {
|
||||
default:
|
||||
return markdownRenderWithTOC(content)
|
||||
case "markdown":
|
||||
return markdownRenderWithTOC(content)
|
||||
case "rst":
|
||||
return []byte(getRstContent(content))
|
||||
}
|
||||
}
|
||||
|
||||
func renderBytes(content []byte, pagefmt string) []byte {
|
||||
switch pagefmt {
|
||||
default:
|
||||
return blackfriday.MarkdownCommon(content)
|
||||
return markdownRender(content)
|
||||
case "markdown":
|
||||
return blackfriday.MarkdownCommon(content)
|
||||
return markdownRender(content)
|
||||
case "rst":
|
||||
return []byte(getRstContent(content))
|
||||
}
|
||||
|
@ -553,7 +569,9 @@ func (page *Page) Convert() error {
|
|||
markupType := page.guessMarkupType()
|
||||
switch markupType {
|
||||
case "markdown", "rst":
|
||||
page.Content = bytesToHTML(page.renderString(string(RemoveSummaryDivider(page.rawContent))))
|
||||
tmpContent, tmpTableOfContents := extractTOC(page.renderContent(RemoveSummaryDivider(page.rawContent)))
|
||||
page.Content = bytesToHTML(tmpContent)
|
||||
page.TableOfContents = bytesToHTML(tmpTableOfContents)
|
||||
case "html":
|
||||
page.Content = bytesToHTML(page.rawContent)
|
||||
default:
|
||||
|
@ -562,19 +580,58 @@ func (page *Page) Convert() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Lazily generate the TOC
|
||||
func (page *Page) TableOfContents() template.HTML {
|
||||
return tableOfContentsFromBytes([]byte(page.Content))
|
||||
func markdownRender(content []byte) []byte {
|
||||
htmlFlags := 0
|
||||
htmlFlags |= blackfriday.HTML_SKIP_SCRIPT
|
||||
htmlFlags |= blackfriday.HTML_USE_SMARTYPANTS
|
||||
renderer := blackfriday.HtmlRenderer(htmlFlags, "", "")
|
||||
|
||||
return blackfriday.Markdown(content, renderer, 0)
|
||||
}
|
||||
|
||||
func tableOfContentsFromBytes(content []byte) template.HTML {
|
||||
func markdownRenderWithTOC(content []byte) []byte {
|
||||
htmlFlags := 0
|
||||
htmlFlags |= blackfriday.HTML_SKIP_SCRIPT
|
||||
htmlFlags |= blackfriday.HTML_TOC
|
||||
htmlFlags |= blackfriday.HTML_OMIT_CONTENTS
|
||||
htmlFlags |= blackfriday.HTML_USE_SMARTYPANTS
|
||||
renderer := blackfriday.HtmlRenderer(htmlFlags, "", "")
|
||||
|
||||
return template.HTML(string(blackfriday.Markdown(RemoveSummaryDivider(content), renderer, 0)))
|
||||
return blackfriday.Markdown(content, renderer, 0)
|
||||
}
|
||||
|
||||
func extractTOC(content []byte) (newcontent []byte, toc []byte) {
|
||||
origContent := make([]byte, len(content))
|
||||
copy(origContent, content)
|
||||
first := []byte(`<nav>
|
||||
<ul>`)
|
||||
|
||||
last := []byte(`</ul>
|
||||
</nav>`)
|
||||
|
||||
replacement := []byte(`<nav id="TableOfContents">
|
||||
<ul>`)
|
||||
|
||||
startOfTOC := bytes.Index(content, first)
|
||||
|
||||
peekEnd := len(content)
|
||||
if peekEnd > 70+startOfTOC {
|
||||
peekEnd = 70 + startOfTOC
|
||||
}
|
||||
|
||||
if startOfTOC < 0 {
|
||||
return stripEmptyNav(content), toc
|
||||
}
|
||||
// Need to peek ahead to see if this nav element is actually the right one.
|
||||
correctNav := bytes.Index(content[startOfTOC:peekEnd], []byte(`#toc_0`))
|
||||
if correctNav < 0 { // no match found
|
||||
return content, toc
|
||||
}
|
||||
lengthOfTOC := bytes.Index(content[startOfTOC:], last) + len(last)
|
||||
endOfTOC := startOfTOC + lengthOfTOC
|
||||
|
||||
newcontent = append(content[:startOfTOC], content[endOfTOC:]...)
|
||||
toc = append(replacement, origContent[startOfTOC+len(first):endOfTOC]...)
|
||||
return
|
||||
}
|
||||
|
||||
func ReaderToBytes(lines io.Reader) []byte {
|
||||
|
|
|
@ -98,7 +98,7 @@ func TestRenderThing(t *testing.T) {
|
|||
}{
|
||||
{PAGE_SIMPLE_TITLE, TEMPLATE_TITLE, "simple template"},
|
||||
{PAGE_SIMPLE_TITLE, TEMPLATE_FUNC, "simple-template"},
|
||||
{PAGE_WITH_MD, TEMPLATE_CONTENT, "<h1>heading 1</h1>\n\n<p>text</p>\n\n<h2>heading 2</h2>\n\n<p>more text</p>\n"},
|
||||
{PAGE_WITH_MD, TEMPLATE_CONTENT, "\n\n<h1 id=\"toc_0\">heading 1</h1>\n\n<p>text</p>\n\n<h2 id=\"toc_1\">heading 2</h2>\n\n<p>more text</p>\n"},
|
||||
{SIMPLE_PAGE_RFC3339_DATE, TEMPLATE_DATE, "2013-05-17 16:59:30 +0000 UTC"},
|
||||
}
|
||||
|
||||
|
@ -265,14 +265,14 @@ func TestSkipRender(t *testing.T) {
|
|||
doc string
|
||||
expected string
|
||||
}{
|
||||
{"sect/doc1.html", "<h1>title</h1>\n\n<p>some <em>content</em></p>\n"},
|
||||
{"sect/doc1.html", "\n\n<h1 id=\"toc_0\">title</h1>\n\n<p>some <em>content</em></p>\n"},
|
||||
{"sect/doc2.html", "<!doctype html><html><body>more content</body></html>"},
|
||||
{"sect/doc3.html", "<h1>doc3</h1>\n\n<p><em>some</em> content</p>\n"},
|
||||
{"sect/doc4.html", "<h1>doc4</h1>\n\n<p><em>some content</em></p>\n"},
|
||||
{"sect/doc3.html", "\n\n<h1 id=\"toc_0\">doc3</h1>\n\n<p><em>some</em> content</p>\n"},
|
||||
{"sect/doc4.html", "\n\n<h1 id=\"toc_0\">doc4</h1>\n\n<p><em>some content</em></p>\n"},
|
||||
{"sect/doc5.html", "<!doctype html><html><head><script src=\"script.js\"></script></head><body>body5</body></html>"},
|
||||
{"sect/doc6.html", "<!doctype html><html><head><script src=\"http://auth/bub/script.js\"></script></head><body>body5</body></html>"},
|
||||
{"doc7.html", "<html><body>doc7 content</body></html>"},
|
||||
{"sect/doc8.html", "<h1>title</h1>\n\n<p>some <em>content</em></p>\n"},
|
||||
{"sect/doc8.html", "\n\n<h1 id=\"toc_0\">title</h1>\n\n<p>some <em>content</em></p>\n"},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
|
Loading…
Reference in a new issue