mirror of
https://github.com/go-sylixos/elvish.git
synced 2024-12-13 01:47:51 +08:00
pkg/md: Refine list support, and enable more tests.
This commit is contained in:
parent
cc8a7b2207
commit
1e3043bb4f
34
pkg/md/md.go
34
pkg/md/md.go
|
@ -65,9 +65,9 @@ type blockParser struct {
|
|||
}
|
||||
|
||||
var (
|
||||
// Group 1: blockquote marker, group 2: bullet list item, group 3: ordered
|
||||
// list marker; group 4: ordered list start index
|
||||
containerMarkerRegexp = regexp.MustCompile(`^ {0,3}(?:(> ?)|([-+*] {1,4})|(([0-9]{1,9})[.)] {1,4}))`)
|
||||
// Group 1: blockquote marker, group 2: bullet item punctuation, group 3: ordered
|
||||
// item start index; group 4: ordered item punctuation
|
||||
containerMarkerRegexp = regexp.MustCompile(`^ {0,3}(?:(> ?)|([-+*]) {1,4}|([0-9]{1,9})([.)]) {1,4})`)
|
||||
thematicBreakRegexp = regexp.MustCompile(`^[ \t]*((?:-[ \t]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})$`)
|
||||
// Group 1: heading opener
|
||||
atxHeadingRegexp = regexp.MustCompile(`^ *(#{1,6})(?:[ \t]|$)`)
|
||||
|
@ -129,7 +129,7 @@ func (p *blockParser) render() {
|
|||
// containers matched.
|
||||
func matchContinuationMarkers(line string, containers []container) (string, int) {
|
||||
for i, container := range containers {
|
||||
markerLen, matched := container.findMarker(line)
|
||||
markerLen, matched := container.findContinuationMarker(line)
|
||||
if !matched {
|
||||
return line, i
|
||||
}
|
||||
|
@ -148,10 +148,10 @@ func parseStartingMarkers(line string) (string, []container) {
|
|||
if m == nil {
|
||||
break
|
||||
}
|
||||
marker, blockquoteMarker, bullet, orderedStart := m[0], m[1], m[2], m[4]
|
||||
marker, bq, bulletPunct, orderedStart, orderedPunct := m[0], m[1], m[2], m[3], m[4]
|
||||
line = line[len(marker):]
|
||||
var c container
|
||||
if blockquoteMarker != "" {
|
||||
if bq != "" {
|
||||
c.typ = blockquote
|
||||
} else {
|
||||
indent := len(marker)
|
||||
|
@ -159,10 +159,12 @@ func parseStartingMarkers(line string) (string, []container) {
|
|||
indent = len(strings.TrimRight(marker, " \t")) + 1
|
||||
}
|
||||
c.indent = strings.Repeat(" ", indent)
|
||||
if bullet != "" {
|
||||
if bulletPunct != "" {
|
||||
c.typ = bulletItem
|
||||
} else { // ordered != ""
|
||||
c.punct = bulletPunct[0]
|
||||
} else {
|
||||
c.typ = orderedItem
|
||||
c.punct = orderedPunct[0]
|
||||
c.start, _ = strconv.Atoi(orderedStart)
|
||||
}
|
||||
}
|
||||
|
@ -172,17 +174,20 @@ func parseStartingMarkers(line string) (string, []container) {
|
|||
}
|
||||
|
||||
func (p *blockParser) appendContainer(c container) {
|
||||
if (p.leafContainerIs(bulletList) && c.typ != bulletItem) ||
|
||||
(p.leafContainerIs(orderedList) && c.typ != orderedItem) {
|
||||
p.popLeafContainer()
|
||||
if len(p.containers) > 0 {
|
||||
leaf := p.containers[len(p.containers)-1]
|
||||
if (leaf.typ == bulletList || leaf.typ == orderedList) && leaf.punct != c.punct {
|
||||
p.popLeafContainer()
|
||||
}
|
||||
}
|
||||
|
||||
if c.typ == bulletItem && !p.leafContainerIs(bulletList) {
|
||||
p.containers = append(p.containers, container{typ: bulletList})
|
||||
p.containers = append(p.containers, container{typ: bulletList, punct: c.punct})
|
||||
p.sb.WriteString(p.syntax.BulletList.Start)
|
||||
p.sb.WriteByte('\n')
|
||||
}
|
||||
if c.typ == orderedItem && !p.leafContainerIs(orderedList) {
|
||||
p.containers = append(p.containers, container{typ: orderedList})
|
||||
p.containers = append(p.containers, container{typ: orderedList, punct: c.punct})
|
||||
p.sb.WriteString(p.syntax.OrderedList(c.start).Start)
|
||||
p.sb.WriteByte('\n')
|
||||
}
|
||||
|
@ -251,6 +256,7 @@ func (s *lineSplitter) next() string {
|
|||
|
||||
type container struct {
|
||||
typ containerType
|
||||
punct byte
|
||||
start int
|
||||
indent string
|
||||
}
|
||||
|
@ -267,7 +273,7 @@ const (
|
|||
|
||||
var blockquoteMarkerRegexp = regexp.MustCompile(`^ {0,3}> ?`)
|
||||
|
||||
func (c container) findMarker(line string) (int, bool) {
|
||||
func (c container) findContinuationMarker(line string) (int, bool) {
|
||||
switch c.typ {
|
||||
case blockquote:
|
||||
marker := blockquoteMarkerRegexp.FindString(line)
|
||||
|
|
|
@ -113,9 +113,10 @@ var htmlSyntax = OutputSyntax{
|
|||
}
|
||||
|
||||
var (
|
||||
linkRef = regexp.MustCompile(`(^|\n)\[([^\\\[\]]|\\[\\\[\]])+\]:`)
|
||||
codeBlock = regexp.MustCompile("(^|\n)>*(```|~~~| )")
|
||||
linkRef = regexp.MustCompile(`(^|\n) {0,3}\[([^\\\[\]]|\\[\\\[\]])+\]:`)
|
||||
codeBlock = regexp.MustCompile("(^|\n)[ >]*(```|~~~| )")
|
||||
emptyListItem = regexp.MustCompile(`(^|\n)([-+*]|[0-9]{1,9}[.)])(\n|$)`)
|
||||
htmlBlock = regexp.MustCompile(`(^|\n)(<a |<!--)`)
|
||||
)
|
||||
|
||||
func TestRender(t *testing.T) {
|
||||
|
@ -140,7 +141,7 @@ func TestRender(t *testing.T) {
|
|||
if emptyListItem.MatchString(tc.Markdown) {
|
||||
t.Skipf("Empty list item not supported")
|
||||
}
|
||||
if strings.HasPrefix(tc.Markdown, "<a ") {
|
||||
if htmlBlock.MatchString(tc.Markdown) {
|
||||
t.Skipf("HTML block not supported")
|
||||
}
|
||||
|
||||
|
@ -161,8 +162,7 @@ func unsupportedSection(section string) bool {
|
|||
"Indented code blocks",
|
||||
"Fenced code blocks",
|
||||
"HTML blocks",
|
||||
"Link reference definitions",
|
||||
"Lists":
|
||||
"Link reference definitions":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
|
@ -173,6 +173,10 @@ func unsupportedExample(example int) string {
|
|||
switch example {
|
||||
case 59, 300:
|
||||
return "has setext heading"
|
||||
case 304:
|
||||
return "rejection of non-1 starter not implemented yet"
|
||||
case 320, 321, 323:
|
||||
return "tight list not implemented"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user