Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow different HardBreaks settings for documents and comments (#11515) #11599

Merged
merged 1 commit into from
May 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 [email protected]

Changes to index.js as per @silverwind 
Co-authored-by: silverwind <[email protected]>

Changes to docs as per @guillep2k 
Co-authored-by: guillep2k <[email protected]>
  • Loading branch information
3 people committed May 24, 2020
commit e17a7dd5d942426065b781f576af220df233e0a6
5 changes: 4 additions & 1 deletion custom/conf/app.ini.sample
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,10 @@ EVENT_SOURCE_UPDATE_TIME = 10s
; Render soft line breaks as hard line breaks, which means a single newline character between
; paragraphs will cause a line break and adding trailing whitespace to paragraphs is not
; necessary to force a line break.
ENABLE_HARD_LINE_BREAK = true
; Render soft line breaks as hard line breaks for comments
ENABLE_HARD_LINE_BREAK_IN_COMMENTS = true
; Render soft line breaks as hard line breaks for markdown documents
ENABLE_HARD_LINE_BREAK_IN_DOCUMENTS = false
; Comma separated list of custom URL-Schemes that are allowed as links when rendering Markdown
; for example git,magnet,ftp (more at https://en.wikipedia.org/wiki/List_of_URI_schemes)
; URLs starting with http and https are always displayed, whatever is put in this entry.
Expand Down
5 changes: 4 additions & 1 deletion docs/content/doc/advanced/config-cheat-sheet.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,10 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.

## Markdown (`markdown`)

- `ENABLE_HARD_LINE_BREAK`: **true**: Render soft line breaks as hard line breaks, which
- `ENABLE_HARD_LINE_BREAK_IN_COMMENTS`: **true**: Render soft line breaks as hard line breaks in comments, which
means a single newline character between paragraphs will cause a line break and adding
trailing whitespace to paragraphs is not necessary to force a line break.
- `ENABLE_HARD_LINE_BREAK_IN_DOCUMENTS`: **false**: Render soft line breaks as hard line breaks in documents, which
means a single newline character between paragraphs will cause a line break and adding
trailing whitespace to paragraphs is not necessary to force a line break.
- `CUSTOM_URL_SCHEMES`: Use a comma separated list (ftp,git,svn) to indicate additional
Expand Down
23 changes: 19 additions & 4 deletions models/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,10 @@ type Repository struct {
*Mirror `xorm:"-"`
Status RepositoryStatus `xorm:"NOT NULL DEFAULT 0"`

RenderingMetas map[string]string `xorm:"-"`
Units []*RepoUnit `xorm:"-"`
PrimaryLanguage *LanguageStat `xorm:"-"`
RenderingMetas map[string]string `xorm:"-"`
DocumentRenderingMetas map[string]string `xorm:"-"`
Units []*RepoUnit `xorm:"-"`
PrimaryLanguage *LanguageStat `xorm:"-"`

IsFork bool `xorm:"INDEX NOT NULL DEFAULT false"`
ForkID int64 `xorm:"INDEX"`
Expand Down Expand Up @@ -534,11 +535,12 @@ func (repo *Repository) mustOwner(e Engine) *User {

// ComposeMetas composes a map of metas for properly rendering issue links and external issue trackers.
func (repo *Repository) ComposeMetas() map[string]string {
if repo.RenderingMetas == nil {
if len(repo.RenderingMetas) == 0 {
metas := map[string]string{
"user": repo.OwnerName,
"repo": repo.Name,
"repoPath": repo.RepoPath(),
"mode": "comment",
}

unit, err := repo.GetUnit(UnitTypeExternalTracker)
Expand Down Expand Up @@ -570,6 +572,19 @@ func (repo *Repository) ComposeMetas() map[string]string {
return repo.RenderingMetas
}

// ComposeDocumentMetas composes a map of metas for properly rendering documents
func (repo *Repository) ComposeDocumentMetas() map[string]string {
if len(repo.DocumentRenderingMetas) == 0 {
metas := map[string]string{}
for k, v := range repo.ComposeMetas() {
metas[k] = v
}
metas["mode"] = "document"
repo.DocumentRenderingMetas = metas
}
return repo.DocumentRenderingMetas
}

// DeleteWiki removes the actual and local copy of repository wiki.
func (repo *Repository) DeleteWiki() error {
return repo.deleteWiki(x)
Expand Down
10 changes: 10 additions & 0 deletions modules/markup/markdown/goldmark.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,16 @@ func (g *ASTTransformer) Transform(node *ast.Document, reader text.Reader, pc pa
v.AppendChild(v, newChild)
}
}
case *ast.Text:
if v.SoftLineBreak() && !v.HardLineBreak() {
renderMetas := pc.Get(renderMetasKey).(map[string]string)
mode := renderMetas["mode"]
if mode != "document" {
v.SetHardLineBreak(setting.Markdown.EnableHardLineBreakInComments)
} else {
v.SetHardLineBreak(setting.Markdown.EnableHardLineBreakInDocuments)
}
}
}
return ast.WalkContinue, nil
})
Expand Down
20 changes: 12 additions & 8 deletions modules/markup/markdown/markdown.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,19 @@ var once = sync.Once{}

var urlPrefixKey = parser.NewContextKey()
var isWikiKey = parser.NewContextKey()
var renderMetasKey = parser.NewContextKey()

// NewGiteaParseContext creates a parser.Context with the gitea context set
func NewGiteaParseContext(urlPrefix string, isWiki bool) parser.Context {
func NewGiteaParseContext(urlPrefix string, metas map[string]string, isWiki bool) parser.Context {
pc := parser.NewContext(parser.WithIDs(newPrefixedIDs()))
pc.Set(urlPrefixKey, urlPrefix)
pc.Set(isWikiKey, isWiki)
pc.Set(renderMetasKey, metas)
return pc
}

// RenderRaw renders Markdown to HTML without handling special links.
func RenderRaw(body []byte, urlPrefix string, wikiMarkdown bool) []byte {
// render renders Markdown to HTML without handling special links.
func render(body []byte, urlPrefix string, metas map[string]string, wikiMarkdown bool) []byte {
once.Do(func() {
converter = goldmark.New(
goldmark.WithExtensions(extension.Table,
Expand Down Expand Up @@ -75,12 +77,9 @@ func RenderRaw(body []byte, urlPrefix string, wikiMarkdown bool) []byte {
),
)

if setting.Markdown.EnableHardLineBreak {
converter.Renderer().AddOptions(html.WithHardWraps())
}
})

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

// Render implements markup.Parser
func (Parser) Render(rawBytes []byte, urlPrefix string, metas map[string]string, isWiki bool) []byte {
return RenderRaw(rawBytes, urlPrefix, isWiki)
return render(rawBytes, urlPrefix, metas, isWiki)
}

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

// RenderRaw renders Markdown to HTML without handling special links.
func RenderRaw(body []byte, urlPrefix string, wikiMarkdown bool) []byte {
return render(body, urlPrefix, map[string]string{}, wikiMarkdown)
}

// RenderString renders Markdown to HTML with special links and returns string type.
func RenderString(raw, urlPrefix string, metas map[string]string) string {
return markup.RenderString("a.md", raw, urlPrefix, metas)
Expand Down
12 changes: 7 additions & 5 deletions modules/setting/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,12 +256,14 @@ var (

// Markdown settings
Markdown = struct {
EnableHardLineBreak bool
CustomURLSchemes []string `ini:"CUSTOM_URL_SCHEMES"`
FileExtensions []string
EnableHardLineBreakInComments bool
EnableHardLineBreakInDocuments bool
CustomURLSchemes []string `ini:"CUSTOM_URL_SCHEMES"`
FileExtensions []string
}{
EnableHardLineBreak: true,
FileExtensions: strings.Split(".md,.markdown,.mdown,.mkd", ","),
EnableHardLineBreakInComments: true,
EnableHardLineBreakInDocuments: false,
FileExtensions: strings.Split(".md,.markdown,.mdown,.mkd", ","),
}

// Admin settings
Expand Down
14 changes: 12 additions & 2 deletions routers/api/v1/misc/markdown.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,12 @@ func Markdown(ctx *context.APIContext, form api.MarkdownOption) {
}

switch form.Mode {
case "comment":
fallthrough
case "gfm":
md := []byte(form.Text)
urlPrefix := form.Context
var meta map[string]string
meta := map[string]string{}
if !strings.HasPrefix(setting.AppSubURL+"/", urlPrefix) {
// check if urlPrefix is already set to a URL
linkRegex, _ := xurls.StrictMatchingScheme("https?:https://")
Expand All @@ -61,7 +63,15 @@ func Markdown(ctx *context.APIContext, form api.MarkdownOption) {
}
}
if ctx.Repo != nil && ctx.Repo.Repository != nil {
meta = ctx.Repo.Repository.ComposeMetas()
// "gfm" = Github Flavored Markdown - set this to render as a document
if form.Mode == "gfm" {
meta = ctx.Repo.Repository.ComposeDocumentMetas()
} else {
meta = ctx.Repo.Repository.ComposeMetas()
}
}
if form.Mode == "gfm" {
meta["mode"] = "document"
}
if form.Wiki {
_, err := ctx.Write([]byte(markdown.RenderWiki(md, urlPrefix, meta)))
Expand Down
2 changes: 1 addition & 1 deletion routers/api/v1/misc/markdown_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ Here are some links to the most important topics. You can find the full list of
<p><strong>Wine Staging</strong> on website <a href="http:https://wine-staging.com" rel="">wine-staging.com</a>.</p>
<h2 id="user-content-quick-links">Quick Links</h2>
<p>Here are some links to the most important topics. You can find the full list of pages at the sidebar.</p>
<p><a href="` + AppSubURL + `wiki/Configuration" rel="">Configuration</a><br/>
<p><a href="` + AppSubURL + `wiki/Configuration" rel="">Configuration</a>
<a href="` + AppSubURL + `wiki/raw/images/icon-bug.png" rel=""><img src="` + AppSubURL + `wiki/raw/images/icon-bug.png" title="icon-bug.png" alt="images/icon-bug.png"/></a></p>
`,
// Guard wiki sidebar: special syntax
Expand Down
6 changes: 3 additions & 3 deletions routers/repo/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
if markupType := markup.Type(readmeFile.name); markupType != "" {
ctx.Data["IsMarkup"] = true
ctx.Data["MarkupType"] = string(markupType)
ctx.Data["FileContent"] = string(markup.Render(readmeFile.name, buf, readmeTreelink, ctx.Repo.Repository.ComposeMetas()))
ctx.Data["FileContent"] = string(markup.Render(readmeFile.name, buf, readmeTreelink, ctx.Repo.Repository.ComposeDocumentMetas()))
} else {
ctx.Data["IsRenderedHTML"] = true
ctx.Data["FileContent"] = strings.Replace(
Expand Down Expand Up @@ -459,7 +459,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
if markupType := markup.Type(blob.Name()); markupType != "" {
ctx.Data["IsMarkup"] = true
ctx.Data["MarkupType"] = markupType
ctx.Data["FileContent"] = string(markup.Render(blob.Name(), buf, path.Dir(treeLink), ctx.Repo.Repository.ComposeMetas()))
ctx.Data["FileContent"] = string(markup.Render(blob.Name(), buf, path.Dir(treeLink), ctx.Repo.Repository.ComposeDocumentMetas()))
} else if readmeExist {
ctx.Data["IsRenderedHTML"] = true
ctx.Data["FileContent"] = strings.Replace(
Expand Down Expand Up @@ -538,7 +538,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
buf = append(buf, d...)
ctx.Data["IsMarkup"] = true
ctx.Data["MarkupType"] = markupType
ctx.Data["FileContent"] = string(markup.Render(blob.Name(), buf, path.Dir(treeLink), ctx.Repo.Repository.ComposeMetas()))
ctx.Data["FileContent"] = string(markup.Render(blob.Name(), buf, path.Dir(treeLink), ctx.Repo.Repository.ComposeDocumentMetas()))
}

}
Expand Down
2 changes: 1 addition & 1 deletion routers/repo/wiki.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
return nil, nil
}

metas := ctx.Repo.Repository.ComposeMetas()
metas := ctx.Repo.Repository.ComposeDocumentMetas()
ctx.Data["content"] = markdown.RenderWiki(data, ctx.Repo.RepoLink, metas)
ctx.Data["sidebarPresent"] = sidebarContent != nil
ctx.Data["sidebarContent"] = markdown.RenderWiki(sidebarContent, ctx.Repo.RepoLink, metas)
Expand Down
2 changes: 1 addition & 1 deletion templates/repo/editor/edit.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
<div class="ui top attached tabular menu" data-write="write" data-preview="preview" data-diff="diff">
<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>
{{if not .IsNewFile}}
<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>
<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>
<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>
{{end}}
</div>
Expand Down
5 changes: 3 additions & 2 deletions web_src/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ function initCommentPreviewTab($form) {
const $this = $(this);
$.post($this.data('url'), {
_csrf: csrf,
mode: 'gfm',
mode: 'comment',
context: $this.data('context'),
text: $form.find(`.tab[data-tab="${$tabMenu.data('write')}"] textarea`).val()
}, (data) => {
Expand All @@ -66,14 +66,15 @@ function initEditPreviewTab($form) {
$previewTab.on('click', function () {
const $this = $(this);
let context = `${$this.data('context')}/`;
const mode = $this.data('markdown-mode') || 'comment';
const treePathEl = $form.find('input#tree_path');
if (treePathEl.length > 0) {
context += treePathEl.val();
}
context = context.substring(0, context.lastIndexOf('/'));
$.post($this.data('url'), {
_csrf: csrf,
mode: 'gfm',
mode,
context,
text: $form.find(`.tab[data-tab="${$tabMenu.data('write')}"] textarea`).val()
}, (data) => {
Expand Down