Repository: kovetskiy/mark
Pull request #451 (2024-06-10 16:18:36)

Bump goreleaser/goreleaser-action from 5 to 6
Bumps [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action) from 5 to 6.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/goreleaser/goreleaser-action/releases">goreleaser/goreleaser-action's releases</a>.</em></p>
<blockquote>
<h2>v6.0.0</h2>
<blockquote>
<p>[!WARNING]
<strong>This is a breaking change!</strong></p>
<p>Follow the instructions <a href="https://goreleaser.com/blog/goreleaser-v2/#upgrading">here</a> to upgrade!</p>
</blockquote>
<h2>What's Changed</h2>
<ul>
<li>feat!: use &quot;~&gt; v2&quot; as default by <a href="https://github.com/caarlos0"><code>@​caarlos0</code></a> in <a href="https://redirect.github.com/goreleaser/goreleaser-action/pull/463">goreleaser/goreleaser-action#463</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a href="https://github.com/goreleaser/goreleaser-action/compare/v5...v6.0.0">https://github.com/goreleaser/goreleaser-action/compare/v5...v6.0.0</a></p>
<h2>v5.1.0</h2>
<h2>Important</h2>
<p>This version changes the default behavior of <code>latest</code> to <code>~&gt; v1</code>.</p>
<p>The next major of this action (v6), will change this to <code>~&gt; v2</code>, and will be launched together with GoReleaser v2.</p>
<h2>What's Changed</h2>
<ul>
<li>docs: bump actions to latest major by <a href="https://github.com/crazy-max"><code>@​crazy-max</code></a> in <a href="https://redirect.github.com/goreleaser/goreleaser-action/pull/435">goreleaser/goreleaser-action#435</a></li>
<li>chore(deps): bump docker/bake-action from 3 to 4 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/goreleaser/goreleaser-action/pull/436">goreleaser/goreleaser-action#436</a></li>
<li>chore(deps): bump codecov/codecov-action from 3 to 4 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/goreleaser/goreleaser-action/pull/437">goreleaser/goreleaser-action#437</a></li>
<li>chore(deps): bump actions/setup-go from 4 to 5 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/goreleaser/goreleaser-action/pull/443">goreleaser/goreleaser-action#443</a></li>
<li>chore(deps): bump actions/upload-artifact from 3 to 4 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/goreleaser/goreleaser-action/pull/444">goreleaser/goreleaser-action#444</a></li>
<li>Delete .kodiak.toml by <a href="https://github.com/vedantmgoyal9"><code>@​vedantmgoyal9</code></a> in <a href="https://redirect.github.com/goreleaser/goreleaser-action/pull/446">goreleaser/goreleaser-action#446</a></li>
<li>chore(deps): bump codecov/codecov-action from 3 to 4 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/goreleaser/goreleaser-action/pull/448">goreleaser/goreleaser-action#448</a></li>
<li>chore(deps): bump ip from 2.0.0 to 2.0.1 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/goreleaser/goreleaser-action/pull/450">goreleaser/goreleaser-action#450</a></li>
<li>Upgrade setup-go action version in README by <a href="https://github.com/kishaningithub"><code>@​kishaningithub</code></a> in <a href="https://redirect.github.com/goreleaser/goreleaser-action/pull/455">goreleaser/goreleaser-action#455</a></li>
<li>chore(deps): bump tar from 6.1.14 to 6.2.1 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/goreleaser/goreleaser-action/pull/456">goreleaser/goreleaser-action#456</a></li>
<li>chore: use corepack to install yarn by <a href="https://github.com/crazy-max"><code>@​crazy-max</code></a> in <a href="https://redirect.github.com/goreleaser/goreleaser-action/pull/458">goreleaser/goreleaser-action#458</a></li>
<li>feat: lock this major version of the action to use '~&gt; v1' as 'latest' by <a href="https://github.com/caarlos0"><code>@​caarlos0</code></a> in <a href="https://redirect.github.com/goreleaser/goreleaser-action/pull/461">goreleaser/goreleaser-action#461</a></li>
<li>chore(deps): bump semver from 7.6.0 to 7.6.2 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/goreleaser/goreleaser-action/pull/462">goreleaser/goreleaser-action#462</a></li>
<li>chore(deps): bump <code>@​actions/http-client</code> from 2.2.0 to 2.2.1 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/goreleaser/goreleaser-action/pull/451">goreleaser/goreleaser-action#451</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/vedantmgoyal9"><code>@​vedantmgoyal9</code></a> made their first contribution in <a href="https://redirect.github.com/goreleaser/goreleaser-action/pull/446">goreleaser/goreleaser-action#446</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a href="https://github.com/goreleaser/goreleaser-action/compare/v5.0.0...v5.1.0">https://github.com/goreleaser/goreleaser-action/compare/v5.0.0...v5.1.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/goreleaser/goreleaser-action/commit/286f3b13b1b49da4ac219696163fb8c1c93e1200"><code>286f3b1</code></a> ci: fix tests</li>
<li><a href="https://github.com/goreleaser/goreleaser-action/commit/beac41031402cb955b6b1325b39dc6a3aaddfa61"><code>beac410</code></a> ci: update workflow and .goreleaser.yml</li>
<li><a href="https://github.com/goreleaser/goreleaser-action/commit/18bbabc70c50bcffbadb2dc68d6d5266056978cb"><code>18bbabc</code></a> feat!: use &quot;~&gt; v2&quot; as default (<a href="https://redirect.github.com/goreleaser/goreleaser-action/issues/463">#463</a>)</li>
<li>See full diff in <a href="https://github.com/goreleaser/goreleaser-action/compare/v5...v6">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=goreleaser/goreleaser-action&package-manager=github_actions&previous-version=5&new-version=6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

You can trigger a rebase of this PR by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>

> **Note**
> Automatic rebases have been disabled on this pull request as it has been open for over 30 days.



Patch:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 86e01f8..7bfa19e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -89,7 +89,7 @@ jobs:
       uses: docker/setup-buildx-action@v3
 
     - name: Build only (on commits)
-      uses: docker/build-push-action@v5
+      uses: docker/build-push-action@v6
       if: ${{ github.ref_type != 'tag' }}
       with:
         push: false
@@ -103,7 +103,7 @@ jobs:
         password: ${{ secrets.DOCKERHUB_PASSWORD }}
 
     - name: Build and push (on tag)
-      uses: docker/build-push-action@v5
+      uses: docker/build-push-action@v6
       if: ${{ github.ref_type == 'tag' }}
       with:
         push: true
diff --git a/.github/workflows/goreleaser.yml b/.github/workflows/goreleaser.yml
index 7773ec2..89add9a 100644
--- a/.github/workflows/goreleaser.yml
+++ b/.github/workflows/goreleaser.yml
@@ -18,9 +18,9 @@ jobs:
       with:
         go-version: "1.21"
     - name: Run GoReleaser
-      uses: goreleaser/goreleaser-action@v5
+      uses: goreleaser/goreleaser-action@v6
       with:
-        version: latest
+        version: "~> 2"
         args: release --clean
       env:
         GOPATH: /home/runner/work/
diff --git a/.gitignore b/.gitignore
index edd1254..f6c18f3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@
 .idea/
 /mark.test
 /profile.cov
+.vscode
diff --git a/.goreleaser.yml b/.goreleaser.yml
index 11a92d0..0157630 100644
--- a/.goreleaser.yml
+++ b/.goreleaser.yml
@@ -1,5 +1,6 @@
 # This is an example goreleaser.yaml file with some sane defaults.
 # Make sure to check the documentation at http://goreleaser.com
+version: 2
 before:
   hooks:
     # You may remove this if you don't use go modules.
@@ -39,7 +40,7 @@ changelog:
 brews:
   -
     name: mark
-    tap:
+    repository:
       owner: kovetskiy
       name: homebrew-mark
       branch: master
@@ -50,7 +51,7 @@ brews:
 
     commit_msg_template: "Brew formula update for {{ .ProjectName }} version {{ .Tag }}"
 
-    folder: Formula
+    directory: Formula
 
     homepage: "https://github.com/kovetskiy/mark"
     description: "Sync your markdown files with Confluence pages."
diff --git a/Dockerfile b/Dockerfile
index 760271e..a5b0a3b 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM golang:1.22.3 as builder
+FROM golang:1.22.5 as builder
 ENV GOPATH="/go"
 WORKDIR /go/src/github.com/kovetskiy/mark
 COPY / .
diff --git a/README.md b/README.md
index 1ebeba8..f581fdd 100644
--- a/README.md
+++ b/README.md
@@ -751,7 +751,7 @@ USAGE:
    mark [global options] 
 
 VERSION:
-   9.12.0
+   9.13.1
 
 DESCRIPTION:
    Mark is a tool to update Atlassian Confluence pages from markdown. Documentation is available here: https://github.com/kovetskiy/mark
diff --git a/go.mod b/go.mod
index 7c53108..3a04437 100644
--- a/go.mod
+++ b/go.mod
@@ -13,9 +13,9 @@ require (
 	github.com/reconquest/pkg v1.3.1-0.20230331080542-242a3690a7bc
 	github.com/reconquest/regexputil-go v0.0.0-20160905154124-38573e70c1f4
 	github.com/stretchr/testify v1.9.0
-	github.com/urfave/cli/v2 v2.27.2
-	github.com/yuin/goldmark v1.7.1
-	golang.org/x/tools v0.21.0
+	github.com/urfave/cli/v2 v2.27.3
+	github.com/yuin/goldmark v1.7.4
+	golang.org/x/tools v0.23.0
 	gopkg.in/yaml.v3 v3.0.1
 )
 
@@ -35,8 +35,8 @@ require (
 	github.com/pmezard/go-difflib v1.0.0 // indirect
 	github.com/reconquest/cog v0.0.0-20230331074503-900980efda0b // indirect
 	github.com/russross/blackfriday/v2 v2.1.0 // indirect
-	github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect
+	github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
 	github.com/zazab/zhash v0.0.0-20210630080733-6e809466f8d3 // indirect
-	golang.org/x/sys v0.20.0 // indirect
+	golang.org/x/sys v0.22.0 // indirect
 	gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
 )
diff --git a/go.sum b/go.sum
index 16b52f8..01e912b 100644
--- a/go.sum
+++ b/go.sum
@@ -55,20 +55,20 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf
 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
 github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
-github.com/urfave/cli/v2 v2.27.2 h1:6e0H+AkS+zDckwPCUrZkKX38mRaau4nL2uipkJpbkcI=
-github.com/urfave/cli/v2 v2.27.2/go.mod h1:g0+79LmHHATl7DAcHO99smiR/T7uGLw84w8Y42x+4eM=
-github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw=
-github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk=
-github.com/yuin/goldmark v1.7.1 h1:3bajkSilaCbjdKVsKdZjZCLBNPL9pYzrCakKaf4U49U=
-github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
+github.com/urfave/cli/v2 v2.27.3 h1:/POWahRmdh7uztQ3CYnaDddk0Rm90PyOgIxgW2rr41M=
+github.com/urfave/cli/v2 v2.27.3/go.mod h1:m4QzxcD2qpra4z7WhzEGn74WZLViBnMpb1ToCAKdGRQ=
+github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
+github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
+github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg=
+github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
 github.com/zazab/zhash v0.0.0-20210630080733-6e809466f8d3 h1:BhVaeQJc3xalHGONn215FylzuxdQBIT3d/aRjDg4nXQ=
 github.com/zazab/zhash v0.0.0-20210630080733-6e809466f8d3/go.mod h1:NtepZ8TEXErPsmQDMUoN72f8aIy4+xNinSJ3f1giess=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
-golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw=
-golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
+golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
+golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
+golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
diff --git a/main.go b/main.go
index 03bd170..a33a2f3 100644
--- a/main.go
+++ b/main.go
@@ -5,6 +5,7 @@ import (
 	"fmt"
 	"os"
 	"path/filepath"
+	"slices"
 	"strings"
 	"time"
 
@@ -24,7 +25,7 @@ import (
 )
 
 const (
-	version     = "9.12.0"
+	version     = "9.13.1"
 	usage       = "A tool for updating Atlassian Confluence pages from markdown."
 	description = `Mark is a tool to update Atlassian Confluence pages from markdown. Documentation is available here: https://github.com/kovetskiy/mark`
 )
@@ -522,6 +523,8 @@ func processFile(
 		log.Fatal(err)
 	}
 
+	updateLabels(api, target, meta)
+
 	if cCtx.Bool("edit-lock") {
 		log.Infof(
 			nil,
@@ -539,6 +542,68 @@ func processFile(
 	return target
 }
 
+func updateLabels(api *confluence.API, target *confluence.PageInfo, meta *mark.Meta) {
+
+	labelInfo, err := api.GetPageLabels(target, "global")
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	log.Debug("Page Labels:")
+	log.Debug(labelInfo.Labels)
+
+	log.Debug("Meta Labels:")
+	log.Debug(meta.Labels)
+
+	delLabels := determineLabelsToRemove(labelInfo, meta)
+	log.Debug("Del Labels:")
+	log.Debug(delLabels)
+
+	addLabels := determineLabelsToAdd(meta, labelInfo)
+	log.Debug("Add Labels:")
+	log.Debug(addLabels)
+
+	if len(addLabels) > 0 {
+		_, err = api.AddPageLabels(target, addLabels)
+		if err != nil {
+			log.Fatal(err)
+		}
+	}
+
+	for _, label := range delLabels {
+		_, err = api.DeletePageLabel(target, label)
+		if err != nil {
+			log.Fatal(err)
+		}
+	}
+}
+
+// Page has label but label not in Metadata
+func determineLabelsToRemove(labelInfo *confluence.LabelInfo, meta *mark.Meta) []string {
+	var labels []string
+	for _, label := range labelInfo.Labels {
+		if !slices.ContainsFunc(meta.Labels, func(metaLabel string) bool {
+			return strings.EqualFold(metaLabel, label.Name)
+		}) {
+			labels = append(labels, label.Name)
+		}
+	}
+	return labels
+}
+
+// Metadata has label but Page does not have it
+func determineLabelsToAdd(meta *mark.Meta, labelInfo *confluence.LabelInfo) []string {
+	var labels []string
+	for _, metaLabel := range meta.Labels {
+		if !slices.ContainsFunc(labelInfo.Labels, func(label confluence.Label) bool {
+			return strings.EqualFold(label.Name, metaLabel)
+		}) {
+			labels = append(labels, metaLabel)
+		}
+	}
+	return labels
+}
+
 func configFilePath() string {
 	fp, err := os.UserConfigDir()
 	if err != nil {
diff --git a/pkg/confluence/api.go b/pkg/confluence/api.go
index 31be7f2..6ede89e 100644
--- a/pkg/confluence/api.go
+++ b/pkg/confluence/api.go
@@ -73,6 +73,15 @@ type AttachmentInfo struct {
 	} `json:"_links"`
 }
 
+type Label struct {
+	ID     string `json:"id"`
+	Prefix string `json:"prefix"`
+	Name   string `json:"name"`
+}
+type LabelInfo struct {
+	Labels []Label `json:"results"`
+	Size   int     `json:"number"`
+}
 type form struct {
 	buffer io.Reader
 	writer *multipart.Writer
@@ -514,17 +523,6 @@ func (api *API) UpdatePage(page *PageInfo, newContent string, minorEdit bool, ve
 		}
 	}
 
-	labels := []map[string]interface{}{}
-	for _, label := range newLabels {
-		if label != "" {
-			item := map[string]interface{}{
-				"prexix": "global",
-				"name":   label,
-			}
-			labels = append(labels, item)
-		}
-	}
-
 	payload := map[string]interface{}{
 		"id":    page.ID,
 		"type":  page.Type,
@@ -542,7 +540,6 @@ func (api *API) UpdatePage(page *PageInfo, newContent string, minorEdit bool, ve
 			},
 		},
 		"metadata": map[string]interface{}{
-			"labels": labels,
 			// Fix to set full-width as has changed on Confluence APIs again.
 			// https://jira.atlassian.com/browse/CONFCLOUD-65447
 			//
@@ -570,6 +567,66 @@ func (api *API) UpdatePage(page *PageInfo, newContent string, minorEdit bool, ve
 	return nil
 }
 
+func (api *API) AddPageLabels(page *PageInfo, newLabels []string) (*LabelInfo, error) {
+
+	labels := []map[string]interface{}{}
+	for _, label := range newLabels {
+		if label != "" {
+			item := map[string]interface{}{
+				"prefix": "global",
+				"name":   label,
+			}
+			labels = append(labels, item)
+		}
+	}
+
+	payload := labels
+
+	request, err := api.rest.Res(
+		"content/"+page.ID+"/label", &LabelInfo{},
+	).Post(payload)
+	if err != nil {
+		return nil, err
+	}
+
+	if request.Raw.StatusCode != http.StatusOK {
+		return nil, newErrorStatusNotOK(request)
+	}
+
+	return request.Response.(*LabelInfo), nil
+}
+
+func (api *API) DeletePageLabel(page *PageInfo, label string) (*LabelInfo, error) {
+
+	request, err := api.rest.Res(
+		"content/"+page.ID+"/label/"+label, &LabelInfo{},
+	).Delete()
+	if err != nil {
+		return nil, err
+	}
+
+	if request.Raw.StatusCode != http.StatusOK {
+		return nil, newErrorStatusNotOK(request)
+	}
+
+	return request.Response.(*LabelInfo), nil
+}
+
+func (api *API) GetPageLabels(page *PageInfo, prefix string) (*LabelInfo, error) {
+
+	request, err := api.rest.Res(
+		"content/"+page.ID+"/label", &LabelInfo{},
+	).Get(map[string]string{"prefix": prefix})
+	if err != nil {
+		return nil, err
+	}
+
+	if request.Raw.StatusCode != http.StatusOK {
+		return nil, newErrorStatusNotOK(request)
+	}
+	return request.Response.(*LabelInfo), nil
+}
+
 func (api *API) GetUserByName(name string) (*User, error) {
 	var response struct {
 		Results []struct {
diff --git a/pkg/mark/markdown.go b/pkg/mark/markdown.go
index 2f057d3..b1c58cd 100644
--- a/pkg/mark/markdown.go
+++ b/pkg/mark/markdown.go
@@ -58,6 +58,7 @@ func (c *ConfluenceExtension) Extend(m goldmark.Markdown) {
 		util.Prioritized(crenderer.NewConfluenceHTMLBlockRenderer(c.Stdlib), 100),
 		util.Prioritized(crenderer.NewConfluenceHeadingRenderer(c.DropFirstH1), 100),
 		util.Prioritized(crenderer.NewConfluenceImageRenderer(c.Stdlib, c, c.Path), 100),
+		util.Prioritized(crenderer.NewConfluenceParagraphRenderer(), 100),
 		util.Prioritized(crenderer.NewConfluenceLinkRenderer(), 100),
 	))
 
diff --git a/pkg/mark/renderer/htmlblock.go b/pkg/mark/renderer/htmlblock.go
index acb3206..b8d9d1a 100644
--- a/pkg/mark/renderer/htmlblock.go
+++ b/pkg/mark/renderer/htmlblock.go
@@ -71,6 +71,12 @@ func (r *ConfluenceHTMLBlockRenderer) renderHTMLBlock(w util.BufWriter, source [
 		case "<!-- ac:layout-cell end -->":
 			_, _ = w.WriteString("</ac:layout-cell>\n")
 			return ast.WalkContinue, nil
+		case "<!-- ac:placeholder -->":
+			_, _ = w.WriteString("<ac:placeholder>\n")
+			return ast.WalkContinue, nil
+		case "<!-- ac:placeholder end -->":
+			_, _ = w.WriteString("</ac:placeholder>\n")
+			return ast.WalkContinue, nil
 
 		}
 	}
diff --git a/pkg/mark/renderer/paragraph.go b/pkg/mark/renderer/paragraph.go
new file mode 100644
index 0000000..df9bc49
--- /dev/null
+++ b/pkg/mark/renderer/paragraph.go
@@ -0,0 +1,31 @@
+package renderer
+
+import (
+	"github.com/yuin/goldmark/ast"
+	"github.com/yuin/goldmark/renderer"
+	"github.com/yuin/goldmark/renderer/html"
+	"github.com/yuin/goldmark/util"
+)
+
+type ConfluenceParagraphRenderer struct {
+	html.Config
+}
+
+// NewConfluenceRenderer creates a new instance of the ConfluenceRenderer
+func NewConfluenceParagraphRenderer(opts ...html.Option) renderer.NodeRenderer {
+	return &ConfluenceParagraphRenderer{
+		Config: html.NewConfig(),
+	}
+}
+
+// RegisterFuncs implements NodeRenderer.RegisterFuncs .
+func (r *ConfluenceParagraphRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) {
+	reg.Register(ast.KindParagraph, r.renderParagraph)
+}
+
+func (r *ConfluenceParagraphRenderer) renderParagraph(w util.BufWriter, source []byte, n ast.Node, entering bool) (ast.WalkStatus, error) {
+	if !entering {
+		_, _ = w.WriteString("\n")
+	}
+	return ast.WalkContinue, nil
+}
diff --git a/pkg/mark/stdlib/stdlib.go b/pkg/mark/stdlib/stdlib.go
index 84bf0e0..d7ae4ce 100644
--- a/pkg/mark/stdlib/stdlib.go
+++ b/pkg/mark/stdlib/stdlib.go
@@ -370,7 +370,7 @@ func templates(api *confluence.API) (*template.Template, error) {
 		/* https://confluence.atlassian.com/conf59/page-properties-macro-792499154.html */
 
 		`ac:details`: text(
-			`<ac:structured-macro ac:name="details" ac:schema-version="1"">`,
+			`<ac:structured-macro ac:name="details" ac:schema-version="1">`,
 			`<ac:rich-text-body>{{ .Body }}</ac:rich-text-body>`,
 			`</ac:structured-macro>`,
 		),


Test patch:
diff --git a/pkg/mark/testdata/codes-droph1.html b/pkg/mark/testdata/codes-droph1.html
index 733410b..bcf5be7 100644
--- a/pkg/mark/testdata/codes-droph1.html
+++ b/pkg/mark/testdata/codes-droph1.html
@@ -1,7 +1,7 @@
-<p><code>inline</code></p>
+<code>inline</code>
 <ac:structured-macro ac:name="code"><ac:parameter ac:name="language"></ac:parameter><ac:parameter ac:name="collapse">false</ac:parameter><ac:plain-text-body><![CDATA[some code]]></ac:plain-text-body></ac:structured-macro><ac:structured-macro ac:name="code"><ac:parameter ac:name="language">bash</ac:parameter><ac:parameter ac:name="collapse">false</ac:parameter><ac:plain-text-body><![CDATA[code bash]]></ac:plain-text-body></ac:structured-macro><ac:structured-macro ac:name="code"><ac:parameter ac:name="language">bash</ac:parameter><ac:parameter ac:name="collapse">false</ac:parameter><ac:plain-text-body><![CDATA[with a newline
-]]></ac:plain-text-body></ac:structured-macro><ac:structured-macro ac:name="code"><ac:parameter ac:name="language">unknown</ac:parameter><ac:parameter ac:name="collapse">false</ac:parameter><ac:plain-text-body><![CDATA[unknown code]]></ac:plain-text-body></ac:structured-macro><p>text
-text 2</p>
+]]></ac:plain-text-body></ac:structured-macro><ac:structured-macro ac:name="code"><ac:parameter ac:name="language">unknown</ac:parameter><ac:parameter ac:name="collapse">false</ac:parameter><ac:plain-text-body><![CDATA[unknown code]]></ac:plain-text-body></ac:structured-macro>text
+text 2
 <ac:structured-macro ac:name="code"><ac:parameter ac:name="language">unknown</ac:parameter><ac:parameter ac:name="collapse">false</ac:parameter><ac:plain-text-body><![CDATA[unknown code 2]]></ac:plain-text-body></ac:structured-macro><ac:structured-macro ac:name="code"><ac:parameter ac:name="language">sh</ac:parameter><ac:parameter ac:name="collapse">false</ac:parameter><ac:parameter ac:name="title">A b c</ac:parameter><ac:plain-text-body><![CDATA[no-collapse-title]]></ac:plain-text-body></ac:structured-macro><ac:structured-macro ac:name="code"><ac:parameter ac:name="language">bash</ac:parameter><ac:parameter ac:name="collapse">true</ac:parameter><ac:parameter ac:name="title">A b c</ac:parameter><ac:plain-text-body><![CDATA[collapse-and-title]]></ac:plain-text-body></ac:structured-macro><ac:structured-macro ac:name="code"><ac:parameter ac:name="language">c</ac:parameter><ac:parameter ac:name="collapse">true</ac:parameter><ac:plain-text-body><![CDATA[collapse-no-title]]></ac:plain-text-body></ac:structured-macro><ac:structured-macro ac:name="code"><ac:parameter ac:name="language">nested</ac:parameter><ac:parameter ac:name="collapse">false</ac:parameter><ac:plain-text-body><![CDATA[code
 ``` more code ```
 even more code]]></ac:plain-text-body></ac:structured-macro><ac:structured-macro ac:name="code"><ac:parameter ac:name="language"></ac:parameter><ac:parameter ac:name="collapse">false</ac:parameter><ac:plain-text-body><![CDATA[indented code block
diff --git a/pkg/mark/testdata/codes-stripnewlines.html b/pkg/mark/testdata/codes-stripnewlines.html
index 63eff28..35097f5 100644
--- a/pkg/mark/testdata/codes-stripnewlines.html
+++ b/pkg/mark/testdata/codes-stripnewlines.html
@@ -1,6 +1,6 @@
-<p><code>inline</code></p>
+<code>inline</code>
 <ac:structured-macro ac:name="code"><ac:parameter ac:name="language"></ac:parameter><ac:parameter ac:name="collapse">false</ac:parameter><ac:plain-text-body><![CDATA[some code]]></ac:plain-text-body></ac:structured-macro><ac:structured-macro ac:name="code"><ac:parameter ac:name="language">bash</ac:parameter><ac:parameter ac:name="collapse">false</ac:parameter><ac:plain-text-body><![CDATA[code bash]]></ac:plain-text-body></ac:structured-macro><ac:structured-macro ac:name="code"><ac:parameter ac:name="language">bash</ac:parameter><ac:parameter ac:name="collapse">false</ac:parameter><ac:plain-text-body><![CDATA[with a newline
-]]></ac:plain-text-body></ac:structured-macro><ac:structured-macro ac:name="code"><ac:parameter ac:name="language">unknown</ac:parameter><ac:parameter ac:name="collapse">false</ac:parameter><ac:plain-text-body><![CDATA[unknown code]]></ac:plain-text-body></ac:structured-macro><p>text text 2</p>
+]]></ac:plain-text-body></ac:structured-macro><ac:structured-macro ac:name="code"><ac:parameter ac:name="language">unknown</ac:parameter><ac:parameter ac:name="collapse">false</ac:parameter><ac:plain-text-body><![CDATA[unknown code]]></ac:plain-text-body></ac:structured-macro>text text 2
 <ac:structured-macro ac:name="code"><ac:parameter ac:name="language">unknown</ac:parameter><ac:parameter ac:name="collapse">false</ac:parameter><ac:plain-text-body><![CDATA[unknown code 2]]></ac:plain-text-body></ac:structured-macro><ac:structured-macro ac:name="code"><ac:parameter ac:name="language">sh</ac:parameter><ac:parameter ac:name="collapse">false</ac:parameter><ac:parameter ac:name="title">A b c</ac:parameter><ac:plain-text-body><![CDATA[no-collapse-title]]></ac:plain-text-body></ac:structured-macro><ac:structured-macro ac:name="code"><ac:parameter ac:name="language">bash</ac:parameter><ac:parameter ac:name="collapse">true</ac:parameter><ac:parameter ac:name="title">A b c</ac:parameter><ac:plain-text-body><![CDATA[collapse-and-title]]></ac:plain-text-body></ac:structured-macro><ac:structured-macro ac:name="code"><ac:parameter ac:name="language">c</ac:parameter><ac:parameter ac:name="collapse">true</ac:parameter><ac:plain-text-body><![CDATA[collapse-no-title]]></ac:plain-text-body></ac:structured-macro><ac:structured-macro ac:name="code"><ac:parameter ac:name="language">nested</ac:parameter><ac:parameter ac:name="collapse">false</ac:parameter><ac:plain-text-body><![CDATA[code
 ``` more code ```
 even more code]]></ac:plain-text-body></ac:structured-macro><ac:structured-macro ac:name="code"><ac:parameter ac:name="language"></ac:parameter><ac:parameter ac:name="collapse">false</ac:parameter><ac:plain-text-body><![CDATA[indented code block
diff --git a/pkg/mark/testdata/codes.html b/pkg/mark/testdata/codes.html
index 733410b..bcf5be7 100644
--- a/pkg/mark/testdata/codes.html
+++ b/pkg/mark/testdata/codes.html
@@ -1,7 +1,7 @@
-<p><code>inline</code></p>
+<code>inline</code>
 <ac:structured-macro ac:name="code"><ac:parameter ac:name="language"></ac:parameter><ac:parameter ac:name="collapse">false</ac:parameter><ac:plain-text-body><![CDATA[some code]]></ac:plain-text-body></ac:structured-macro><ac:structured-macro ac:name="code"><ac:parameter ac:name="language">bash</ac:parameter><ac:parameter ac:name="collapse">false</ac:parameter><ac:plain-text-body><![CDATA[code bash]]></ac:plain-text-body></ac:structured-macro><ac:structured-macro ac:name="code"><ac:parameter ac:name="language">bash</ac:parameter><ac:parameter ac:name="collapse">false</ac:parameter><ac:plain-text-body><![CDATA[with a newline
-]]></ac:plain-text-body></ac:structured-macro><ac:structured-macro ac:name="code"><ac:parameter ac:name="language">unknown</ac:parameter><ac:parameter ac:name="collapse">false</ac:parameter><ac:plain-text-body><![CDATA[unknown code]]></ac:plain-text-body></ac:structured-macro><p>text
-text 2</p>
+]]></ac:plain-text-body></ac:structured-macro><ac:structured-macro ac:name="code"><ac:parameter ac:name="language">unknown</ac:parameter><ac:parameter ac:name="collapse">false</ac:parameter><ac:plain-text-body><![CDATA[unknown code]]></ac:plain-text-body></ac:structured-macro>text
+text 2
 <ac:structured-macro ac:name="code"><ac:parameter ac:name="language">unknown</ac:parameter><ac:parameter ac:name="collapse">false</ac:parameter><ac:plain-text-body><![CDATA[unknown code 2]]></ac:plain-text-body></ac:structured-macro><ac:structured-macro ac:name="code"><ac:parameter ac:name="language">sh</ac:parameter><ac:parameter ac:name="collapse">false</ac:parameter><ac:parameter ac:name="title">A b c</ac:parameter><ac:plain-text-body><![CDATA[no-collapse-title]]></ac:plain-text-body></ac:structured-macro><ac:structured-macro ac:name="code"><ac:parameter ac:name="language">bash</ac:parameter><ac:parameter ac:name="collapse">true</ac:parameter><ac:parameter ac:name="title">A b c</ac:parameter><ac:plain-text-body><![CDATA[collapse-and-title]]></ac:plain-text-body></ac:structured-macro><ac:structured-macro ac:name="code"><ac:parameter ac:name="language">c</ac:parameter><ac:parameter ac:name="collapse">true</ac:parameter><ac:plain-text-body><![CDATA[collapse-no-title]]></ac:plain-text-body></ac:structured-macro><ac:structured-macro ac:name="code"><ac:parameter ac:name="language">nested</ac:parameter><ac:parameter ac:name="collapse">false</ac:parameter><ac:plain-text-body><![CDATA[code
 ``` more code ```
 even more code]]></ac:plain-text-body></ac:structured-macro><ac:structured-macro ac:name="code"><ac:parameter ac:name="language"></ac:parameter><ac:parameter ac:name="collapse">false</ac:parameter><ac:plain-text-body><![CDATA[indented code block
diff --git a/pkg/mark/testdata/issue-64-broken-link-droph1.html b/pkg/mark/testdata/issue-64-broken-link-droph1.html
index 0d39ce8..dca9603 100644
--- a/pkg/mark/testdata/issue-64-broken-link-droph1.html
+++ b/pkg/mark/testdata/issue-64-broken-link-droph1.html
@@ -1,1 +1,1 @@
-<p><a href="Page2#Page2-Releasev71-22-Feb-2018(intern)">v71</a></p>
+<a href="Page2#Page2-Releasev71-22-Feb-2018(intern)">v71</a>
diff --git a/pkg/mark/testdata/issue-64-broken-link-stripnewlines.html b/pkg/mark/testdata/issue-64-broken-link-stripnewlines.html
index 0d39ce8..dca9603 100644
--- a/pkg/mark/testdata/issue-64-broken-link-stripnewlines.html
+++ b/pkg/mark/testdata/issue-64-broken-link-stripnewlines.html
@@ -1,1 +1,1 @@
-<p><a href="Page2#Page2-Releasev71-22-Feb-2018(intern)">v71</a></p>
+<a href="Page2#Page2-Releasev71-22-Feb-2018(intern)">v71</a>
diff --git a/pkg/mark/testdata/issue-64-broken-link.html b/pkg/mark/testdata/issue-64-broken-link.html
index 0d39ce8..dca9603 100644
--- a/pkg/mark/testdata/issue-64-broken-link.html
+++ b/pkg/mark/testdata/issue-64-broken-link.html
@@ -1,1 +1,1 @@
-<p><a href="Page2#Page2-Releasev71-22-Feb-2018(intern)">v71</a></p>
+<a href="Page2#Page2-Releasev71-22-Feb-2018(intern)">v71</a>
diff --git a/pkg/mark/testdata/links-droph1.html b/pkg/mark/testdata/links-droph1.html
index 82fd040..b002880 100644
--- a/pkg/mark/testdata/links-droph1.html
+++ b/pkg/mark/testdata/links-droph1.html
@@ -1,17 +1,17 @@
-<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 <ac:link><ri:page ri:content-title="Page"/><ac:plain-text-link-body><![CDATA[page link]]></ac:plain-text-link-body></ac:link></p>
-<p>Use <ac:link><ri:page ri:content-title="AnotherPage"/><ac:plain-text-link-body><![CDATA[AnotherPage]]></ac:plain-text-link-body></ac:link></p>
-<p>Use <ac:link><ri:page ri:content-title="Another Page"/><ac:plain-text-link-body><![CDATA[Another Page]]></ac:plain-text-link-body></ac:link></p>
-<p>Use <ac:link><ri:page ri:content-title="Page With Space"/><ac:plain-text-link-body><![CDATA[page link with spaces]]></ac:plain-text-link-body></ac:link></p>
-<p><ac:image ac:alt="My Image"><ri:attachment ri:filename="test.png"/></ac:image></p>
-<p><ac:image ac:alt="My External Image"><ri:url ri:value="http://confluence.atlassian.com/images/logo/confluence_48_trans.png?key1=value1&amp;key2=value2"/></ac:image></p>
-<p>Use footnotes link <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></p>
+Use <a href="https://example.com">https://example.com</a>
+Use <ac:rich-text-body>aaa</ac:rich-text-body>
+Use <ac:link><ri:page ri:content-title="Page"/><ac:plain-text-link-body><![CDATA[page link]]></ac:plain-text-link-body></ac:link>
+Use <ac:link><ri:page ri:content-title="AnotherPage"/><ac:plain-text-link-body><![CDATA[AnotherPage]]></ac:plain-text-link-body></ac:link>
+Use <ac:link><ri:page ri:content-title="Another Page"/><ac:plain-text-link-body><![CDATA[Another Page]]></ac:plain-text-link-body></ac:link>
+Use <ac:link><ri:page ri:content-title="Page With Space"/><ac:plain-text-link-body><![CDATA[page link with spaces]]></ac:plain-text-link-body></ac:link>
+<ac:image ac:alt="My Image"><ri:attachment ri:filename="test.png"/></ac:image>
+<ac:image ac:alt="My External Image"><ri:url ri:value="http://confluence.atlassian.com/images/logo/confluence_48_trans.png?key1=value1&amp;key2=value2"/></ac:image>
+Use footnotes link <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>
 <div class="footnotes" role="doc-endnotes">
 <hr />
 <ol>
 <li id="fn:1">
-<p>a footnote link&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
+a footnote link&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>
 </li>
 </ol>
 </div>
diff --git a/pkg/mark/testdata/links-stripnewlines.html b/pkg/mark/testdata/links-stripnewlines.html
index 82fd040..b002880 100644
--- a/pkg/mark/testdata/links-stripnewlines.html
+++ b/pkg/mark/testdata/links-stripnewlines.html
@@ -1,17 +1,17 @@
-<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 <ac:link><ri:page ri:content-title="Page"/><ac:plain-text-link-body><![CDATA[page link]]></ac:plain-text-link-body></ac:link></p>
-<p>Use <ac:link><ri:page ri:content-title="AnotherPage"/><ac:plain-text-link-body><![CDATA[AnotherPage]]></ac:plain-text-link-body></ac:link></p>
-<p>Use <ac:link><ri:page ri:content-title="Another Page"/><ac:plain-text-link-body><![CDATA[Another Page]]></ac:plain-text-link-body></ac:link></p>
-<p>Use <ac:link><ri:page ri:content-title="Page With Space"/><ac:plain-text-link-body><![CDATA[page link with spaces]]></ac:plain-text-link-body></ac:link></p>
-<p><ac:image ac:alt="My Image"><ri:attachment ri:filename="test.png"/></ac:image></p>
-<p><ac:image ac:alt="My External Image"><ri:url ri:value="http://confluence.atlassian.com/images/logo/confluence_48_trans.png?key1=value1&amp;key2=value2"/></ac:image></p>
-<p>Use footnotes link <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></p>
+Use <a href="https://example.com">https://example.com</a>
+Use <ac:rich-text-body>aaa</ac:rich-text-body>
+Use <ac:link><ri:page ri:content-title="Page"/><ac:plain-text-link-body><![CDATA[page link]]></ac:plain-text-link-body></ac:link>
+Use <ac:link><ri:page ri:content-title="AnotherPage"/><ac:plain-text-link-body><![CDATA[AnotherPage]]></ac:plain-text-link-body></ac:link>
+Use <ac:link><ri:page ri:content-title="Another Page"/><ac:plain-text-link-body><![CDATA[Another Page]]></ac:plain-text-link-body></ac:link>
+Use <ac:link><ri:page ri:content-title="Page With Space"/><ac:plain-text-link-body><![CDATA[page link with spaces]]></ac:plain-text-link-body></ac:link>
+<ac:image ac:alt="My Image"><ri:attachment ri:filename="test.png"/></ac:image>
+<ac:image ac:alt="My External Image"><ri:url ri:value="http://confluence.atlassian.com/images/logo/confluence_48_trans.png?key1=value1&amp;key2=value2"/></ac:image>
+Use footnotes link <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>
 <div class="footnotes" role="doc-endnotes">
 <hr />
 <ol>
 <li id="fn:1">
-<p>a footnote link&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
+a footnote link&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>
 </li>
 </ol>
 </div>
diff --git a/pkg/mark/testdata/links.html b/pkg/mark/testdata/links.html
index 82fd040..b002880 100644
--- a/pkg/mark/testdata/links.html
+++ b/pkg/mark/testdata/links.html
@@ -1,17 +1,17 @@
-<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 <ac:link><ri:page ri:content-title="Page"/><ac:plain-text-link-body><![CDATA[page link]]></ac:plain-text-link-body></ac:link></p>
-<p>Use <ac:link><ri:page ri:content-title="AnotherPage"/><ac:plain-text-link-body><![CDATA[AnotherPage]]></ac:plain-text-link-body></ac:link></p>
-<p>Use <ac:link><ri:page ri:content-title="Another Page"/><ac:plain-text-link-body><![CDATA[Another Page]]></ac:plain-text-link-body></ac:link></p>
-<p>Use <ac:link><ri:page ri:content-title="Page With Space"/><ac:plain-text-link-body><![CDATA[page link with spaces]]></ac:plain-text-link-body></ac:link></p>
-<p><ac:image ac:alt="My Image"><ri:attachment ri:filename="test.png"/></ac:image></p>
-<p><ac:image ac:alt="My External Image"><ri:url ri:value="http://confluence.atlassian.com/images/logo/confluence_48_trans.png?key1=value1&amp;key2=value2"/></ac:image></p>
-<p>Use footnotes link <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></p>
+Use <a href="https://example.com">https://example.com</a>
+Use <ac:rich-text-body>aaa</ac:rich-text-body>
+Use <ac:link><ri:page ri:content-title="Page"/><ac:plain-text-link-body><![CDATA[page link]]></ac:plain-text-link-body></ac:link>
+Use <ac:link><ri:page ri:content-title="AnotherPage"/><ac:plain-text-link-body><![CDATA[AnotherPage]]></ac:plain-text-link-body></ac:link>
+Use <ac:link><ri:page ri:content-title="Another Page"/><ac:plain-text-link-body><![CDATA[Another Page]]></ac:plain-text-link-body></ac:link>
+Use <ac:link><ri:page ri:content-title="Page With Space"/><ac:plain-text-link-body><![CDATA[page link with spaces]]></ac:plain-text-link-body></ac:link>
+<ac:image ac:alt="My Image"><ri:attachment ri:filename="test.png"/></ac:image>
+<ac:image ac:alt="My External Image"><ri:url ri:value="http://confluence.atlassian.com/images/logo/confluence_48_trans.png?key1=value1&amp;key2=value2"/></ac:image>
+Use footnotes link <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>
 <div class="footnotes" role="doc-endnotes">
 <hr />
 <ol>
 <li id="fn:1">
-<p>a footnote link&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
+a footnote link&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>
 </li>
 </ol>
 </div>
diff --git a/pkg/mark/testdata/lists-droph1.html b/pkg/mark/testdata/lists-droph1.html
index af27c54..11aa2ca 100644
--- a/pkg/mark/testdata/lists-droph1.html
+++ b/pkg/mark/testdata/lists-droph1.html
@@ -13,7 +13,7 @@
 </ul>
 </li>
 </ul>
-<p>text</p>
+text
 <ul>
 <li>a</li>
 <li>b</li>
diff --git a/pkg/mark/testdata/lists-stripnewlines.html b/pkg/mark/testdata/lists-stripnewlines.html
index af27c54..11aa2ca 100644
--- a/pkg/mark/testdata/lists-stripnewlines.html
+++ b/pkg/mark/testdata/lists-stripnewlines.html
@@ -13,7 +13,7 @@
 </ul>
 </li>
 </ul>
-<p>text</p>
+text
 <ul>
 <li>a</li>
 <li>b</li>
diff --git a/pkg/mark/testdata/lists.html b/pkg/mark/testdata/lists.html
index af27c54..11aa2ca 100644
--- a/pkg/mark/testdata/lists.html
+++ b/pkg/mark/testdata/lists.html
@@ -13,7 +13,7 @@
 </ul>
 </li>
 </ul>
-<p>text</p>
+text
 <ul>
 <li>a</li>
 <li>b</li>
diff --git a/pkg/mark/testdata/macro-include-droph1.html b/pkg/mark/testdata/macro-include-droph1.html
index 8d8ba05..ccf5127 100644
--- a/pkg/mark/testdata/macro-include-droph1.html
+++ b/pkg/mark/testdata/macro-include-droph1.html
@@ -1,6 +1,26 @@
-<p><foo>bar</foo></p>
-<p><ac:structured-macro ac:name="info">
+<foo>bar</foo>
+<ac:structured-macro ac:name="info">
 <ac:parameter ac:name="icon">true</ac:parameter>
 <ac:parameter ac:name="title">Attention</ac:parameter>
 <ac:rich-text-body>This is an info!</ac:rich-text-body>
-</ac:structured-macro></p>
+</ac:structured-macro>
+<ac:structured-macro ac:name="info">
+<ac:parameter ac:name="icon">true</ac:parameter>
+<ac:parameter ac:name="title">Attention</ac:parameter>
+<ac:rich-text-body>
+<table>
+<thead>
+<tr>
+<th>Header 1</th>
+<th>Header 2</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>Cell A</td>
+<td>Cell B</td>
+</tr>
+</tbody>
+</table>
+</ac:rich-text-body>
+</ac:structured-macro>
diff --git a/pkg/mark/testdata/macro-include-stripnewlines.html b/pkg/mark/testdata/macro-include-stripnewlines.html
index 52e4af7..5ad6298 100644
--- a/pkg/mark/testdata/macro-include-stripnewlines.html
+++ b/pkg/mark/testdata/macro-include-stripnewlines.html
@@ -1,2 +1,18 @@
-<p><foo>bar</foo></p>
-<p><ac:structured-macro ac:name="info"> <ac:parameter ac:name="icon">true</ac:parameter> <ac:parameter ac:name="title">Attention</ac:parameter> <ac:rich-text-body>This is an info!</ac:rich-text-body> </ac:structured-macro></p>
+<foo>bar</foo>
+<ac:structured-macro ac:name="info"> <ac:parameter ac:name="icon">true</ac:parameter> <ac:parameter ac:name="title">Attention</ac:parameter> <ac:rich-text-body>This is an info!</ac:rich-text-body> </ac:structured-macro>
+<ac:structured-macro ac:name="info"> <ac:parameter ac:name="icon">true</ac:parameter> <ac:parameter ac:name="title">Attention</ac:parameter> <ac:rich-text-body>
+<table>
+<thead>
+<tr>
+<th>Header 1</th>
+<th>Header 2</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>Cell A</td>
+<td>Cell B</td>
+</tr>
+</tbody>
+</table>
+</ac:rich-text-body> </ac:structured-macro>
diff --git a/pkg/mark/testdata/macro-include.html b/pkg/mark/testdata/macro-include.html
index 8d8ba05..ccf5127 100644
--- a/pkg/mark/testdata/macro-include.html
+++ b/pkg/mark/testdata/macro-include.html
@@ -1,6 +1,26 @@
-<p><foo>bar</foo></p>
-<p><ac:structured-macro ac:name="info">
+<foo>bar</foo>
+<ac:structured-macro ac:name="info">
 <ac:parameter ac:name="icon">true</ac:parameter>
 <ac:parameter ac:name="title">Attention</ac:parameter>
 <ac:rich-text-body>This is an info!</ac:rich-text-body>
-</ac:structured-macro></p>
+</ac:structured-macro>
+<ac:structured-macro ac:name="info">
+<ac:parameter ac:name="icon">true</ac:parameter>
+<ac:parameter ac:name="title">Attention</ac:parameter>
+<ac:rich-text-body>
+<table>
+<thead>
+<tr>
+<th>Header 1</th>
+<th>Header 2</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>Cell A</td>
+<td>Cell B</td>
+</tr>
+</tbody>
+</table>
+</ac:rich-text-body>
+</ac:structured-macro>
diff --git a/pkg/mark/testdata/macro-include.md b/pkg/mark/testdata/macro-include.md
index c8d3d89..84123d1 100644
--- a/pkg/mark/testdata/macro-include.md
+++ b/pkg/mark/testdata/macro-include.md
@@ -4,4 +4,15 @@
 <ac:parameter ac:name="icon">true</ac:parameter>
 <ac:parameter ac:name="title">Attention</ac:parameter>
 <ac:rich-text-body>This is an info!</ac:rich-text-body>
-</ac:structured-macro>
\ No newline at end of file
+</ac:structured-macro>
+
+<ac:structured-macro ac:name="info">
+<ac:parameter ac:name="icon">true</ac:parameter>
+<ac:parameter ac:name="title">Attention</ac:parameter>
+<ac:rich-text-body>
+| Header 1 | Header 2 |
+|---|---|
+| Cell A | Cell B |
+
+</ac:rich-text-body>
+</ac:structured-macro>
diff --git a/pkg/mark/testdata/newlines-droph1.html b/pkg/mark/testdata/newlines-droph1.html
index b97e510..272fe20 100644
--- a/pkg/mark/testdata/newlines-droph1.html
+++ b/pkg/mark/testdata/newlines-droph1.html
@@ -1,10 +1,10 @@
-<p>one-1
-one-2</p>
-<p>two-1</p>
-<p>two-2</p>
-<p>three-1</p>
-<p>three-2</p>
-<p>space-1
-space-2</p>
-<p>2space-1<br />
-2space-2</p>
+one-1
+one-2
+two-1
+two-2
+three-1
+three-2
+space-1
+space-2
+2space-1<br />
+2space-2
diff --git a/pkg/mark/testdata/newlines-stripnewlines.html b/pkg/mark/testdata/newlines-stripnewlines.html
index 2fd4dc0..cca4996 100644
--- a/pkg/mark/testdata/newlines-stripnewlines.html
+++ b/pkg/mark/testdata/newlines-stripnewlines.html
@@ -1,8 +1,8 @@
-<p>one-1 one-2</p>
-<p>two-1</p>
-<p>two-2</p>
-<p>three-1</p>
-<p>three-2</p>
-<p>space-1 space-2</p>
-<p>2space-1<br />
-2space-2</p>
+one-1 one-2
+two-1
+two-2
+three-1
+three-2
+space-1 space-2
+2space-1<br />
+2space-2
diff --git a/pkg/mark/testdata/newlines.html b/pkg/mark/testdata/newlines.html
index b97e510..272fe20 100644
--- a/pkg/mark/testdata/newlines.html
+++ b/pkg/mark/testdata/newlines.html
@@ -1,10 +1,10 @@
-<p>one-1
-one-2</p>
-<p>two-1</p>
-<p>two-2</p>
-<p>three-1</p>
-<p>three-2</p>
-<p>space-1
-space-2</p>
-<p>2space-1<br />
-2space-2</p>
+one-1
+one-2
+two-1
+two-2
+three-1
+three-2
+space-1
+space-2
+2space-1<br />
+2space-2
diff --git a/pkg/mark/testdata/pagelayout-droph1.html b/pkg/mark/testdata/pagelayout-droph1.html
index a244202..23f17d5 100644
--- a/pkg/mark/testdata/pagelayout-droph1.html
+++ b/pkg/mark/testdata/pagelayout-droph1.html
@@ -1,18 +1,18 @@
 <ac:layout>
 <ac:layout-section ac:type="three_with_sidebars">
 <ac:layout-cell>
-<p>More Content</p>
+More Content
 </ac:layout-cell>
 <ac:layout-cell>
-<p>More Content</p>
+More Content
 </ac:layout-cell>
 <ac:layout-cell>
-<p>Even More Content</p>
+Even More Content
 </ac:layout-cell>
 </ac:layout-section>
 <ac:layout-section ac:type="single">
 <ac:layout-cell>
-<p>Still More Content</p>
+Still More Content
 </ac:layout-cell>
 </ac:layout-section>
 </ac:layout>
diff --git a/pkg/mark/testdata/pagelayout-stripnewlines.html b/pkg/mark/testdata/pagelayout-stripnewlines.html
index a244202..23f17d5 100644
--- a/pkg/mark/testdata/pagelayout-stripnewlines.html
+++ b/pkg/mark/testdata/pagelayout-stripnewlines.html
@@ -1,18 +1,18 @@
 <ac:layout>
 <ac:layout-section ac:type="three_with_sidebars">
 <ac:layout-cell>
-<p>More Content</p>
+More Content
 </ac:layout-cell>
 <ac:layout-cell>
-<p>More Content</p>
+More Content
 </ac:layout-cell>
 <ac:layout-cell>
-<p>Even More Content</p>
+Even More Content
 </ac:layout-cell>
 </ac:layout-section>
 <ac:layout-section ac:type="single">
 <ac:layout-cell>
-<p>Still More Content</p>
+Still More Content
 </ac:layout-cell>
 </ac:layout-section>
 </ac:layout>
diff --git a/pkg/mark/testdata/pagelayout.html b/pkg/mark/testdata/pagelayout.html
index a244202..23f17d5 100644
--- a/pkg/mark/testdata/pagelayout.html
+++ b/pkg/mark/testdata/pagelayout.html
@@ -1,18 +1,18 @@
 <ac:layout>
 <ac:layout-section ac:type="three_with_sidebars">
 <ac:layout-cell>
-<p>More Content</p>
+More Content
 </ac:layout-cell>
 <ac:layout-cell>
-<p>More Content</p>
+More Content
 </ac:layout-cell>
 <ac:layout-cell>
-<p>Even More Content</p>
+Even More Content
 </ac:layout-cell>
 </ac:layout-section>
 <ac:layout-section ac:type="single">
 <ac:layout-cell>
-<p>Still More Content</p>
+Still More Content
 </ac:layout-cell>
 </ac:layout-section>
 </ac:layout>
diff --git a/pkg/mark/testdata/quotes-droph1.html b/pkg/mark/testdata/quotes-droph1.html
index d8fdcdf..e90782a 100644
--- a/pkg/mark/testdata/quotes-droph1.html
+++ b/pkg/mark/testdata/quotes-droph1.html
@@ -1,19 +1,19 @@
 <h2 id="first-heading">First Heading</h2>
 <ac:structured-macro ac:name="note"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
-<p><strong>NOTES:</strong></p>
+<strong>NOTES:</strong>
 <ol>
 <li>Note number one</li>
 <li>Note number two</li>
 </ol>
 <blockquote>
-<p>a
-b</p>
+a
+b
 </blockquote>
-<p><strong>Warn (Should not be picked as blockquote type)</strong></p>
+<strong>Warn (Should not be picked as blockquote type)</strong>
 </ac:rich-text-body></ac:structured-macro>
 <h2 id="second-heading">Second Heading</h2>
 <ac:structured-macro ac:name="warn"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
-<p><strong>Warn</strong></p>
+<strong>Warn</strong>
 <ul>
 <li>Warn bullet 1</li>
 <li>Warn bullet 2</li>
@@ -26,9 +26,9 @@ that runs long</li>
 <h2 id="third-heading">Third Heading</h2>
 <ac:structured-macro ac:name="info"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
 <!-- Info -->
-<p>Test</p>
+Test
 </ac:rich-text-body></ac:structured-macro>
 <h2 id="simple-blockquote">Simple Blockquote</h2>
 <blockquote>
-<p>This paragraph is a simple blockquote</p>
+This paragraph is a simple blockquote
 </blockquote>
diff --git a/pkg/mark/testdata/quotes-stripnewlines.html b/pkg/mark/testdata/quotes-stripnewlines.html
index 7a43019..d0520a9 100644
--- a/pkg/mark/testdata/quotes-stripnewlines.html
+++ b/pkg/mark/testdata/quotes-stripnewlines.html
@@ -1,19 +1,19 @@
 <h1 id="main-heading">Main Heading</h1>
 <h2 id="first-heading">First Heading</h2>
 <ac:structured-macro ac:name="note"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
-<p><strong>NOTES:</strong></p>
+<strong>NOTES:</strong>
 <ol>
 <li>Note number one</li>
 <li>Note number two</li>
 </ol>
 <blockquote>
-<p>a b</p>
+a b
 </blockquote>
-<p><strong>Warn (Should not be picked as blockquote type)</strong></p>
+<strong>Warn (Should not be picked as blockquote type)</strong>
 </ac:rich-text-body></ac:structured-macro>
 <h2 id="second-heading">Second Heading</h2>
 <ac:structured-macro ac:name="warn"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
-<p><strong>Warn</strong></p>
+<strong>Warn</strong>
 <ul>
 <li>Warn bullet 1</li>
 <li>Warn bullet 2</li>
@@ -25,9 +25,9 @@
 <h2 id="third-heading">Third Heading</h2>
 <ac:structured-macro ac:name="info"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
 <!-- Info -->
-<p>Test</p>
+Test
 </ac:rich-text-body></ac:structured-macro>
 <h2 id="simple-blockquote">Simple Blockquote</h2>
 <blockquote>
-<p>This paragraph is a simple blockquote</p>
+This paragraph is a simple blockquote
 </blockquote>
diff --git a/pkg/mark/testdata/quotes.html b/pkg/mark/testdata/quotes.html
index c1519c7..957e7eb 100644
--- a/pkg/mark/testdata/quotes.html
+++ b/pkg/mark/testdata/quotes.html
@@ -1,20 +1,20 @@
 <h1 id="main-heading">Main Heading</h1>
 <h2 id="first-heading">First Heading</h2>
 <ac:structured-macro ac:name="note"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
-<p><strong>NOTES:</strong></p>
+<strong>NOTES:</strong>
 <ol>
 <li>Note number one</li>
 <li>Note number two</li>
 </ol>
 <blockquote>
-<p>a
-b</p>
+a
+b
 </blockquote>
-<p><strong>Warn (Should not be picked as blockquote type)</strong></p>
+<strong>Warn (Should not be picked as blockquote type)</strong>
 </ac:rich-text-body></ac:structured-macro>
 <h2 id="second-heading">Second Heading</h2>
 <ac:structured-macro ac:name="warn"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
-<p><strong>Warn</strong></p>
+<strong>Warn</strong>
 <ul>
 <li>Warn bullet 1</li>
 <li>Warn bullet 2</li>
@@ -27,9 +27,9 @@ that runs long</li>
 <h2 id="third-heading">Third Heading</h2>
 <ac:structured-macro ac:name="info"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
 <!-- Info -->
-<p>Test</p>
+Test
 </ac:rich-text-body></ac:structured-macro>
 <h2 id="simple-blockquote">Simple Blockquote</h2>
 <blockquote>
-<p>This paragraph is a simple blockquote</p>
+This paragraph is a simple blockquote
 </blockquote>
diff --git a/pkg/mark/testdata/tags-droph1.html b/pkg/mark/testdata/tags-droph1.html
index a5161db..5c3f317 100644
--- a/pkg/mark/testdata/tags-droph1.html
+++ b/pkg/mark/testdata/tags-droph1.html
@@ -1,6 +1,6 @@
-<p><b>bold</b>
-<strong>bold</strong></p>
-<p><i>vitalik</i>
-<em>vitalik</em></p>
-<p>
strikethrough

-<del>strikethrough</del></p>
+<b>bold</b>
+<strong>bold</strong>
+<i>vitalik</i>
+<em>vitalik</em>
+
strikethrough

+<del>strikethrough</del>
diff --git a/pkg/mark/testdata/tags-stripnewlines.html b/pkg/mark/testdata/tags-stripnewlines.html
index cc0698b..85c1878 100644
--- a/pkg/mark/testdata/tags-stripnewlines.html
+++ b/pkg/mark/testdata/tags-stripnewlines.html
@@ -1,3 +1,3 @@
-<p><b>bold</b> <strong>bold</strong></p>
-<p><i>vitalik</i> <em>vitalik</em></p>
-<p>
strikethrough
 <del>strikethrough</del></p>
+<b>bold</b> <strong>bold</strong>
+<i>vitalik</i> <em>vitalik</em>
+
strikethrough
 <del>strikethrough</del>
diff --git a/pkg/mark/testdata/tags.html b/pkg/mark/testdata/tags.html
index a5161db..5c3f317 100644
--- a/pkg/mark/testdata/tags.html
+++ b/pkg/mark/testdata/tags.html
@@ -1,6 +1,6 @@
-<p><b>bold</b>
-<strong>bold</strong></p>
-<p><i>vitalik</i>
-<em>vitalik</em></p>
-<p>
strikethrough

-<del>strikethrough</del></p>
+<b>bold</b>
+<strong>bold</strong>
+<i>vitalik</i>
+<em>vitalik</em>
+
strikethrough

+<del>strikethrough</del>