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") + }) + } +}