From 4ef28e6c7e1ade14b9b89de9206173184c887ad4 Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Sat, 17 Aug 2019 16:34:28 +0100 Subject: [PATCH] Add non-blocking-space A backslash-space is a non-blocking-space that is recognized when enabling the NonBlockingSpace extension. Signed-off-by: Miek Gieben --- README.md | 3 +++ ast/node.go | 5 +++++ html/renderer.go | 6 ++++++ parser/inline.go | 4 ++++ parser/parser.go | 1 + 5 files changed, 19 insertions(+) diff --git a/README.md b/README.md index 4a14212..52ee67c 100644 --- a/README.md +++ b/README.md @@ -241,6 +241,9 @@ implements the following extensions: * **Hard line breaks**. With this extension enabled newlines in the input translate into line breaks in the output. This extension is off by default. +* **Non blocking space**. With this extension enabled spaces preceeded by an backslash n the input + translate non-blocking spaces in the output. This extension is off by default. + * **Smart quotes**. Smartypants-style punctuation substitution is supported, turning normal double- and single-quote marks into curly quotes, etc. diff --git a/ast/node.go b/ast/node.go index 329223a..e6fcba9 100644 --- a/ast/node.go +++ b/ast/node.go @@ -313,6 +313,11 @@ type Hardbreak struct { Leaf } +// NonBlockingSpace represents markdown non-blocking space node +type NonBlockingSpace struct { + Leaf +} + // Code represents markdown code node type Code struct { Leaf diff --git a/html/renderer.go b/html/renderer.go index af8da22..367f7df 100644 --- a/html/renderer.go +++ b/html/renderer.go @@ -446,6 +446,10 @@ func (r *Renderer) hardBreak(w io.Writer, node *ast.Hardbreak) { r.cr(w) } +func (r *Renderer) nonBlockingSpace(w io.Writer, node *ast.NonBlockingSpace) { + r.outs(w, " ") +} + func (r *Renderer) outOneOf(w io.Writer, outFirst bool, first string, second string) { if outFirst { r.outs(w, first) @@ -924,6 +928,8 @@ func (r *Renderer) RenderNode(w io.Writer, node ast.Node, entering bool) ast.Wal // TODO: make it configurable via out(renderer.softbreak) case *ast.Hardbreak: r.hardBreak(w, node) + case *ast.NonBlockingSpace: + r.nonBlockingSpace(w, node) case *ast.Emph: r.outOneOf(w, entering, "", "") case *ast.Strong: diff --git a/parser/inline.go b/parser/inline.go index bf2e46b..81766b8 100644 --- a/parser/inline.go +++ b/parser/inline.go @@ -695,6 +695,10 @@ func escape(p *Parser, data []byte, offset int) (int, ast.Node) { return 2, nil } + if p.extensions&NonBlockingSpace != 0 && data[1] == ' ' { + return 2, &ast.NonBlockingSpace{} + } + if p.extensions&BackslashLineBreak != 0 && data[1] == '\n' { return 2, &ast.Hardbreak{} } diff --git a/parser/parser.go b/parser/parser.go index bb741da..c7302df 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -27,6 +27,7 @@ const ( LaxHTMLBlocks // Loosen up HTML block parsing rules SpaceHeadings // Be strict about prefix heading rules HardLineBreak // Translate newlines into line breaks + NonBlockingSpace // Translate backspace spaces into line non-blocking spaces TabSizeEight // Expand tabs to eight spaces instead of four Footnotes // Pandoc-style footnotes NoEmptyLineBeforeBlock // No need to insert an empty line to start a (code, quote, ordered list, unordered list) block