Remove sourceRelativeLinks

Fixes #3766
This commit is contained in:
Bjørn Erik Pedersen 2017-08-02 21:37:03 +02:00
parent 481924b34d
commit 9891c0fb0e
6 changed files with 22 additions and 329 deletions

View file

@ -71,8 +71,6 @@ type Blackfriday struct {
LatexDashes bool LatexDashes bool
TaskLists bool TaskLists bool
PlainIDAnchors bool PlainIDAnchors bool
SourceRelativeLinksEval bool
SourceRelativeLinksProjectFolder string
Extensions []string Extensions []string
ExtensionsMask []string ExtensionsMask []string
} }
@ -89,8 +87,6 @@ func (c ContentSpec) NewBlackfriday() *Blackfriday {
"latexDashes": true, "latexDashes": true,
"plainIDAnchors": true, "plainIDAnchors": true,
"taskLists": true, "taskLists": true,
"sourceRelativeLinks": false,
"sourceRelativeLinksProjectFolder": "/docs/content",
} }
ToLowerMap(defaultParam) ToLowerMap(defaultParam)
@ -112,13 +108,6 @@ func (c ContentSpec) NewBlackfriday() *Blackfriday {
jww.FATAL.Printf("Failed to get site rendering config\n%s", err.Error()) jww.FATAL.Printf("Failed to get site rendering config\n%s", err.Error())
} }
if combinedConfig.SourceRelativeLinksEval {
// Remove in Hugo 0.21
Deprecated("blackfriday", "sourceRelativeLinksEval",
`There is no replacement for this feature, as no developer has stepped up to the plate and volunteered to maintain this feature`, false)
}
return combinedConfig return combinedConfig
} }
@ -412,8 +401,6 @@ type RenderingContext struct {
DocumentName string DocumentName string
Config *Blackfriday Config *Blackfriday
RenderTOC bool RenderTOC bool
FileResolver FileResolverFunc
LinkResolver LinkResolverFunc
Cfg config.Provider Cfg config.Provider
} }

View file

@ -20,7 +20,6 @@ import (
"github.com/gohugoio/hugo/config" "github.com/gohugoio/hugo/config"
"github.com/miekg/mmark" "github.com/miekg/mmark"
"github.com/russross/blackfriday" "github.com/russross/blackfriday"
jww "github.com/spf13/jwalterweatherman"
) )
type LinkResolverFunc func(ref string) (string, error) type LinkResolverFunc func(ref string) (string, error)
@ -43,35 +42,6 @@ func (r *HugoHTMLRenderer) BlockCode(out *bytes.Buffer, text []byte, lang string
} }
} }
func (r *HugoHTMLRenderer) Link(out *bytes.Buffer, link []byte, title []byte, content []byte) {
if r.LinkResolver == nil || bytes.HasPrefix(link, []byte("HAHAHUGOSHORTCODE")) {
// Use the blackfriday built in Link handler
r.Renderer.Link(out, link, title, content)
} else {
// set by SourceRelativeLinksEval
newLink, err := r.LinkResolver(string(link))
if err != nil {
newLink = string(link)
jww.ERROR.Printf("LinkResolver: %s", err)
}
r.Renderer.Link(out, []byte(newLink), title, content)
}
}
func (r *HugoHTMLRenderer) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) {
if r.FileResolver == nil || bytes.HasPrefix(link, []byte("HAHAHUGOSHORTCODE")) {
// Use the blackfriday built in Image handler
r.Renderer.Image(out, link, title, alt)
} else {
// set by SourceRelativeLinksEval
newLink, err := r.FileResolver(string(link))
if err != nil {
newLink = string(link)
jww.ERROR.Printf("FileResolver: %s", err)
}
r.Renderer.Image(out, []byte(newLink), title, alt)
}
}
// ListItem adds task list support to the Blackfriday renderer. // ListItem adds task list support to the Blackfriday renderer.
func (r *HugoHTMLRenderer) ListItem(out *bytes.Buffer, text []byte, flags int) { func (r *HugoHTMLRenderer) ListItem(out *bytes.Buffer, text []byte, flags int) {
if !r.Config.TaskLists { if !r.Config.TaskLists {

View file

@ -188,7 +188,6 @@ func TestGetHTMLRendererAllFlags(t *testing.T) {
ctx.Config.SmartDashes = true ctx.Config.SmartDashes = true
ctx.Config.Smartypants = true ctx.Config.Smartypants = true
ctx.Config.SmartypantsQuotesNBSP = true ctx.Config.SmartypantsQuotesNBSP = true
ctx.Config.SourceRelativeLinksEval = true
renderer := c.getHTMLRenderer(defaultFlags, ctx) renderer := c.getHTMLRenderer(defaultFlags, ctx)
actualFlags := renderer.GetFlags() actualFlags := renderer.GetFlags()
var expectedFlags int var expectedFlags int

View file

@ -622,22 +622,11 @@ func (p *Page) setAutoSummary() error {
} }
func (p *Page) renderContent(content []byte) []byte { func (p *Page) renderContent(content []byte) []byte {
var fn helpers.LinkResolverFunc
var fileFn helpers.FileResolverFunc
if p.getRenderingConfig().SourceRelativeLinksEval {
fn = func(ref string) (string, error) {
return p.Site.SourceRelativeLink(ref, p)
}
fileFn = func(ref string) (string, error) {
return p.Site.SourceRelativeLinkFile(ref, p)
}
}
return p.s.ContentSpec.RenderBytes(&helpers.RenderingContext{ return p.s.ContentSpec.RenderBytes(&helpers.RenderingContext{
Content: content, RenderTOC: true, PageFmt: p.determineMarkupType(), Content: content, RenderTOC: true, PageFmt: p.determineMarkupType(),
Cfg: p.Language(), Cfg: p.Language(),
DocumentID: p.UniqueID(), DocumentName: p.Path(), DocumentID: p.UniqueID(), DocumentName: p.Path(),
Config: p.getRenderingConfig(), LinkResolver: fn, FileResolver: fileFn}) Config: p.getRenderingConfig()})
} }
func (p *Page) getRenderingConfig() *helpers.Blackfriday { func (p *Page) getRenderingConfig() *helpers.Blackfriday {

View file

@ -493,126 +493,6 @@ func (s *SiteInfo) RelRef(ref string, page *Page, options ...string) (string, er
return s.refLink(ref, page, true, outputFormat) return s.refLink(ref, page, true, outputFormat)
} }
// SourceRelativeLink attempts to convert any source page relative links (like [../another.md]) into absolute links
func (s *SiteInfo) SourceRelativeLink(ref string, currentPage *Page) (string, error) {
var refURL *url.URL
var err error
refURL, err = url.Parse(strings.TrimPrefix(ref, currentPage.getRenderingConfig().SourceRelativeLinksProjectFolder))
if err != nil {
return "", err
}
if refURL.Scheme != "" {
// Not a relative source level path
return ref, nil
}
var target *Page
var link string
if refURL.Path != "" {
refPath := filepath.Clean(filepath.FromSlash(refURL.Path))
if strings.IndexRune(refPath, os.PathSeparator) == 0 { // filepath.IsAbs fails to me.
refPath = refPath[1:]
} else {
if currentPage != nil {
refPath = filepath.Join(currentPage.Source.Dir(), refURL.Path)
}
}
for _, page := range s.AllRegularPages {
if page.Source.Path() == refPath {
target = page
break
}
}
// need to exhaust the test, then try with the others :/
// if the refPath doesn't end in a filename with extension `.md`, then try with `.md` , and then `/index.md`
mdPath := strings.TrimSuffix(refPath, string(os.PathSeparator)) + ".md"
for _, page := range s.AllRegularPages {
if page.Source.Path() == mdPath {
target = page
break
}
}
indexPath := filepath.Join(refPath, "index.md")
for _, page := range s.AllRegularPages {
if page.Source.Path() == indexPath {
target = page
break
}
}
if target == nil {
return "", fmt.Errorf("No page found for \"%s\" on page \"%s\".\n", ref, currentPage.Source.Path())
}
link = target.RelPermalink()
}
if refURL.Fragment != "" {
link = link + "#" + refURL.Fragment
if refURL.Path != "" && target != nil && !target.getRenderingConfig().PlainIDAnchors {
link = link + ":" + target.UniqueID()
} else if currentPage != nil && !currentPage.getRenderingConfig().PlainIDAnchors {
link = link + ":" + currentPage.UniqueID()
}
}
return link, nil
}
// SourceRelativeLinkFile attempts to convert any non-md source relative links (like [../another.gif]) into absolute links
func (s *SiteInfo) SourceRelativeLinkFile(ref string, currentPage *Page) (string, error) {
var refURL *url.URL
var err error
refURL, err = url.Parse(strings.TrimPrefix(ref, currentPage.getRenderingConfig().SourceRelativeLinksProjectFolder))
if err != nil {
return "", err
}
if refURL.Scheme != "" {
// Not a relative source level path
return ref, nil
}
var target *source.File
var link string
if refURL.Path != "" {
refPath := filepath.Clean(filepath.FromSlash(refURL.Path))
if strings.IndexRune(refPath, os.PathSeparator) == 0 { // filepath.IsAbs fails to me.
refPath = refPath[1:]
} else {
if currentPage != nil {
refPath = filepath.Join(currentPage.Source.Dir(), refURL.Path)
}
}
for _, file := range *s.Files {
if file.Path() == refPath {
target = file
break
}
}
if target == nil {
return "", fmt.Errorf("No file found for \"%s\" on page \"%s\".\n", ref, currentPage.Source.Path())
}
link = target.Path()
return "/" + filepath.ToSlash(link), nil
}
return "", fmt.Errorf("failed to find a file to match \"%s\" on page \"%s\"", ref, currentPage.Source.Path())
}
func (s *SiteInfo) addToPaginationPageCount(cnt uint64) { func (s *SiteInfo) addToPaginationPageCount(cnt uint64) {
atomic.AddUint64(&s.paginationPageCount, cnt) atomic.AddUint64(&s.paginationPageCount, cnt)
} }

View file

@ -938,8 +938,7 @@ func setupLinkingMockSite(t *testing.T) *Site {
cfg.Set("pluralizeListTitles", false) cfg.Set("pluralizeListTitles", false)
cfg.Set("canonifyURLs", false) cfg.Set("canonifyURLs", false)
cfg.Set("blackfriday", cfg.Set("blackfriday",
map[string]interface{}{ map[string]interface{}{})
"sourceRelativeLinksProjectFolder": "/docs"})
writeSourcesToSource(t, "content", fs, sources...) writeSourcesToSource(t, "content", fs, sources...)
return buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{}) return buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{})
@ -973,134 +972,3 @@ func TestRefLinking(t *testing.T) {
// TODO: and then the failure cases. // TODO: and then the failure cases.
} }
func TestSourceRelativeLinksing(t *testing.T) {
t.Parallel()
site := setupLinkingMockSite(t)
type resultMap map[string]string
okresults := map[string]resultMap{
"index.md": map[string]string{
"/docs/rootfile.md": "/rootfile/",
"rootfile.md": "/rootfile/",
// See #3396 -- this may potentially be ambiguous (i.e. name conflict with home page).
// But the user have chosen so. This index.md patterns is more relevant in /sub-folders.
"index.md": "/",
"level2/2-root.md": "/level2/2-root/",
"/docs/level2/2-root.md": "/level2/2-root/",
"level2/level3/3-root.md": "/level2/level3/3-root/",
"/docs/level2/level3/3-root.md": "/level2/level3/3-root/",
"/docs/level2/2-root/": "/level2/2-root/",
"/docs/level2/2-root": "/level2/2-root/",
"/level2/2-root/": "/level2/2-root/",
"/level2/2-root": "/level2/2-root/",
}, "rootfile.md": map[string]string{
"/docs/rootfile.md": "/rootfile/",
"rootfile.md": "/rootfile/",
"level2/2-root.md": "/level2/2-root/",
"/docs/level2/2-root.md": "/level2/2-root/",
"level2/level3/3-root.md": "/level2/level3/3-root/",
"/docs/level2/level3/3-root.md": "/level2/level3/3-root/",
}, "level2/2-root.md": map[string]string{
"../rootfile.md": "/rootfile/",
"/docs/rootfile.md": "/rootfile/",
"2-root.md": "/level2/2-root/",
"../level2/2-root.md": "/level2/2-root/",
"./2-root.md": "/level2/2-root/",
"/docs/level2/2-root.md": "/level2/2-root/",
"level3/3-root.md": "/level2/level3/3-root/",
"../level2/level3/3-root.md": "/level2/level3/3-root/",
"/docs/level2/level3/3-root.md": "/level2/level3/3-root/",
}, "level2/index.md": map[string]string{
"../rootfile.md": "/rootfile/",
"/docs/rootfile.md": "/rootfile/",
"2-root.md": "/level2/2-root/",
"../level2/2-root.md": "/level2/2-root/",
"./2-root.md": "/level2/2-root/",
"/docs/level2/2-root.md": "/level2/2-root/",
"level3/3-root.md": "/level2/level3/3-root/",
"../level2/level3/3-root.md": "/level2/level3/3-root/",
"/docs/level2/level3/3-root.md": "/level2/level3/3-root/",
}, "level2/level3/3-root.md": map[string]string{
"../../rootfile.md": "/rootfile/",
"/docs/rootfile.md": "/rootfile/",
"../2-root.md": "/level2/2-root/",
"/docs/level2/2-root.md": "/level2/2-root/",
"3-root.md": "/level2/level3/3-root/",
"./3-root.md": "/level2/level3/3-root/",
"/docs/level2/level3/3-root.md": "/level2/level3/3-root/",
}, "level2/level3/index.md": map[string]string{
"../../rootfile.md": "/rootfile/",
"/docs/rootfile.md": "/rootfile/",
"../2-root.md": "/level2/2-root/",
"/docs/level2/2-root.md": "/level2/2-root/",
"3-root.md": "/level2/level3/3-root/",
"./3-root.md": "/level2/level3/3-root/",
"/docs/level2/level3/3-root.md": "/level2/level3/3-root/",
},
}
for currentFile, results := range okresults {
currentPage := findPage(site, currentFile)
if currentPage == nil {
t.Fatalf("failed to find current page in site")
}
for link, url := range results {
if out, err := site.Info.SourceRelativeLink(link, currentPage); err != nil || out != url {
t.Errorf("Expected %s to resolve to (%s), got (%s) - error: %s", link, url, out, err)
} else {
//t.Logf("tested ok %s maps to %s", link, out)
}
}
}
// TODO: and then the failure cases.
// "https://docker.com": "",
// site_test.go:1094: Expected https://docker.com to resolve to (), got () - error: Not a plain filepath link (https://docker.com)
}
func TestSourceRelativeLinkFileing(t *testing.T) {
t.Parallel()
site := setupLinkingMockSite(t)
type resultMap map[string]string
okresults := map[string]resultMap{
"index.md": map[string]string{
"/root-image.png": "/root-image.png",
"root-image.png": "/root-image.png",
}, "rootfile.md": map[string]string{
"/root-image.png": "/root-image.png",
}, "level2/2-root.md": map[string]string{
"/root-image.png": "/root-image.png",
"common.png": "/level2/common.png",
}, "level2/index.md": map[string]string{
"/root-image.png": "/root-image.png",
"common.png": "/level2/common.png",
"./common.png": "/level2/common.png",
}, "level2/level3/3-root.md": map[string]string{
"/root-image.png": "/root-image.png",
"common.png": "/level2/level3/common.png",
"../common.png": "/level2/common.png",
}, "level2/level3/index.md": map[string]string{
"/root-image.png": "/root-image.png",
"common.png": "/level2/level3/common.png",
"../common.png": "/level2/common.png",
},
}
for currentFile, results := range okresults {
currentPage := findPage(site, currentFile)
if currentPage == nil {
t.Fatalf("failed to find current page in site")
}
for link, url := range results {
if out, err := site.Info.SourceRelativeLinkFile(link, currentPage); err != nil || out != url {
t.Errorf("Expected %s to resolve to (%s), got (%s) - error: %s", link, url, out, err)
} else {
//t.Logf("tested ok %s maps to %s", link, out)
}
}
}
}