diff --git a/README.md b/README.md
index c8f3b8f..3ce0f18 100644
--- a/README.md
+++ b/README.md
@@ -371,6 +371,10 @@ By default, mark provides several built-in templates and macros:
See: https://confluence.atlassian.com/doc/blog-posts-macro-139470.html
+* template: `ac:include` to include a page
+ - Page: the page to be included
+ - Space: the space the page is in (optional, otherwise same space)
+
* macro `@{...}` to mention user by name specified in the braces.
## Template & Macros Usecases
diff --git a/pkg/mark/markdown.go b/pkg/mark/markdown.go
index 680375d..5b12cd1 100644
--- a/pkg/mark/markdown.go
+++ b/pkg/mark/markdown.go
@@ -6,6 +6,7 @@ import (
"regexp"
"strings"
+ cparser "github.com/kovetskiy/mark/pkg/mark/parser"
"github.com/kovetskiy/mark/pkg/mark/stdlib"
"github.com/reconquest/pkg/log"
"github.com/yuin/goldmark"
@@ -450,7 +451,7 @@ func CompileMarkdown(markdown []byte, stdlib *stdlib.Lib) string {
converter.Parser().AddOptions(parser.WithInlineParsers(
// Must be registered with a higher priority than goldmark's linkParser to make sure goldmark doesn't parse
// the tags.
- util.Prioritized(NewACTagParser(), 199),
+ util.Prioritized(cparser.NewConfluenceTagParser(), 199),
))
converter.Renderer().AddOptions(renderer.WithNodeRenderers(
diff --git a/pkg/mark/ac_tag_parser.go b/pkg/mark/parser/confluencetags.go
similarity index 72%
rename from pkg/mark/ac_tag_parser.go
rename to pkg/mark/parser/confluencetags.go
index 763a1ca..56bba8d 100644
--- a/pkg/mark/ac_tag_parser.go
+++ b/pkg/mark/parser/confluencetags.go
@@ -1,4 +1,4 @@
-package mark
+package parser
import (
"bytes"
@@ -9,25 +9,25 @@ import (
"regexp"
)
-// NewACTagParser returns an inline parser that parses tags to ensure that Confluence specific tags are parsed
+// NewConfluenceTagParser returns an inline parser that parses and tags to ensure that Confluence specific tags are parsed
// as ast.KindRawHtml so they are not escaped at render time. The parser must be registered with a higher priority
// than goldmark's linkParser. Otherwise, the linkParser would parse the tags.
-func NewACTagParser() parser.InlineParser {
- return &acTagParser{}
+func NewConfluenceTagParser() parser.InlineParser {
+ return &confluenceTagParser{}
}
-var _ parser.InlineParser = (*acTagParser)(nil)
+var _ parser.InlineParser = (*confluenceTagParser)(nil)
-// acTagParser is a stripped down version of goldmark's rawHTMLParser.
+// confluenceTagParser is a stripped down version of goldmark's rawHTMLParser.
// See: https://github.com/yuin/goldmark/blob/master/parser/raw_html.go
-type acTagParser struct {
+type confluenceTagParser struct {
}
-func (s *acTagParser) Trigger() []byte {
+func (s *confluenceTagParser) Trigger() []byte {
return []byte{'<'}
}
-func (s *acTagParser) Parse(_ ast.Node, block text.Reader, pc parser.Context) ast.Node {
+func (s *confluenceTagParser) Parse(_ ast.Node, block text.Reader, pc parser.Context) ast.Node {
line, _ := block.PeekLine()
if len(line) > 1 && util.IsAlphaNumeric(line[1]) {
return s.parseMultiLineRegexp(openTagRegexp, block, pc)
@@ -48,15 +48,15 @@ var tagnamePattern = `([A-Za-z][A-Za-z0-9-]*)`
var attributePattern = `(?:[\r\n \t]+[a-zA-Z_:][a-zA-Z0-9:._-]*(?:[\r\n \t]*=[\r\n \t]*(?:[^\"'=<>` + "`" + `\x00-\x20]+|'[^']*'|"[^"]*"))?)`
-// Only match tags
-var openTagRegexp = regexp.MustCompile("^`)
+// Only match and tags
+var openTagRegexp = regexp.MustCompile("^<(ac|ri):" + tagnamePattern + attributePattern + `*[ \t]*/?>`)
var closeTagRegexp = regexp.MustCompile("^`)
var openCDATA = []byte("")
var closeDecl = []byte(">")
-func (s *acTagParser) parseUntil(block text.Reader, closer []byte, _ parser.Context) ast.Node {
+func (s *confluenceTagParser) parseUntil(block text.Reader, closer []byte, _ parser.Context) ast.Node {
savedLine, savedSegment := block.Position()
node := ast.NewRawHTML()
for {
@@ -77,7 +77,7 @@ func (s *acTagParser) parseUntil(block text.Reader, closer []byte, _ parser.Cont
return nil
}
-func (s *acTagParser) parseMultiLineRegexp(reg *regexp.Regexp, block text.Reader, _ parser.Context) ast.Node {
+func (s *confluenceTagParser) parseMultiLineRegexp(reg *regexp.Regexp, block text.Reader, _ parser.Context) ast.Node {
sline, ssegment := block.Position()
if block.Match(reg) {
node := ast.NewRawHTML()
diff --git a/pkg/mark/stdlib/stdlib.go b/pkg/mark/stdlib/stdlib.go
index 31c20b6..62daf5f 100644
--- a/pkg/mark/stdlib/stdlib.go
+++ b/pkg/mark/stdlib/stdlib.go
@@ -261,6 +261,18 @@ func templates(api *confluence.API) (*template.Template, error) {
`{{printf "\n"}}`,
),
+ /* https://confluence.atlassian.com/conf59/include-page-macro-792499125.html */
+
+ `ac:include`: text(
+ `{{printf "\n"}}`,
+ `{{printf "\n"}}`,
+ `{{printf "\n"}}`,
+ `{{printf "\n"}}`,
+ `{{printf "\n"}}`,
+ `{{printf "\n"}}`,
+ `{{printf "\n"}}`,
+ ),
+
// TODO(seletskiy): more templates here
} {
templates, err = templates.New(name).Parse(body)