Skip to content

Commit 814ca9f

Browse files
zeripathsilverwindguillep2k
authoredMay 24, 2020
Allow different HardBreaks settings for documents and comments (#11515)
GH has different HardBreaks behaviour for markdown comments and documents. Comments have hard breaks and documents have soft breaks - therefore Gitea's rendering will always be different from GH's if we only provide one setting. Here we split the setting in to two - one for documents and one for comments and other things. Signed-off-by: Andrew Thornton art27@cantab.net Changes to index.js as per @silverwind Co-authored-by: silverwind <me@silverwind.io> Changes to docs as per @guillep2k Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com>
1 parent 3761bdb commit 814ca9f

File tree

12 files changed

+77
-29
lines changed

12 files changed

+77
-29
lines changed
 

‎custom/conf/app.ini.sample

+4-1
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,10 @@ EVENT_SOURCE_UPDATE_TIME = 10s
216216
; Render soft line breaks as hard line breaks, which means a single newline character between
217217
; paragraphs will cause a line break and adding trailing whitespace to paragraphs is not
218218
; necessary to force a line break.
219-
ENABLE_HARD_LINE_BREAK = true
219+
; Render soft line breaks as hard line breaks for comments
220+
ENABLE_HARD_LINE_BREAK_IN_COMMENTS = true
221+
; Render soft line breaks as hard line breaks for markdown documents
222+
ENABLE_HARD_LINE_BREAK_IN_DOCUMENTS = false
220223
; Comma separated list of custom URL-Schemes that are allowed as links when rendering Markdown
221224
; for example git,magnet,ftp (more at https://en.wikipedia.org/wiki/List_of_URI_schemes)
222225
; URLs starting with http and https are always displayed, whatever is put in this entry.

‎docs/content/doc/advanced/config-cheat-sheet.en-us.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,10 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
152152

153153
## Markdown (`markdown`)
154154

155-
- `ENABLE_HARD_LINE_BREAK`: **true**: Render soft line breaks as hard line breaks, which
155+
- `ENABLE_HARD_LINE_BREAK_IN_COMMENTS`: **true**: Render soft line breaks as hard line breaks in comments, which
156+
means a single newline character between paragraphs will cause a line break and adding
157+
trailing whitespace to paragraphs is not necessary to force a line break.
158+
- `ENABLE_HARD_LINE_BREAK_IN_DOCUMENTS`: **false**: Render soft line breaks as hard line breaks in documents, which
156159
means a single newline character between paragraphs will cause a line break and adding
157160
trailing whitespace to paragraphs is not necessary to force a line break.
158161
- `CUSTOM_URL_SCHEMES`: Use a comma separated list (ftp,git,svn) to indicate additional

‎models/repo.go

+19-4
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,10 @@ type Repository struct {
174174
*Mirror `xorm:"-"`
175175
Status RepositoryStatus `xorm:"NOT NULL DEFAULT 0"`
176176

177-
RenderingMetas map[string]string `xorm:"-"`
178-
Units []*RepoUnit `xorm:"-"`
179-
PrimaryLanguage *LanguageStat `xorm:"-"`
177+
RenderingMetas map[string]string `xorm:"-"`
178+
DocumentRenderingMetas map[string]string `xorm:"-"`
179+
Units []*RepoUnit `xorm:"-"`
180+
PrimaryLanguage *LanguageStat `xorm:"-"`
180181

181182
IsFork bool `xorm:"INDEX NOT NULL DEFAULT false"`
182183
ForkID int64 `xorm:"INDEX"`
@@ -545,11 +546,12 @@ func (repo *Repository) mustOwner(e Engine) *User {
545546

546547
// ComposeMetas composes a map of metas for properly rendering issue links and external issue trackers.
547548
func (repo *Repository) ComposeMetas() map[string]string {
548-
if repo.RenderingMetas == nil {
549+
if len(repo.RenderingMetas) == 0 {
549550
metas := map[string]string{
550551
"user": repo.OwnerName,
551552
"repo": repo.Name,
552553
"repoPath": repo.RepoPath(),
554+
"mode": "comment",
553555
}
554556

555557
unit, err := repo.GetUnit(UnitTypeExternalTracker)
@@ -581,6 +583,19 @@ func (repo *Repository) ComposeMetas() map[string]string {
581583
return repo.RenderingMetas
582584
}
583585

586+
// ComposeDocumentMetas composes a map of metas for properly rendering documents
587+
func (repo *Repository) ComposeDocumentMetas() map[string]string {
588+
if len(repo.DocumentRenderingMetas) == 0 {
589+
metas := map[string]string{}
590+
for k, v := range repo.ComposeMetas() {
591+
metas[k] = v
592+
}
593+
metas["mode"] = "document"
594+
repo.DocumentRenderingMetas = metas
595+
}
596+
return repo.DocumentRenderingMetas
597+
}
598+
584599
// DeleteWiki removes the actual and local copy of repository wiki.
585600
func (repo *Repository) DeleteWiki() error {
586601
return repo.deleteWiki(x)

‎modules/markup/markdown/goldmark.go

+10
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,16 @@ func (g *ASTTransformer) Transform(node *ast.Document, reader text.Reader, pc pa
151151
v.AppendChild(v, newChild)
152152
}
153153
}
154+
case *ast.Text:
155+
if v.SoftLineBreak() && !v.HardLineBreak() {
156+
renderMetas := pc.Get(renderMetasKey).(map[string]string)
157+
mode := renderMetas["mode"]
158+
if mode != "document" {
159+
v.SetHardLineBreak(setting.Markdown.EnableHardLineBreakInComments)
160+
} else {
161+
v.SetHardLineBreak(setting.Markdown.EnableHardLineBreakInDocuments)
162+
}
163+
}
154164
}
155165
return ast.WalkContinue, nil
156166
})

‎modules/markup/markdown/markdown.go

+12-8
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,19 @@ var once = sync.Once{}
2929

3030
var urlPrefixKey = parser.NewContextKey()
3131
var isWikiKey = parser.NewContextKey()
32+
var renderMetasKey = parser.NewContextKey()
3233

3334
// NewGiteaParseContext creates a parser.Context with the gitea context set
34-
func NewGiteaParseContext(urlPrefix string, isWiki bool) parser.Context {
35+
func NewGiteaParseContext(urlPrefix string, metas map[string]string, isWiki bool) parser.Context {
3536
pc := parser.NewContext(parser.WithIDs(newPrefixedIDs()))
3637
pc.Set(urlPrefixKey, urlPrefix)
3738
pc.Set(isWikiKey, isWiki)
39+
pc.Set(renderMetasKey, metas)
3840
return pc
3941
}
4042

41-
// RenderRaw renders Markdown to HTML without handling special links.
42-
func RenderRaw(body []byte, urlPrefix string, wikiMarkdown bool) []byte {
43+
// render renders Markdown to HTML without handling special links.
44+
func render(body []byte, urlPrefix string, metas map[string]string, wikiMarkdown bool) []byte {
4345
once.Do(func() {
4446
converter = goldmark.New(
4547
goldmark.WithExtensions(extension.Table,
@@ -75,12 +77,9 @@ func RenderRaw(body []byte, urlPrefix string, wikiMarkdown bool) []byte {
7577
),
7678
)
7779

78-
if setting.Markdown.EnableHardLineBreak {
79-
converter.Renderer().AddOptions(html.WithHardWraps())
80-
}
8180
})
8281

83-
pc := NewGiteaParseContext(urlPrefix, wikiMarkdown)
82+
pc := NewGiteaParseContext(urlPrefix, metas, wikiMarkdown)
8483
var buf bytes.Buffer
8584
if err := converter.Convert(giteautil.NormalizeEOL(body), &buf, parser.WithContext(pc)); err != nil {
8685
log.Error("Unable to render: %v", err)
@@ -112,14 +111,19 @@ func (Parser) Extensions() []string {
112111

113112
// Render implements markup.Parser
114113
func (Parser) Render(rawBytes []byte, urlPrefix string, metas map[string]string, isWiki bool) []byte {
115-
return RenderRaw(rawBytes, urlPrefix, isWiki)
114+
return render(rawBytes, urlPrefix, metas, isWiki)
116115
}
117116

118117
// Render renders Markdown to HTML with all specific handling stuff.
119118
func Render(rawBytes []byte, urlPrefix string, metas map[string]string) []byte {
120119
return markup.Render("a.md", rawBytes, urlPrefix, metas)
121120
}
122121

122+
// RenderRaw renders Markdown to HTML without handling special links.
123+
func RenderRaw(body []byte, urlPrefix string, wikiMarkdown bool) []byte {
124+
return render(body, urlPrefix, map[string]string{}, wikiMarkdown)
125+
}
126+
123127
// RenderString renders Markdown to HTML with special links and returns string type.
124128
func RenderString(raw, urlPrefix string, metas map[string]string) string {
125129
return markup.RenderString("a.md", raw, urlPrefix, metas)

‎modules/setting/setting.go

+7-5
Original file line numberDiff line numberDiff line change
@@ -256,12 +256,14 @@ var (
256256

257257
// Markdown settings
258258
Markdown = struct {
259-
EnableHardLineBreak bool
260-
CustomURLSchemes []string `ini:"CUSTOM_URL_SCHEMES"`
261-
FileExtensions []string
259+
EnableHardLineBreakInComments bool
260+
EnableHardLineBreakInDocuments bool
261+
CustomURLSchemes []string `ini:"CUSTOM_URL_SCHEMES"`
262+
FileExtensions []string
262263
}{
263-
EnableHardLineBreak: true,
264-
FileExtensions: strings.Split(".md,.markdown,.mdown,.mkd", ","),
264+
EnableHardLineBreakInComments: true,
265+
EnableHardLineBreakInDocuments: false,
266+
FileExtensions: strings.Split(".md,.markdown,.mdown,.mkd", ","),
265267
}
266268

267269
// Admin settings

‎routers/api/v1/misc/markdown.go

+12-2
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,12 @@ func Markdown(ctx *context.APIContext, form api.MarkdownOption) {
4848
}
4949

5050
switch form.Mode {
51+
case "comment":
52+
fallthrough
5153
case "gfm":
5254
md := []byte(form.Text)
5355
urlPrefix := form.Context
54-
var meta map[string]string
56+
meta := map[string]string{}
5557
if !strings.HasPrefix(setting.AppSubURL+"/", urlPrefix) {
5658
// check if urlPrefix is already set to a URL
5759
linkRegex, _ := xurls.StrictMatchingScheme("https?://")
@@ -61,7 +63,15 @@ func Markdown(ctx *context.APIContext, form api.MarkdownOption) {
6163
}
6264
}
6365
if ctx.Repo != nil && ctx.Repo.Repository != nil {
64-
meta = ctx.Repo.Repository.ComposeMetas()
66+
// "gfm" = Github Flavored Markdown - set this to render as a document
67+
if form.Mode == "gfm" {
68+
meta = ctx.Repo.Repository.ComposeDocumentMetas()
69+
} else {
70+
meta = ctx.Repo.Repository.ComposeMetas()
71+
}
72+
}
73+
if form.Mode == "gfm" {
74+
meta["mode"] = "document"
6575
}
6676
if form.Wiki {
6777
_, err := ctx.Write([]byte(markdown.RenderWiki(md, urlPrefix, meta)))

‎routers/api/v1/misc/markdown_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ Here are some links to the most important topics. You can find the full list of
9494
<p><strong>Wine Staging</strong> on website <a href="http://wine-staging.com" rel="nofollow">wine-staging.com</a>.</p>
9595
<h2 id="user-content-quick-links">Quick Links</h2>
9696
<p>Here are some links to the most important topics. You can find the full list of pages at the sidebar.</p>
97-
<p><a href="` + AppSubURL + `wiki/Configuration" rel="nofollow">Configuration</a><br/>
97+
<p><a href="` + AppSubURL + `wiki/Configuration" rel="nofollow">Configuration</a>
9898
<a href="` + AppSubURL + `wiki/raw/images/icon-bug.png" rel="nofollow"><img src="` + AppSubURL + `wiki/raw/images/icon-bug.png" title="icon-bug.png" alt="images/icon-bug.png"/></a></p>
9999
`,
100100
// Guard wiki sidebar: special syntax

‎routers/repo/view.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
319319
if markupType := markup.Type(readmeFile.name); markupType != "" {
320320
ctx.Data["IsMarkup"] = true
321321
ctx.Data["MarkupType"] = string(markupType)
322-
ctx.Data["FileContent"] = string(markup.Render(readmeFile.name, buf, readmeTreelink, ctx.Repo.Repository.ComposeMetas()))
322+
ctx.Data["FileContent"] = string(markup.Render(readmeFile.name, buf, readmeTreelink, ctx.Repo.Repository.ComposeDocumentMetas()))
323323
} else {
324324
ctx.Data["IsRenderedHTML"] = true
325325
ctx.Data["FileContent"] = strings.Replace(
@@ -459,7 +459,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
459459
if markupType := markup.Type(blob.Name()); markupType != "" {
460460
ctx.Data["IsMarkup"] = true
461461
ctx.Data["MarkupType"] = markupType
462-
ctx.Data["FileContent"] = string(markup.Render(blob.Name(), buf, path.Dir(treeLink), ctx.Repo.Repository.ComposeMetas()))
462+
ctx.Data["FileContent"] = string(markup.Render(blob.Name(), buf, path.Dir(treeLink), ctx.Repo.Repository.ComposeDocumentMetas()))
463463
} else if readmeExist {
464464
ctx.Data["IsRenderedHTML"] = true
465465
ctx.Data["FileContent"] = strings.Replace(
@@ -538,7 +538,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
538538
buf = append(buf, d...)
539539
ctx.Data["IsMarkup"] = true
540540
ctx.Data["MarkupType"] = markupType
541-
ctx.Data["FileContent"] = string(markup.Render(blob.Name(), buf, path.Dir(treeLink), ctx.Repo.Repository.ComposeMetas()))
541+
ctx.Data["FileContent"] = string(markup.Render(blob.Name(), buf, path.Dir(treeLink), ctx.Repo.Repository.ComposeDocumentMetas()))
542542
}
543543

544544
}

‎routers/repo/wiki.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
209209
return nil, nil
210210
}
211211

212-
metas := ctx.Repo.Repository.ComposeMetas()
212+
metas := ctx.Repo.Repository.ComposeDocumentMetas()
213213
ctx.Data["content"] = markdown.RenderWiki(data, ctx.Repo.RepoLink, metas)
214214
ctx.Data["sidebarPresent"] = sidebarContent != nil
215215
ctx.Data["sidebarContent"] = markdown.RenderWiki(sidebarContent, ctx.Repo.RepoLink, metas)

‎templates/repo/editor/edit.tmpl

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
<div class="ui top attached tabular menu" data-write="write" data-preview="preview" data-diff="diff">
3131
<a class="active item" data-tab="write">{{svg "octicon-code" 16}} {{if .IsNewFile}}{{.i18n.Tr "repo.editor.new_file"}}{{else}}{{.i18n.Tr "repo.editor.edit_file"}}{{end}}</a>
3232
{{if not .IsNewFile}}
33-
<a class="item" data-tab="preview" data-url="{{.Repository.APIURL}}/markdown" data-context="{{.RepoLink}}/src/{{.BranchNameSubURL | EscapePound}}" data-preview-file-modes="{{.PreviewableFileModes}}">{{svg "octicon-eye" 16}} {{.i18n.Tr "preview"}}</a>
33+
<a class="item" data-tab="preview" data-url="{{.Repository.APIURL}}/markdown" data-context="{{.RepoLink}}/src/{{.BranchNameSubURL | EscapePound}}" data-preview-file-modes="{{.PreviewableFileModes}}" data-markdown-mode="gfm">{{svg "octicon-eye" 16}} {{.i18n.Tr "preview"}}</a>
3434
<a class="item" data-tab="diff" data-url="{{.RepoLink}}/_preview/{{.BranchName | EscapePound}}/{{.TreePath | EscapePound}}" data-context="{{.BranchLink}}">{{svg "octicon-diff" 16}} {{.i18n.Tr "repo.editor.preview_changes"}}</a>
3535
{{end}}
3636
</div>

‎web_src/js/index.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ function initCommentPreviewTab($form) {
4141
const $this = $(this);
4242
$.post($this.data('url'), {
4343
_csrf: csrf,
44-
mode: 'gfm',
44+
mode: 'comment',
4545
context: $this.data('context'),
4646
text: $form.find(`.tab[data-tab="${$tabMenu.data('write')}"] textarea`).val()
4747
}, (data) => {
@@ -65,14 +65,15 @@ function initEditPreviewTab($form) {
6565
$previewTab.on('click', function () {
6666
const $this = $(this);
6767
let context = `${$this.data('context')}/`;
68+
const mode = $this.data('markdown-mode') || 'comment';
6869
const treePathEl = $form.find('input#tree_path');
6970
if (treePathEl.length > 0) {
7071
context += treePathEl.val();
7172
}
7273
context = context.substring(0, context.lastIndexOf('/'));
7374
$.post($this.data('url'), {
7475
_csrf: csrf,
75-
mode: 'gfm',
76+
mode,
7677
context,
7778
text: $form.find(`.tab[data-tab="${$tabMenu.data('write')}"] textarea`).val()
7879
}, (data) => {

0 commit comments

Comments
 (0)
Please sign in to comment.