Repository: kovetskiy/mark
Pull request #158 (2022-01-21 17:39:25)

Add subdirectories related templates
It is the same as #151 but for the template.


Patch:
diff --git a/auth.go b/auth.go
index a62bba5..816f277 100644
--- a/auth.go
+++ b/auth.go
@@ -31,12 +31,6 @@ func GetCredentials(
 
 	if username == "" {
 		username = config.Username
-		if username == "" {
-			return nil, errors.New(
-				"Confluence username should be specified using -u " +
-					"flag or be stored in configuration file",
-			)
-		}
 	}
 
 	if password == "" {
diff --git a/main.go b/main.go
index dba8f3e..0812e5e 100644
--- a/main.go
+++ b/main.go
@@ -39,7 +39,7 @@ type Flags struct {
 }
 
 const (
-	version = "7.0"
+	version = "7.1"
 	usage   = `mark - a tool for updating Atlassian Confluence pages from markdown.
 
 Docs: https://github.com/kovetskiy/mark
@@ -53,7 +53,9 @@ Usage:
 Options:
   -u <username>        Use specified username for updating Confluence page.
   -p <token>           Use specified token for updating Confluence page.
-                        Specify - as password to read password from stdin.
+                        Specify - as password to read password from stdin, or your Personal access token.
+                        Username is not mandatory if personal access token is provided.
+                        For more info please see: https://developer.atlassian.com/server/confluence/confluence-server-rest-api/#authentication.
   -l <url>             Edit specified Confluence page.
                         If -l is not specified, file should contain metadata (see
                         above).
@@ -207,6 +209,7 @@ func processFile(
 
 	for {
 		templates, markdown, recurse, err = includes.ProcessIncludes(
+			filepath.Dir(file),
 			markdown,
 			templates,
 		)
@@ -219,7 +222,7 @@ func processFile(
 		}
 	}
 
-	macros, markdown, err := macro.ExtractMacros(markdown, templates)
+	macros, markdown, err := macro.ExtractMacros(filepath.Dir(file), markdown, templates)
 	if err != nil {
 		log.Fatal(err)
 	}
diff --git a/pkg/confluence/api.go b/pkg/confluence/api.go
index 3dd7a1c..2930851 100644
--- a/pkg/confluence/api.go
+++ b/pkg/confluence/api.go
@@ -88,9 +88,18 @@ func (tracer *tracer) Printf(format string, args ...interface{}) {
 }
 
 func NewAPI(baseURL string, username string, password string) *API {
-	auth := &gopencils.BasicAuth{username, password}
-
+	var auth *gopencils.BasicAuth
+	if username != "" {
+		auth = &gopencils.BasicAuth{username, password}
+	}
 	rest := gopencils.Api(baseURL+"/rest/api", auth)
+	if username == "" {
+		if rest.Headers == nil {
+			rest.Headers = http.Header{}
+		}
+		rest.SetHeader("Authorization", fmt.Sprintf("Bearer %s", password))
+	}
+
 	json := gopencils.Api(
 		baseURL+"/rpc/json-rpc/confluenceservice-v2",
 		auth,
@@ -218,7 +227,11 @@ func (api *API) CreateAttachment(
 	)
 
 	resource.Payload = form.buffer
+	oldHeaders := resource.Headers.Clone()
 	resource.Headers = http.Header{}
+	if resource.Api.BasicAuth == nil {
+		resource.Headers.Set("Authorization", oldHeaders.Get("Authorization"))
+	}
 
 	resource.SetHeader("Content-Type", form.writer.FormDataContentType())
 	resource.SetHeader("X-Atlassian-Token", "no-check")
@@ -284,7 +297,11 @@ func (api *API) UpdateAttachment(
 	)
 
 	resource.Payload = form.buffer
+	oldHeaders := resource.Headers.Clone()
 	resource.Headers = http.Header{}
+	if resource.Api.BasicAuth == nil {
+		resource.Headers.Set("Authorization", oldHeaders.Get("Authorization"))
+	}
 
 	resource.SetHeader("Content-Type", form.writer.FormDataContentType())
 	resource.SetHeader("X-Atlassian-Token", "no-check")
diff --git a/pkg/mark/includes/templates.go b/pkg/mark/includes/templates.go
index 75725a0..06aada8 100644
--- a/pkg/mark/includes/templates.go
+++ b/pkg/mark/includes/templates.go
@@ -21,6 +21,7 @@ var reIncludeDirective = regexp.MustCompile(
 	`(?s)<!--\s*Include:\s*(?P<template>\S+)\s*(\n(?P<config>.*?))?-->`)
 
 func LoadTemplate(
+	base string,
 	path string,
 	templates *template.Template,
 ) (*template.Template, error) {
@@ -35,7 +36,7 @@ func LoadTemplate(
 
 	var body []byte
 
-	body, err := ioutil.ReadFile(path)
+	body, err := ioutil.ReadFile(filepath.Join(base, path))
 	if err != nil {
 		err = facts.Format(
 			err,
@@ -65,6 +66,7 @@ func LoadTemplate(
 }
 
 func ProcessIncludes(
+	base string,
 	contents []byte,
 	templates *template.Template,
 ) (*template.Template, []byte, bool, error) {
@@ -122,7 +124,7 @@ func ProcessIncludes(
 
 			log.Tracef(vardump(facts, data), "including template %q", path)
 
-			templates, err = LoadTemplate(path, templates)
+			templates, err = LoadTemplate(base, path, templates)
 			if err != nil {
 				err = facts.Format(err, "unable to load template")
 
diff --git a/pkg/mark/macro/macro.go b/pkg/mark/macro/macro.go
index 796061f..a88fc47 100644
--- a/pkg/mark/macro/macro.go
+++ b/pkg/mark/macro/macro.go
@@ -105,6 +105,7 @@ func (macro *Macro) configure(node interface{}, groups [][]byte) interface{} {
 }
 
 func ExtractMacros(
+	base string,
 	contents []byte,
 	templates *template.Template,
 ) ([]Macro, []byte, error) {
@@ -133,7 +134,7 @@ func ExtractMacros(
 				macro Macro
 			)
 
-			macro.Template, err = includes.LoadTemplate(template, templates)
+			macro.Template, err = includes.LoadTemplate(base, template, templates)
 			if err != nil {
 				err = karma.Format(err, "unable to load template")
 
diff --git a/pkg/mark/markdown.go b/pkg/mark/markdown.go
index de418b8..06c2128 100644
--- a/pkg/mark/markdown.go
+++ b/pkg/mark/markdown.go
@@ -125,7 +125,8 @@ func CompileMarkdown(
 				bf.Titleblock|
 				bf.BackslashLineBreak|
 				bf.DefinitionLists|
-				bf.NoEmptyLineBeforeBlock,
+				bf.NoEmptyLineBeforeBlock|
+				bf.Footnotes,
 		),
 	)
 
diff --git a/pkg/mark/stdlib/stdlib.go b/pkg/mark/stdlib/stdlib.go
index 01f6f4e..463d638 100644
--- a/pkg/mark/stdlib/stdlib.go
+++ b/pkg/mark/stdlib/stdlib.go
@@ -41,6 +41,7 @@ func macros(templates *template.Template) ([]macro.Macro, error) {
 	}
 
 	macros, _, err := macro.ExtractMacros(
+		"",
 		[]byte(text(
 			`<!-- Macro: @\{([^}]+)\}`,
 			`     Template: ac:link:user`,


Test patch:
diff --git a/pkg/mark/testdata/links.html b/pkg/mark/testdata/links.html
index 295c740..4a3293e 100644
--- a/pkg/mark/testdata/links.html
+++ b/pkg/mark/testdata/links.html
@@ -1,3 +1,15 @@
 <p>Use <a href="https://example.com">https://example.com</a></p>
 
 <p>Use <ac:rich-text-body>aaa</ac:rich-text-body></p>
+
+<p>Use footnotes link <sup class="footnote-ref" id="fnref:1"><a href="#fn:1">1</a></sup></p>
+
+<div class="footnotes">
+
+<hr />
+
+<ol>
+<li id="fn:1">a footnote link</li>
+</ol>
+
+</div>
diff --git a/pkg/mark/testdata/links.md b/pkg/mark/testdata/links.md
index 7ef24fa..f814795 100644
--- a/pkg/mark/testdata/links.md
+++ b/pkg/mark/testdata/links.md
@@ -1,3 +1,6 @@
 Use <https://example.com>
 
 Use <ac:rich-text-body>aaa</ac:rich-text-body>
+
+Use footnotes link [^1]  
+[^1]: a footnote link
\ No newline at end of file