From 6c55ba55a10ada871645ab9abeb000fce17fb53b Mon Sep 17 00:00:00 2001 From: yuin Date: Wed, 27 Nov 2019 03:00:17 +0900 Subject: [PATCH] Fixes #36 --- parser/atx_heading.go | 9 ++++++--- parser/parser.go | 35 ++++++++++++++++++----------------- util/util.go | 18 ++++++++++++++++-- 3 files changed, 40 insertions(+), 22 deletions(-) diff --git a/parser/atx_heading.go b/parser/atx_heading.go index 04278ab..67f55ac 100644 --- a/parser/atx_heading.go +++ b/parser/atx_heading.go @@ -96,6 +96,9 @@ func (b *atxHeadingParser) Open(parent ast.Node, reader text.Reader, pc Context) return nil, NoChildren } start := i + l + if start >= len(line) { + start = len(line) - 1 + } origstart := start stop := len(line) - util.TrimRightSpaceLength(line) @@ -128,7 +131,7 @@ func (b *atxHeadingParser) Open(parent ast.Node, reader text.Reader, pc Context) for _, attr := range attrs { node.SetAttribute(attr.Name, attr.Value) } - node.Lines().Append(text.NewSegment(segment.Start+start+1, segment.Start+closureOpen)) + node.Lines().Append(text.NewSegment(segment.Start+start+1-segment.Padding, segment.Start+closureOpen-segment.Padding)) } } } @@ -136,7 +139,7 @@ func (b *atxHeadingParser) Open(parent ast.Node, reader text.Reader, pc Context) start = origstart stop := len(line) - util.TrimRightSpaceLength(line) if stop <= start { // empty headings like '##[space]' - stop = start + 1 + stop = start } else { i = stop - 1 for ; line[i] == '#' && i >= start; i-- { @@ -149,7 +152,7 @@ func (b *atxHeadingParser) Open(parent ast.Node, reader text.Reader, pc Context) } if len(util.TrimRight(line[start:stop], []byte{'#'})) != 0 { // empty heading like '### ###' - node.Lines().Append(text.NewSegment(segment.Start+start, segment.Start+stop)) + node.Lines().Append(text.NewSegment(segment.Start+start-segment.Padding, segment.Start+stop-segment.Padding)) } } return node, NoChildren diff --git a/parser/parser.go b/parser/parser.go index 1f1e370..d9f54f5 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -824,7 +824,7 @@ func (p *parser) Parse(reader text.Reader, opts ...ParseOption) ast.Node { for _, at := range p.astTransformers { at.Transform(root, reader, pc) } - //root.Dump(reader.Source(), 0) + // root.Dump(reader.Source(), 0) return root } @@ -1086,13 +1086,28 @@ func (p *parser) parseBlock(block text.BlockReader, parent ast.Node, pc Context) break } lineLength := len(line) + hardlineBreak := false + softLinebreak := line[lineLength-1] == '\n' + if lineLength > 2 && line[lineLength-2] == '\\' && softLinebreak { // ends with \\n + lineLength -= 2 + hardlineBreak = true + + } else if lineLength > 3 && line[lineLength-3] == '\\' && line[lineLength-2] == '\r' && softLinebreak { // ends with \\r\n + lineLength -= 3 + hardlineBreak = true + } else if lineLength > 3 && line[lineLength-3] == ' ' && line[lineLength-2] == ' ' && softLinebreak { // ends with [space][space]\n + lineLength -= 3 + hardlineBreak = true + } else if lineLength > 4 && line[lineLength-4] == ' ' && line[lineLength-3] == ' ' && line[lineLength-2] == '\r' && softLinebreak { // ends with [space][space]\r\n + lineLength -= 4 + hardlineBreak = true + } + l, startPosition := block.Position() n := 0 - softLinebreak := false for i := 0; i < lineLength; i++ { c := line[i] if c == '\n' { - softLinebreak = true break } isSpace := util.IsSpace(c) @@ -1150,20 +1165,6 @@ func (p *parser) parseBlock(block text.BlockReader, parent ast.Node, pc Context) } diff := startPosition.Between(currentPosition) stop := diff.Stop - hardlineBreak := false - if lineLength > 2 && line[lineLength-2] == '\\' && softLinebreak { // ends with \\n - stop-- - hardlineBreak = true - - } else if lineLength > 3 && line[lineLength-3] == '\\' && line[lineLength-2] == '\r' && softLinebreak { // ends with \\r\n - stop -= 2 - hardlineBreak = true - } else if lineLength > 3 && line[lineLength-3] == ' ' && line[lineLength-2] == ' ' && softLinebreak { // ends with [space][space]\n - stop-- - hardlineBreak = true - } else if lineLength > 4 && line[lineLength-4] == ' ' && line[lineLength-3] == ' ' && line[lineLength-2] == '\r' && softLinebreak { // ends with [space][space]\r\n - hardlineBreak = true - } rest := diff.WithStop(stop) text := ast.NewTextSegment(rest.TrimRightSpace(source)) text.SetSoftLineBreak(softLinebreak) diff --git a/util/util.go b/util/util.go index 64a2b90..57a2b84 100644 --- a/util/util.go +++ b/util/util.go @@ -91,7 +91,7 @@ func VisualizeSpaces(bs []byte) []byte { bs = bytes.Replace(bs, []byte(" "), []byte("[SPACE]"), -1) bs = bytes.Replace(bs, []byte("\t"), []byte("[TAB]"), -1) bs = bytes.Replace(bs, []byte("\n"), []byte("[NEWLINE]\n"), -1) - bs = bytes.Replace(bs, []byte("\r"), []byte("[CR]\n"), -1) + bs = bytes.Replace(bs, []byte("\r"), []byte("[CR]"), -1) return bs } @@ -620,8 +620,22 @@ func URLEscape(v []byte, resolveReference bool) []byte { n = i continue } + if int(u8len) >= len(v) { + u8len = int8(len(v) - 1) + } + if u8len == 0 { + i++ + n = i + continue + } cob.Write(v[n:i]) - cob.Write(StringToReadOnlyBytes(url.QueryEscape(string(v[i : i+int(u8len)])))) + stop := i + int(u8len) + if stop > len(v) { + i += 1 + n = i + continue + } + cob.Write(StringToReadOnlyBytes(url.QueryEscape(string(v[i:stop])))) i += int(u8len) n = i }