hackdoc: render TOC inline

Change-Id: Ib91e4d3b73354e7e19095ea62eed70a23ef96512
changes/43/443/1
q3k 2020-09-23 18:13:05 +00:00
parent 80380f4444
commit 0a2f413b4c
4 changed files with 43 additions and 28 deletions

View File

@ -13,6 +13,16 @@ You can pass a `?ref=foo` URL parameter to a hackdoc URL to get it to render a p
- https://hackdoc.hackerspace.pl/?ref=master for the `master` branch
- https://hackdoc.hackerspace.pl/?ref=change/249 for the the source code at change '249'
Special Markdown
----------------
We should be accepting a Somewhat Standard Subset Of Markdown. For reference, we're using the [blackfriday](https://godoc.org/gopkg.in/russross/blackfriday.v2) library with [CommonExtensions](https://godoc.org/gopkg.in/russross/blackfriday.v2#CommonExtensions) enabled.
In addition, we also support Table of Contents autorendering, just place the following anywhere in your document to render a TOC:
[TOC]
Local Rendering
---------------

View File

@ -28,11 +28,18 @@ func renderMarkdown(input []byte, ref string) []byte {
parser := blackfriday.New(blackfriday.WithRenderer(r), blackfriday.WithExtensions(blackfriday.CommonExtensions))
ast := parser.Parse(input)
// Render table of contents (raw HTML) into bytes.
var tocB bytes.Buffer
tocB.Write([]byte(`<div class="toc">`))
r.RenderHeader(&tocB, ast)
tocB.Write([]byte(`</div>`))
toc := tocB.Bytes()
var buf bytes.Buffer
buf.Write([]byte(`<div class="toc"><h1>Page Contents</h1>`))
r.RenderHeader(&buf, ast)
buf.Write([]byte(`</div><div class="content">`))
buf.Write([]byte(`<div class="content">`))
// Render Markdown with some custom behaviour.
ast.Walk(func(node *blackfriday.Node, entering bool) blackfriday.WalkStatus {
// Fix intra-hackdoc links to contain ?ref=
if ref != "" && entering && node.Type == blackfriday.Link || node.Type == blackfriday.Image {
dest := string(node.Destination)
u, err := url.Parse(dest)
@ -41,9 +48,14 @@ func renderMarkdown(input []byte, ref string) []byte {
q["ref"] = []string{ref}
u.RawQuery = q.Encode()
node.Destination = []byte(u.String())
glog.Infof("link fix %q -> %q", dest, u.String())
glog.V(10).Infof("link fix %q -> %q", dest, u.String())
}
}
// Replace [TOC] anchor with a rendered TOC.
if entering && node.Type == blackfriday.Text && string(node.Literal) == "[TOC]" {
buf.Write(toc)
return blackfriday.GoToNext
}
return r.RenderNode(&buf, node, entering)
})
buf.Write([]byte(`</div>`))

View File

@ -169,7 +169,7 @@ h1,h2,h3,h4 {
line-height: 1.5em;
}
.content ul {
.content :not(li) > ul {
padding-top: 0.5em;
line-height: 1.5em;
}
@ -178,12 +178,20 @@ h1,h2,h3,h4 {
padding-left: 1em;
}
.content ul li::before {
.content :not(li) > ul > li::before {
content: "•";
color: #333;;
display: inline-block;
width: 1em;
margin-left: -1em;
margin-left: -0.5em;
}
.content li > ul > li::before {
content: "◦";
color: #333;;
display: inline-block;
width: 1em;
margin-left: -0.5em;
}
.content img {
@ -193,37 +201,19 @@ h1,h2,h3,h4 {
}
.toc {
float: right;
padding: 1em 1em 1em 1em;
padding: .5em;
border: 1px solid #ddd;
background-color: #f8f8f8;
margin: 2em;
max-width: 30%;
}
.toc h1 {
font-size: 1.2em;
padding-bottom: 0.5em;
font-size: 1em;
font-family: sans-serif;
}
.toc a {
text-decoration: none;
}
.toc li {
padding-left: 0.5em;
}
.toc ul {
list-style-type: disc;
padding-left: 1em;
}
.toc ul ul {
list-style-type: circle;
}
</style>
{{ end }}
{{ define "body" }}

View File

@ -3,6 +3,8 @@ Your first hscloud Change
This codelab will teach you how to send your first change to hscloud. We'll be modifying some files in your personal directory, so you won't bother anyone or break anything.
[TOC]
Prerequisites
-------------
@ -190,3 +192,4 @@ Further steps
- If you need a **Git refresher** - we highly recommend the [Git Visual Reference](https://marklodato.github.io/visual-git-guide/index-en.html)
- While this codelab showed you how to create and submit CRs, you didn't see anything about code review. Watch this space for a codelab about that.
- You should now be able to commit and change code. Watch this space for a link to a codelab on using Bazel or writing a simple microservice in Go.