diff --git a/cmd/hype/cli/vscode.go b/cmd/hype/cli/vscode.go
index 4f511d0..d6cb7d9 100644
--- a/cmd/hype/cli/vscode.go
+++ b/cmd/hype/cli/vscode.go
@@ -49,7 +49,7 @@ func (cmd *VSCode) Flags() (*flag.FlagSet, error) {
return cmd.flags, nil
}
-func (cmd *VSCode) Main(ctx context.Context, pwd string, args []string) error {
+func (cmd *VSCode) Main(ctx context.Context, _ string, args []string) error {
if err := cmd.validate(); err != nil {
return err
}
@@ -77,14 +77,14 @@ func (cmd *VSCode) Main(ctx context.Context, pwd string, args []string) error {
path := args[0]
- pwd = filepath.Dir(path)
+ dir := filepath.Dir(path)
name := filepath.Base(path)
- cmd.FS = os.DirFS(pwd)
+ cmd.FS = os.DirFS(dir)
err = WithTimeout(ctx, cmd.Timeout, func(ctx context.Context) error {
- return WithinDir(pwd, func() error {
- return cmd.execute(ctx, pwd, name)
+ return WithinDir(dir, func() error {
+ return cmd.execute(ctx, dir, name)
})
})
diff --git a/mdx/parser.go b/mdx/parser.go
index 22d96b0..9d9c6d7 100644
--- a/mdx/parser.go
+++ b/mdx/parser.go
@@ -5,6 +5,7 @@ import (
"fmt"
"io"
"regexp"
+ "strconv"
"strings"
"sync"
@@ -46,15 +47,19 @@ func New() *Parser {
return p
}
-func (p *Parser) parse(lines []string) ([]byte, error) {
+func (p *Parser) parse(lines []string, fenced []bool) ([]byte, error) {
bb := &bytes.Buffer{}
var chunk []string
var after string
var ind int
- for _, line := range lines {
+ for i, line := range lines {
ind++
+ if fenced[i] {
+ chunk = append(chunk, line)
+ continue
+ }
if strings.HasPrefix(line, "\n~~~\n\n---\n\n# Second"
+
+ p := New()
+ out, err := p.Parse([]byte(src))
+ r.NoError(err)
+
+ act := string(out)
+ r.Equal(2, strings.Count(act, ""))
+ r.Contains(act, "--------\nGo Version: go1.25.0\n\n")
+ r.Contains(act, "Next
")
+ r.Contains(act, "<include src="x.md"></include>")
+ r.Contains(act, "Second
")
+}
+
+func Test_Parser_Parse_InlineCodeIsNotFence(t *testing.T) {
+ t.Parallel()
+ r := require.New(t)
+
+ src := "# Title\n\n``` use ``code`` ```\n\n---\n\n# Second"
+
+ p := New()
+ out, err := p.Parse([]byte(src))
+ r.NoError(err)
+
+ r.Equal(2, strings.Count(string(out), ""))
+}
+
+func Test_Parser_Parse_FenceInsideHTMLBlock(t *testing.T) {
+ t.Parallel()
+ r := require.New(t)
+
+ src := "# Title\n\n\n```\n
\n\n---\n\n# Second\n\n```go\nx := 1\n```\n"
+
+ p := New()
+ out, err := p.Parse([]byte(src))
+ r.NoError(err)
+
+ act := string(out)
+ r.Equal(2, strings.Count(act, ""))
+ r.Contains(act, "Second
")
+}
+
+func Test_Parser_Parse_FenceCloseMustMatchExactly(t *testing.T) {
+ t.Parallel()
+
+ tcs := []struct {
+ name string
+ close string
+ }{
+ {name: "longer marker", close: "````"},
+ {name: "trailing spaces", close: "``` "},
+ }
+
+ for _, tc := range tcs {
+ t.Run(tc.name, func(t *testing.T) {
+ t.Parallel()
+ r := require.New(t)
+
+ src := "# Title\n\n```\nbefore\n" + tc.close + "\n---\nafter\n```\n"
+
+ p := New()
+ out, err := p.Parse([]byte(src))
+ r.NoError(err)
+
+ act := string(out)
+ r.Equal(1, strings.Count(act, ""))
+ r.Contains(act, "---\nafter\n")
+ })
+ }
+}