Tidy up Markdown at-mentions in plain text form
This commit is contained in:
parent
688d2e0baa
commit
1935b28ee5
|
@ -10,11 +10,11 @@ import (
|
||||||
// returned by the scope list function.
|
// returned by the scope list function.
|
||||||
func TestAdminScopesCount(t *testing.T) {
|
func TestAdminScopesCount(t *testing.T) {
|
||||||
var scopes = config.ListAdminScopes()
|
var scopes = config.ListAdminScopes()
|
||||||
if len(scopes) != config.QuantityAdminScopes || len(scopes) != len(config.AdminScopeDescriptions) {
|
if len(scopes) != config.QuantityAdminScopes || len(scopes) != len(config.AdminScopeDescriptions)-1 {
|
||||||
t.Errorf(
|
t.Errorf(
|
||||||
"The list of scopes returned by ListAdminScopes doesn't match the expected count. "+
|
"The list of scopes returned by ListAdminScopes doesn't match the expected count. "+
|
||||||
"Expected %d, got %d",
|
"Expected %d (with %d descriptions), got %d",
|
||||||
config.QuantityAdminScopes,
|
config.QuantityAdminScopes, len(config.AdminScopeDescriptions),
|
||||||
len(scopes),
|
len(scopes),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,18 @@
|
||||||
package markdown
|
package markdown
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/microcosm-cc/bluemonday"
|
"github.com/microcosm-cc/bluemonday"
|
||||||
"github.com/shurcooL/github_flavored_markdown"
|
"github.com/shurcooL/github_flavored_markdown"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
RegexpHTMLTag = regexp.MustCompile(`<(.|\n)+?>`)
|
||||||
|
RegexpMarkdownLink = regexp.MustCompile(`\[([^\[\]]*)\]\((.*?)\)`)
|
||||||
|
)
|
||||||
|
|
||||||
// Render markdown from untrusted sources.
|
// Render markdown from untrusted sources.
|
||||||
func Render(input string) string {
|
func Render(input string) string {
|
||||||
// Render Markdown to HTML.
|
// Render Markdown to HTML.
|
||||||
|
@ -27,3 +33,28 @@ func Quotify(input string) string {
|
||||||
}
|
}
|
||||||
return strings.Join(lines, "\n")
|
return strings.Join(lines, "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
DeMarkify strips some Markdown syntax from plain text snippets.
|
||||||
|
|
||||||
|
It is especially useful on Forum views that show plain text contents of posts, and especially
|
||||||
|
for linked at-mentions of the form `[@username](/go/comment?id=1234)` so that those can be
|
||||||
|
simplified down to just the `@username` text contents.
|
||||||
|
|
||||||
|
This function will strip and simplify:
|
||||||
|
|
||||||
|
- Markdown hyperlinks as spelled out above
|
||||||
|
- Literal HTML tags such as <a href="">
|
||||||
|
*/
|
||||||
|
func DeMarkify(input string) string {
|
||||||
|
// Strip all standard HTML tags.
|
||||||
|
input = RegexpHTMLTag.ReplaceAllString(input, "")
|
||||||
|
|
||||||
|
// Replace Markdown hyperlinks.
|
||||||
|
matches := RegexpMarkdownLink.FindAllStringSubmatch(input, -1)
|
||||||
|
for _, m := range matches {
|
||||||
|
input = strings.ReplaceAll(input, m[0], m[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
return input
|
||||||
|
}
|
||||||
|
|
38
pkg/markdown/markdown_test.go
Normal file
38
pkg/markdown/markdown_test.go
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
package markdown_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"code.nonshy.com/nonshy/website/pkg/markdown"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDeMarkify(t *testing.T) {
|
||||||
|
var cases = []struct {
|
||||||
|
Input string
|
||||||
|
Expect string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Input: "Hello world!",
|
||||||
|
Expect: "Hello world!",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Input: "[@username](/go/comment?id=1234) Very well said!",
|
||||||
|
Expect: "@username Very well said!",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Input: `<a href="https://wikipedia.org">Wikipedia</a> said **otherwise.**`,
|
||||||
|
Expect: "Wikipedia said **otherwise.**",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Input: "[Here](/here) is one [link](https://example.com), while [Here](/here) is [another](/another).",
|
||||||
|
Expect: "Here is one link, while Here is another.",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tc := range cases {
|
||||||
|
actual := markdown.DeMarkify(tc.Input)
|
||||||
|
if actual != tc.Expect {
|
||||||
|
t.Errorf("Test #%d: expected '%s' but got '%s'", i, tc.Expect, actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -36,6 +36,7 @@ func TemplateFuncs(r *http.Request) template.FuncMap {
|
||||||
"ComputeAge": utility.Age,
|
"ComputeAge": utility.Age,
|
||||||
"Split": strings.Split,
|
"Split": strings.Split,
|
||||||
"ToMarkdown": ToMarkdown,
|
"ToMarkdown": ToMarkdown,
|
||||||
|
"DeMarkify": markdown.DeMarkify,
|
||||||
"ToJSON": ToJSON,
|
"ToJSON": ToJSON,
|
||||||
"ToHTML": ToHTML,
|
"ToHTML": ToHTML,
|
||||||
"ToString": func(v interface{}) string {
|
"ToString": func(v interface{}) string {
|
||||||
|
|
|
@ -132,7 +132,7 @@
|
||||||
{{if .Pinned}}<sup class="fa fa-thumbtack has-text-success mr-2 is-size-6" title="Pinned"></sup>{{end}}
|
{{if .Pinned}}<sup class="fa fa-thumbtack has-text-success mr-2 is-size-6" title="Pinned"></sup>{{end}}
|
||||||
{{or .Title "Untitled"}}
|
{{or .Title "Untitled"}}
|
||||||
</h2>
|
</h2>
|
||||||
{{TrimEllipses .Comment.Message 256}}
|
{{TrimEllipses (DeMarkify .Comment.Message) 256}}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<hr class="has-background-success my-2">
|
<hr class="has-background-success my-2">
|
||||||
|
|
|
@ -126,7 +126,7 @@
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<a href="/forum/thread/{{.ThreadID}}" class="has-text-dark">
|
<a href="/forum/thread/{{.ThreadID}}" class="has-text-dark">
|
||||||
{{TrimEllipses .Thread.Comment.Message 256}}
|
{{TrimEllipses (DeMarkify .Thread.Comment.Message) 256}}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{{$Photos := $Root.PhotoMap.Get .Thread.Comment.ID}}
|
{{$Photos := $Root.PhotoMap.Get .Thread.Comment.ID}}
|
||||||
|
@ -191,7 +191,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a href="/go/comment?id={{.Comment.ID}}" class="has-text-dark">
|
<a href="/go/comment?id={{.Comment.ID}}" class="has-text-dark">
|
||||||
{{TrimEllipses .Comment.Message 256}}
|
{{TrimEllipses (DeMarkify .Comment.Message) 256}}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{{$Photos := $Root.PhotoMap.Get .Comment.ID}}
|
{{$Photos := $Root.PhotoMap.Get .Comment.ID}}
|
||||||
|
|
|
@ -165,7 +165,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a href="/go/comment?id={{.ID}}" class="has-text-dark">
|
<a href="/go/comment?id={{.ID}}" class="has-text-dark">
|
||||||
{{TrimEllipses .Message 512}}
|
{{TrimEllipses (DeMarkify .Message) 512}}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{{$Photos := $Root.PhotoMap.Get .ID}}
|
{{$Photos := $Root.PhotoMap.Get .ID}}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user