summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/content/overview/configuration.md32
-rw-r--r--helpers/content.go38
-rw-r--r--helpers/content_renderer.go2
-rw-r--r--hugolib/page.go8
-rw-r--r--hugolib/site.go53
-rw-r--r--hugolib/site_test.go27
6 files changed, 80 insertions, 80 deletions
diff --git a/docs/content/overview/configuration.md b/docs/content/overview/configuration.md
index e351c651a..9d721d4a0 100644
--- a/docs/content/overview/configuration.md
+++ b/docs/content/overview/configuration.md
@@ -289,6 +289,38 @@ Its behavior can be modified with the <code>latexDashes</code> flag listed below
<td class="purpose-description" colspan="2">Extensions in this option won't be loaded.<br>
<small><strong>Example:</strong>&nbsp;Add <code>"autoHeaderIds"</code> to disable <code>EXTENSION_AUTO_HEADER_IDS</code>.</small></td>
</tr>
+
+<tr>
+<td><code><strong>sourceRelativeLinksEval</strong></code></td>
+<td><code>false</code></td>
+<td><code>none</code></td>
+</tr>
+<tr>
+<td class="purpose-title">Purpose:</td>
+<td class="purpose-description" colspan="2">Source file based relative linking (a la Github).<br>
+Relative links to markdown and static files within a page will be evaluated relative to the
+location of that page, and then converted to html links during rendering. For example,
+`[example](../other/page.md)` in `content/total/overview.md` will be linked to
+`content/other/overview.md`, and then rendered to `/other/overview/` in the HTML output.
+</td>
+</tr>
+
+<tr>
+<td><code><strong>sourceRelativeLinksProjectFolder</strong></code></td>
+<td><code>"/docs/content"</code></td>
+<td><code>none</code></td>
+</tr>
+<tr>
+<td class="purpose-title">Purpose:</td>
+<td class="purpose-description" colspan="2">Source file based relative linking Hugo Project sub-folder.<br>
+When `sourceRelativeLinksEval` is enabled, source level paths may contain an absolute respository path to the
+markdown or static file which needs to be removed before trying to match it with the intended link.
+ For example, if your documentation is in `/docs/content`, then
+`[example](/docs/content/other/page.md)` in `/docs/content/total/overview.md` will be linked to
+`/docs/content/other/overview.md`, and then rendered to `/other/overview/` in the HTML output.
+</td>
+</tr>
+
</tbody>
</table>
diff --git a/helpers/content.go b/helpers/content.go
index c1353ae29..f60349055 100644
--- a/helpers/content.go
+++ b/helpers/content.go
@@ -43,29 +43,31 @@ var SummaryDivider = []byte("<!--more-->")
// Blackfriday holds configuration values for Blackfriday rendering.
type Blackfriday struct {
- Smartypants bool
- AngledQuotes bool
- Fractions bool
- HrefTargetBlank bool
- SmartDashes bool
- LatexDashes bool
- PlainIDAnchors bool
- SourceRelativeLinksEval bool
- Extensions []string
- ExtensionsMask []string
+ Smartypants bool
+ AngledQuotes bool
+ Fractions bool
+ HrefTargetBlank bool
+ SmartDashes bool
+ LatexDashes bool
+ PlainIDAnchors bool
+ SourceRelativeLinksEval bool
+ SourceRelativeLinksProjectFolder string
+ Extensions []string
+ ExtensionsMask []string
}
// NewBlackfriday creates a new Blackfriday filled with site config or some sane defaults.
func NewBlackfriday() *Blackfriday {
combinedParam := map[string]interface{}{
- "smartypants": true,
- "angledQuotes": false,
- "fractions": true,
- "hrefTargetBlank": false,
- "smartDashes": true,
- "latexDashes": true,
- "plainIDAnchors": false,
- "sourceRelativeLinks": false,
+ "smartypants": true,
+ "angledQuotes": false,
+ "fractions": true,
+ "hrefTargetBlank": false,
+ "smartDashes": true,
+ "latexDashes": true,
+ "plainIDAnchors": false,
+ "sourceRelativeLinks": false,
+ "sourceRelativeLinksProjectFolder": "/docs/content",
}
siteParam := viper.GetStringMap("blackfriday")
diff --git a/helpers/content_renderer.go b/helpers/content_renderer.go
index aedf0e1d0..18df9ebef 100644
--- a/helpers/content_renderer.go
+++ b/helpers/content_renderer.go
@@ -49,6 +49,7 @@ func (renderer *HugoHTMLRenderer) Link(out *bytes.Buffer, link []byte, title []b
// Use the blackfriday built in Link handler
renderer.Renderer.Link(out, link, title, content)
} else {
+ // set by SourceRelativeLinksEval
newLink, err := renderer.LinkResolver(string(link))
if err != nil {
newLink = string(link)
@@ -62,6 +63,7 @@ func (renderer *HugoHTMLRenderer) Image(out *bytes.Buffer, link []byte, title []
// Use the blackfriday built in Image handler
renderer.Renderer.Image(out, link, title, alt)
} else {
+ // set by SourceRelativeLinksEval
newLink, err := renderer.FileResolver(string(link))
if err != nil {
newLink = string(link)
diff --git a/hugolib/page.go b/hugolib/page.go
index 3d1b48738..2342e368f 100644
--- a/hugolib/page.go
+++ b/hugolib/page.go
@@ -257,10 +257,10 @@ func (p *Page) renderBytes(content []byte) []byte {
var fileFn helpers.FileResolverFunc
if p.getRenderingConfig().SourceRelativeLinksEval {
fn = func(ref string) (string, error) {
- return p.Node.Site.GitHub(ref, p)
+ return p.Node.Site.SourceRelativeLink(ref, p)
}
fileFn = func(ref string) (string, error) {
- return p.Node.Site.GitHubFileLink(ref, p)
+ return p.Node.Site.SourceRelativeLinkFile(ref, p)
}
}
return helpers.RenderBytes(
@@ -273,10 +273,10 @@ func (p *Page) renderContent(content []byte) []byte {
var fileFn helpers.FileResolverFunc
if p.getRenderingConfig().SourceRelativeLinksEval {
fn = func(ref string) (string, error) {
- return p.Node.Site.GitHub(ref, p)
+ return p.Node.Site.SourceRelativeLink(ref, p)
}
fileFn = func(ref string) (string, error) {
- return p.Node.Site.GitHubFileLink(ref, p)
+ return p.Node.Site.SourceRelativeLinkFile(ref, p)
}
}
return helpers.RenderBytesWithTOC(&helpers.RenderingContext{Content: content, PageFmt: p.guessMarkupType(),
diff --git a/hugolib/site.go b/hugolib/site.go
index ea9297b3d..0f488f7cb 100644
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -225,28 +225,18 @@ func (s *SiteInfo) RelRef(ref string, page *Page) (string, error) {
return s.refLink(ref, page, true)
}
-// TODO(sven): Document
-func (s *SiteInfo) GitHub(ref string, page *Page) (string, error) {
- return s.githubLink(ref, page, true)
-}
-
-func (s *SiteInfo) githubLink(ref string, currentPage *Page, relative bool) (string, error) {
+// 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
- // TODO can I make this a param to `hugo --use-github-links=/docs`?
- // SVEN: add more tests - the prefix might be a real dir inside tho - add some pages that have it as a legitimate path
- repositoryPathPrefix := "/docs"
-
- refURL, err = url.Parse(strings.TrimPrefix(ref, repositoryPathPrefix))
+ refURL, err = url.Parse(strings.TrimPrefix(ref, currentPage.getRenderingConfig().SourceRelativeLinksProjectFolder))
if err != nil {
return "", err
}
if refURL.Scheme != "" {
- // TODO: consider looking for http(s?)://github.com/user/project/prefix and replacing it - tho this may be intentional, so idk
- //return "", fmt.Errorf("Not a plain filepath link (%s)", ref)
- // Treat this as not an error, as the link is used as-is
+ // Not a relative source level path
return ref, nil
}
@@ -291,19 +281,13 @@ func (s *SiteInfo) githubLink(ref string, currentPage *Page, relative bool) (str
return "", fmt.Errorf("No page found for \"%s\" on page \"%s\".\n", ref, currentPage.Source.Path())
}
- // SVEN: look at filepath.Rel() it might help, got the rel/non-rel url's (dangerous tho)
- if relative {
- link, err = target.RelPermalink()
- } else {
- link, err = target.Permalink()
- }
+ link, err = target.RelPermalink()
if err != nil {
return "", err
}
}
- // SVEN: add tests for github style relative fragments
if refURL.Fragment != "" {
link = link + "#" + refURL.Fragment
@@ -317,29 +301,18 @@ func (s *SiteInfo) githubLink(ref string, currentPage *Page, relative bool) (str
return link, nil
}
-// TODO(sven): Document
-func (s *SiteInfo) GitHubFileLink(ref string, page *Page) (string, error) {
- return s.githubFileLink(ref, page, false)
-}
-
-// for non-pages in the site tree
-func (s *SiteInfo) githubFileLink(ref string, currentPage *Page, relative bool) (string, error) {
+// 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
- // TODO can I make this a param to `hugo --use-github-links=/docs`?
- // SVEN: add more tests - the prefix might be a real dir inside tho - add some pages that have it as a legitimate path
- repositoryPathPrefix := "/docs"
-
- refURL, err = url.Parse(strings.TrimPrefix(ref, repositoryPathPrefix))
+ refURL, err = url.Parse(strings.TrimPrefix(ref, currentPage.getRenderingConfig().SourceRelativeLinksProjectFolder))
if err != nil {
return "", err
}
if refURL.Scheme != "" {
- // TODO: consider looking for http(s?)://github.com/user/project/prefix and replacing it - tho this may be intentional, so idk
- //return "", fmt.Errorf("Not a plain filepath link (%s)", ref)
- // Treat this as not an error, as the link is used as-is
+ // Not a relative source level path
return ref, nil
}
@@ -369,13 +342,7 @@ func (s *SiteInfo) githubFileLink(ref string, currentPage *Page, relative bool)
}
link = target.Path()
- // SVEN: look at filepath.Rel() it might help, got the rel/non-rel url's (dangerous tho)
- // SVEN: reconsider the fact I hardcoded the `relative` bool in both github resolvers
- if relative {
- return "./" + filepath.ToSlash(link), nil
- } else {
- return "/" + filepath.ToSlash(link), nil
- }
+ return "/" + filepath.ToSlash(link), nil
}
return "", fmt.Errorf("failed to find a file to match \"%s\" on page \"%s\"", ref, currentPage.Source.Path())
diff --git a/hugolib/site_test.go b/hugolib/site_test.go
index ae3021624..dd52b6d26 100644
--- a/hugolib/site_test.go
+++ b/hugolib/site_test.go
@@ -1023,8 +1023,6 @@ func TestWeightedTaxonomies(t *testing.T) {
}
func findPage(site *Site, f string) *Page {
- // TODO: it seems that filepath.FromSlash results in page.Source.Path() returning windows backslash - which means refLinking's string compare is totally busted.
- // TODO: Not used for non-fragment linking (SVEN thinks this is a bug)
currentPath := source.NewFile(filepath.FromSlash(f))
//t.Logf("looking for currentPath: %s", currentPath.Path())
@@ -1062,6 +1060,15 @@ func setupLinkingMockSite(t *testing.T) *Site {
{filepath.FromSlash("level2/level3/common.png"), []byte("")},
}
+ viper.Set("baseurl", "http://auth/")
+ viper.Set("DefaultExtension", "html")
+ viper.Set("UglyURLs", false)
+ viper.Set("PluralizeListTitles", false)
+ viper.Set("CanonifyURLs", false)
+ viper.Set("blackfriday",
+ map[string]interface{}{
+ "sourceRelativeLinksProjectFolder": "/docs"})
+
site := &Site{
Source: &source.InMemorySource{ByteSource: sources},
}
@@ -1072,12 +1079,6 @@ func setupLinkingMockSite(t *testing.T) *Site {
t.Fatalf("Unable to create pages: %s", err)
}
- viper.Set("baseurl", "http://auth/bub")
- viper.Set("DefaultExtension", "html")
- viper.Set("UglyURLs", false)
- viper.Set("PluralizeListTitles", false)
- viper.Set("CanonifyURLs", false)
-
return site
}
@@ -1228,7 +1229,7 @@ func TestSourceRelativeLinksing(t *testing.T) {
t.Fatalf("failed to find current page in site")
}
for link, url := range results {
- if out, err := site.Info.githubLink(link, currentPage, true); err != nil || out != url {
+ 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)
@@ -1241,7 +1242,7 @@ func TestSourceRelativeLinksing(t *testing.T) {
}
-func TestGitHubFileLinking(t *testing.T) {
+func TestSourceRelativeLinkFileing(t *testing.T) {
viper.Reset()
defer viper.Reset()
site := setupLinkingMockSite(t)
@@ -1278,15 +1279,11 @@ func TestGitHubFileLinking(t *testing.T) {
t.Fatalf("failed to find current page in site")
}
for link, url := range results {
- if out, err := site.Info.githubFileLink(link, currentPage, false); err != nil || out != url {
+ 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)
}
}
}
- // 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)
-
}