From 697e44ce881f864c785b78bdce80b0b48c86d712 Mon Sep 17 00:00:00 2001
From: yuin
++//= = = = = = = = = = = = = = = = = = = = = = = =// + +66: EOF should be rendered as a newline with an unclosed block +//- - - - - - - - -// +> ``` +> 0 +//- - - - - - - - -// ++0 +
++//= = = = = = = = = = = = = = = = = = = = = = = =// diff --git a/parser/blockquote.go b/parser/blockquote.go index e7778dc..8faa7ac 100644 --- a/parser/blockquote.go +++ b/parser/blockquote.go @@ -28,12 +28,13 @@ func (b *blockquoteParser) process(reader text.Reader) bool { reader.Advance(pos) return true } - if line[pos] == ' ' || line[pos] == '\t' { - pos++ - } reader.Advance(pos) - if line[pos-1] == '\t' { - reader.SetPadding(2) + if line[pos] == ' ' || line[pos] == '\t' { + padding := 0 + if line[pos] == '\t' { + padding = util.TabWidth(reader.LineOffset()) - 1 + } + reader.AdvanceAndSetPadding(1, padding) } return true } diff --git a/parser/parser.go b/parser/parser.go index 5cc2175..b59666c 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -878,10 +878,17 @@ func (p *parser) Parse(reader text.Reader, opts ...ParseOption) ast.Node { blockReader := text.NewBlockReader(reader.Source(), nil) p.walkBlock(root, func(node ast.Node) { p.parseBlock(blockReader, node, pc) + lines := node.Lines() + if lines != nil && lines.Len() != 0 { + s := lines.At(lines.Len() - 1) + s.EOB = true + lines.Set(lines.Len()-1, s) + } }) for _, at := range p.astTransformers { at.Transform(root, reader, pc) } + // root.Dump(reader.Source(), 0) return root } @@ -1256,4 +1263,5 @@ func (p *parser) parseBlock(block text.BlockReader, parent ast.Node, pc Context) for _, ip := range p.closeBlockers { ip.CloseBlock(parent, block, pc) } + } diff --git a/text/segment.go b/text/segment.go index badd4bc..3198d84 100644 --- a/text/segment.go +++ b/text/segment.go @@ -2,6 +2,7 @@ package text import ( "bytes" + "github.com/yuin/goldmark/util" ) @@ -18,6 +19,9 @@ type Segment struct { // Padding is a padding length of the segment. Padding int + + // EOB is true if the segment is end of the block. + EOB bool } // NewSegment return a new Segment. @@ -45,7 +49,11 @@ func (t *Segment) Value(buffer []byte) []byte { } result := make([]byte, 0, t.Padding+t.Stop-t.Start+1) result = append(result, bytes.Repeat(space, t.Padding)...) - return append(result, buffer[t.Start:t.Stop]...) + result = append(result, buffer[t.Start:t.Stop]...) + if t.EOB && len(result) > 0 && result[len(result)-1] != '\n' { + result = append(result, '\n') + } + return result } // Len returns a length of the segment. diff --git a/util/util.go b/util/util.go index e2c92c6..aa9863f 100644 --- a/util/util.go +++ b/util/util.go @@ -166,7 +166,13 @@ func IndentPositionPadding(bs []byte, currentPos, paddingv, width int) (pos, pad w := 0 i := 0 l := len(bs) + p := paddingv for ; i < l; i++ { + if p > 0 { + p-- + w++ + continue + } if bs[i] == '\t' && w < width { w += TabWidth(currentPos + w) } else if bs[i] == ' ' && w < width {+0 +