From acce9f9b70053fafb4572bd7fcfc66c3a7ed1f8c Mon Sep 17 00:00:00 2001
From: Gusted <postmaster@gusted.xyz>
Date: Tue, 8 Aug 2023 15:25:40 +0200
Subject: [PATCH] [GITEA] Fix media description render for orgmode

- In org mode you can specify an description for media via the following
syntax `[[description][media link]]`. The description is then used as
title or alt.
- This patch fixes the rendering of the description by seperating the
description and non-description cases and using `org.String()`.
- Added unit tests.
- Inspired by https://github.com/niklasfasching/go-org/blob/6eb20dbda93cb88c3503f7508dc78cbbc639378f/org/html_writer.go#L406-L427
- Resolves https://codeberg.org/Codeberg/Community/issues/848

(cherry picked from commit ef2456e1b16be50a31c32d69c86f0e07971f5ff2)
(cherry picked from commit b6559b4825d90da8a6acdfb266d8aa4b712a8e49)
(cherry picked from commit d6dcc34492221bea782ee697bdf3e623ff5927a7)
(cherry picked from commit 8b8aab83113b34bade61964e2097ed497abc39e9)
(cherry picked from commit b9e0297bc8001b543b6e6c0e6864f9686b345772)
---
 modules/markup/orgmode/orgmode.go      | 28 ++++++++++++++++++--------
 modules/markup/orgmode/orgmode_test.go | 14 ++++++++++++-
 2 files changed, 33 insertions(+), 9 deletions(-)

diff --git a/modules/markup/orgmode/orgmode.go b/modules/markup/orgmode/orgmode.go
index a6dac12039..7a95ab518c 100644
--- a/modules/markup/orgmode/orgmode.go
+++ b/modules/markup/orgmode/orgmode.go
@@ -153,18 +153,30 @@ func (r *Writer) WriteRegularLink(l org.RegularLink) {
 		link = []byte(util.URLJoin(r.URLPrefix, lnk))
 	}
 
-	description := string(link)
-	if l.Description != nil {
-		description = r.WriteNodesAsString(l.Description...)
-	}
 	switch l.Kind() {
 	case "image":
-		imageSrc := getMediaURL(link)
-		fmt.Fprintf(r, `<img src="%s" alt="%s" title="%s" />`, imageSrc, description, description)
+		if l.Description == nil {
+			imageSrc := getMediaURL(link)
+			fmt.Fprintf(r, `<img src="%s" alt="%s" title="%s" />`, imageSrc, link, link)
+		} else {
+			description := strings.TrimPrefix(org.String(l.Description...), "file:")
+			imageSrc := getMediaURL([]byte(description))
+			fmt.Fprintf(r, `<a href="%s"><img src="%s" alt="%s" /></a>`, link, imageSrc, imageSrc)
+		}
 	case "video":
-		videoSrc := getMediaURL(link)
-		fmt.Fprintf(r, `<video src="%s" title="%s">%s</video>`, videoSrc, description, description)
+		if l.Description == nil {
+			imageSrc := getMediaURL(link)
+			fmt.Fprintf(r, `<video src="%s" title="%s">%s</video>`, imageSrc, link, link)
+		} else {
+			description := strings.TrimPrefix(org.String(l.Description...), "file:")
+			videoSrc := getMediaURL([]byte(description))
+			fmt.Fprintf(r, `<a href="%s"><video src="%s" title="%s"></video></a>`, link, videoSrc, videoSrc)
+		}
 	default:
+		description := string(link)
+		if l.Description != nil {
+			description = r.WriteNodesAsString(l.Description...)
+		}
 		fmt.Fprintf(r, `<a href="%s" title="%s">%s</a>`, link, description, description)
 	}
 }
diff --git a/modules/markup/orgmode/orgmode_test.go b/modules/markup/orgmode/orgmode_test.go
index d6467c36f7..8f454e9955 100644
--- a/modules/markup/orgmode/orgmode_test.go
+++ b/modules/markup/orgmode/orgmode_test.go
@@ -42,7 +42,7 @@ func TestRender_StandardLinks(t *testing.T) {
 		"<p><a href=\""+lnk+"\" title=\"WikiPage\">WikiPage</a></p>")
 }
 
-func TestRender_Images(t *testing.T) {
+func TestRender_Media(t *testing.T) {
 	setting.AppURL = AppURL
 	setting.AppSubURL = AppSubURL
 
@@ -60,6 +60,18 @@ func TestRender_Images(t *testing.T) {
 
 	test("[[file:"+url+"]]",
 		"<p><img src=\""+result+"\" alt=\""+result+"\" title=\""+result+"\" /></p>")
+
+	// With description.
+	test("[[https://example.com][https://example.com/example.svg]]",
+		`<p><a href="https://example.com"><img src="https://example.com/example.svg" alt="https://example.com/example.svg" /></a></p>`)
+	test("[[https://example.com][https://example.com/example.mp4]]",
+		`<p><a href="https://example.com"><video src="https://example.com/example.mp4" title="https://example.com/example.mp4"></video></a></p>`)
+
+	// Without description.
+	test("[[https://example.com/example.svg]]",
+		`<p><img src="https://example.com/example.svg" alt="https://example.com/example.svg" title="https://example.com/example.svg" /></p>`)
+	test("[[https://example.com/example.mp4]]",
+		`<p><video src="https://example.com/example.mp4" title="https://example.com/example.mp4">https://example.com/example.mp4</video></p>`)
 }
 
 func TestRender_Source(t *testing.T) {