From ccd38f9a701da4ca7e0bc096674420717ee40c0d Mon Sep 17 00:00:00 2001 From: Giteabot Date: Sun, 26 Jul 2026 09:58:22 -0700 Subject: [PATCH] fix: orgmode render include path (#38642) (#38645) Backport #38642 Co-authored-by: wxiaoguang Co-authored-by: TheFox0x7 Co-authored-by: bircni --- modules/markup/orgmode/orgmode.go | 10 +++- modules/markup/orgmode/orgmode_test.go | 74 +++++++++++--------------- 2 files changed, 40 insertions(+), 44 deletions(-) diff --git a/modules/markup/orgmode/orgmode.go b/modules/markup/orgmode/orgmode.go index 37184dcdac..bcb0df8ffd 100644 --- a/modules/markup/orgmode/orgmode.go +++ b/modules/markup/orgmode/orgmode.go @@ -70,7 +70,15 @@ func Render(ctx *markup.RenderContext, input io.Reader, output io.Writer) error w := &orgWriter{rctx: ctx, HTMLWriter: htmlWriter} htmlWriter.ExtendingWriter = w - res, err := org.New().Silent().Parse(input, "").Write(w) + cfg := org.New() + cfg.ReadFile = func(path string) ([]byte, error) { + // actually the orgmode render doesn't support rendering the content from the content again, + // so just leave the plain text to end users + content := fmt.Sprintf("#+INCLUDE: [[%s]]", path) + return []byte(content), nil + } + doc := cfg.Silent().Parse(input, "") + res, err := doc.Write(w) if err != nil { return fmt.Errorf("orgmode.Render failed: %w", err) } diff --git a/modules/markup/orgmode/orgmode_test.go b/modules/markup/orgmode/orgmode_test.go index d18660b054..28607a1531 100644 --- a/modules/markup/orgmode/orgmode_test.go +++ b/modules/markup/orgmode/orgmode_test.go @@ -21,86 +21,74 @@ func TestMain(m *testing.M) { os.Exit(m.Run()) } -func TestRender_StandardLinks(t *testing.T) { - test := func(input, expected string) { - buffer, err := orgmode.RenderString(markup.NewTestRenderContext(), input) - assert.NoError(t, err) - assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer)) - } +func testRender(t *testing.T, input, expected string) { + buffer, err := orgmode.RenderString(markup.NewTestRenderContext(), input) + assert.NoError(t, err) + assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer)) +} - test("[[https://google.com/]]", +func TestRender_StandardLinks(t *testing.T) { + testRender(t, "[[https://google.com/]]", `

https://google.com/

`) - test("[[ImageLink.svg][The Image Desc]]", + testRender(t, "[[ImageLink.svg][The Image Desc]]", `

The Image Desc

`) } func TestRender_InternalLinks(t *testing.T) { - test := func(input, expected string) { - buffer, err := orgmode.RenderString(markup.NewTestRenderContext(), input) - assert.NoError(t, err) - assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer)) - } - - test("[[file:test.org][Test]]", + testRender(t, "[[file:test.org][Test]]", `

Test

`) - test("[[./test.org][Test]]", + testRender(t, "[[./test.org][Test]]", `

Test

`) - test("[[test.org][Test]]", + testRender(t, "[[test.org][Test]]", `

Test

`) - test("[[path/to/test.org][Test]]", + testRender(t, "[[path/to/test.org][Test]]", `

Test

`) } func TestRender_Media(t *testing.T) { - test := func(input, expected string) { - buffer, err := orgmode.RenderString(markup.NewTestRenderContext(), input) - assert.NoError(t, err) - assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer)) - } - - test("[[file:../../.images/src/02/train.jpg]]", + testRender(t, "[[file:../../.images/src/02/train.jpg]]", `

../../.images/src/02/train.jpg

`) - test("[[file:train.jpg]]", + testRender(t, "[[file:train.jpg]]", `

train.jpg

`) // With description. - test("[[https://example.com][https://example.com/example.svg]]", + testRender(t, "[[https://example.com][https://example.com/example.svg]]", `

https://example.com/example.svg

`) - test("[[https://example.com][pre https://example.com/example.svg post]]", + testRender(t, "[[https://example.com][pre https://example.com/example.svg post]]", `

pre https://example.com/example.svg post

`) - test("[[https://example.com][https://example.com/example.mp4]]", + testRender(t, "[[https://example.com][https://example.com/example.mp4]]", `

`) - test("[[https://example.com][pre https://example.com/example.mp4 post]]", + testRender(t, "[[https://example.com][pre https://example.com/example.mp4 post]]", `

pre post

`) // Without description. - test("[[https://example.com/example.svg]]", + testRender(t, "[[https://example.com/example.svg]]", `

https://example.com/example.svg

`) - test("[[https://example.com/example.mp4]]", + testRender(t, "[[https://example.com/example.mp4]]", `

`) // test [[LINK][DESCRIPTION]] syntax with "file:" prefix - test(`[[https://example.com/][file:https://example.com/foo%20bar.svg]]`, + testRender(t, `[[https://example.com/][file:https://example.com/foo%20bar.svg]]`, `

https://example.com/foo%20bar.svg

`) - test(`[[file:https://example.com/foo%20bar.svg][Goto Image]]`, + testRender(t, `[[file:https://example.com/foo%20bar.svg][Goto Image]]`, `

Goto Image

`) - test(`[[file:https://example.com/link][https://example.com/image.jpg]]`, + testRender(t, `[[file:https://example.com/link][https://example.com/image.jpg]]`, `

https://example.com/image.jpg

`) - test(`[[file:https://example.com/link][file:https://example.com/image.jpg]]`, + testRender(t, `[[file:https://example.com/link][file:https://example.com/image.jpg]]`, `

https://example.com/image.jpg

`) } func TestRender_Source(t *testing.T) { - test := func(input, expected string) { - buffer, err := orgmode.RenderString(markup.NewTestRenderContext(), input) - assert.NoError(t, err) - assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer)) - } - - test(`#+begin_src c + testRender(t, `#+begin_src c int a; #+end_src `, `
int a;
`) } + +func TestRender_IncludeLink(t *testing.T) { + testRender(t, `#+INCLUDE: "./other.org" src text`, `
+
#+INCLUDE: [[other.org]]
+
`) +}