Compare commits

...

9 Commits

Author SHA1 Message Date
dependabot[bot]
ccc596c4eb Bump github.com/bmatcuk/doublestar/v4 from 4.8.1 to 4.9.0
Bumps [github.com/bmatcuk/doublestar/v4](https://github.com/bmatcuk/doublestar) from 4.8.1 to 4.9.0.
- [Release notes](https://github.com/bmatcuk/doublestar/releases)
- [Commits](https://github.com/bmatcuk/doublestar/compare/v4.8.1...v4.9.0)

---
updated-dependencies:
- dependency-name: github.com/bmatcuk/doublestar/v4
  dependency-version: 4.9.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-14 23:53:25 +02:00
dependabot[bot]
0841a6b370 Bump github.com/dreampuf/mermaid.go from 0.0.28 to 0.0.29
Bumps [github.com/dreampuf/mermaid.go](https://github.com/dreampuf/mermaid.go) from 0.0.28 to 0.0.29.
- [Release notes](https://github.com/dreampuf/mermaid.go/releases)
- [Commits](https://github.com/dreampuf/mermaid.go/compare/v0.0.28...v0.0.29)

---
updated-dependencies:
- dependency-name: github.com/dreampuf/mermaid.go
  dependency-version: 0.0.29
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-11 21:38:01 +02:00
Manuel Rüger
4f1d68bfee Document admonitions feature 2025-07-11 21:32:24 +02:00
dependabot[bot]
01a6bc7af2 Bump golang.org/x/tools from 0.34.0 to 0.35.0
Bumps [golang.org/x/tools](https://github.com/golang/tools) from 0.34.0 to 0.35.0.
- [Release notes](https://github.com/golang/tools/releases)
- [Commits](https://github.com/golang/tools/compare/v0.34.0...v0.35.0)

---
updated-dependencies:
- dependency-name: golang.org/x/tools
  dependency-version: 0.35.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-11 21:32:15 +02:00
dependabot[bot]
eae6fc0d90 Bump golang from 1.24.4 to 1.24.5
Bumps golang from 1.24.4 to 1.24.5.

---
updated-dependencies:
- dependency-name: golang
  dependency-version: 1.24.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-11 10:43:44 +02:00
dependabot[bot]
c54d458dba Bump github.com/dreampuf/mermaid.go from 0.0.27 to 0.0.28
Bumps [github.com/dreampuf/mermaid.go](https://github.com/dreampuf/mermaid.go) from 0.0.27 to 0.0.28.
- [Release notes](https://github.com/dreampuf/mermaid.go/releases)
- [Commits](https://github.com/dreampuf/mermaid.go/compare/v0.0.27...v0.0.28)

---
updated-dependencies:
- dependency-name: github.com/dreampuf/mermaid.go
  dependency-version: 0.0.28
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-20 20:54:58 +02:00
Paul.Glesmann
32490b2c90 feat: add Support for converting Material for MkDocs Admonitions to Confluence Info Panels
chore: add test files

fix: add tests for stripnewline and droph1

chore: rename Admontion to MkDocsAdmonition, remove annoying comments

fix: import parser instead of copying the file

chore: rename mkDocs renderer function

fix: fix bug and pipeline

feat: add Support for converting Material for MkDocs Admonitions to Confluence Info Panels

fix: add tests for stripnewline and droph1

chore: rename Admontion to MkDocsAdmonition, remove annoying comments

fix: import parser instead of copying the file

chore: rename mkDocs renderer function

fix: fix bug and pipeline

chore: remove test for droph1 and stripNewLines

fix: add admonitions to StripNewLines and dropH1 tests

feat: add Support for converting Material for MkDocs Admonitions to Confluence Info Panels

fix: add tests for stripnewline and droph1

chore: rename Admontion to MkDocsAdmonition, remove annoying comments

fix: import parser instead of copying the file

chore: rename mkDocs renderer function

fix: fix bug and pipeline

feat: add Support for converting Material for MkDocs Admonitions to Confluence Info Panels

chore: rename Admontion to MkDocsAdmonition, remove annoying comments

fix: import parser instead of copying the file

chore: rename mkDocs renderer function

fix: fix bug and pipeline

chore: remove test for droph1 and stripNewLines

fix: add admonitions to StripNewLines and dropH1 tests

feat: add mkdocsadmonition as opt-in renderer and parser

fix: fix unit tests
2025-06-18 11:14:52 +02:00
dependabot[bot]
242cebb5ee Bump github.com/urfave/cli/v3 from 3.3.3 to 3.3.8
Bumps [github.com/urfave/cli/v3](https://github.com/urfave/cli) from 3.3.3 to 3.3.8.
- [Release notes](https://github.com/urfave/cli/releases)
- [Changelog](https://github.com/urfave/cli/blob/main/docs/CHANGELOG.md)
- [Commits](https://github.com/urfave/cli/compare/v3.3.3...v3.3.8)

---
updated-dependencies:
- dependency-name: github.com/urfave/cli/v3
  dependency-version: 3.3.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-15 20:47:09 +02:00
Manuel Rüger
c16386abb2 goreleaser: Fix path 2025-06-12 13:40:43 +02:00
13 changed files with 534 additions and 33 deletions

View File

@ -55,7 +55,7 @@ brews:
install: |
bin.install "mark"
generate_completions_from_executable("mark", "completion")
generate_completions_from_executable(bin/"mark", "completion")
test: |
system "#{bin}/mark", "version"

View File

@ -1,4 +1,4 @@
FROM golang:1.24.4 AS builder
FROM golang:1.24.5 AS builder
ENV GOPATH="/go"
WORKDIR /go/src/github.com/kovetskiy/mark
COPY / .

View File

@ -741,6 +741,16 @@ All you need is a codeblock marked as "d2".
X -> Y
```
### MkDocs' Admonitions
Optionally you can enable mkdocs-style [Admonitions](https://squidfunk.github.io/mkdocs-material/reference/admonitions/) via `--features="mkdocsadmonitions"`.
When enabled, this renders note, warning, tip, info admonitions as Confluence alerts.
```markdown
!!! note
```
## Installation
### Homebrew

17
go.mod
View File

@ -5,20 +5,21 @@ go 1.24.0
toolchain go1.24.2
require (
github.com/bmatcuk/doublestar/v4 v4.8.1
github.com/bmatcuk/doublestar/v4 v4.9.0
github.com/chromedp/cdproto v0.0.0-20250403032234-65de8f5d025b
github.com/chromedp/chromedp v0.13.6
github.com/dreampuf/mermaid.go v0.0.27
github.com/chromedp/chromedp v0.13.7
github.com/dreampuf/mermaid.go v0.0.29
github.com/kovetskiy/gopencils v0.0.0-20250404051442-0b776066936a
github.com/kovetskiy/lorg v1.2.1-0.20240830111423-ba4fe8b6f7c4
github.com/reconquest/karma-go v1.5.0
github.com/reconquest/pkg v1.3.1-0.20240901105413-68c2adbf2b64
github.com/reconquest/regexputil-go v0.0.0-20160905154124-38573e70c1f4
github.com/stefanfritsch/goldmark-admonitions v1.1.1
github.com/stretchr/testify v1.10.0
github.com/urfave/cli-altsrc/v3 v3.0.1
github.com/urfave/cli/v3 v3.3.3
github.com/urfave/cli/v3 v3.3.8
github.com/yuin/goldmark v1.7.12
golang.org/x/tools v0.34.0
golang.org/x/tools v0.35.0
gopkg.in/yaml.v3 v3.0.1
oss.terrastruct.com/d2 v0.7.0
oss.terrastruct.com/util-go v0.0.0-20250213174338-243d8661088a
@ -49,9 +50,9 @@ require (
github.com/zazab/zhash v0.0.0-20221031090444-2b0d50417446 // indirect
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
golang.org/x/image v0.20.0 // indirect
golang.org/x/net v0.41.0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/text v0.26.0 // indirect
golang.org/x/net v0.42.0 // indirect
golang.org/x/sys v0.34.0 // indirect
golang.org/x/text v0.27.0 // indirect
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
gonum.org/v1/plot v0.14.0 // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect

34
go.sum
View File

@ -18,14 +18,14 @@ github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss=
github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
github.com/bmatcuk/doublestar/v4 v4.8.1 h1:54Bopc5c2cAvhLRAzqOGCYHYyhcDHsFF4wWIR5wKP38=
github.com/bmatcuk/doublestar/v4 v4.8.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
github.com/bmatcuk/doublestar/v4 v4.9.0 h1:DBvuZxjdKkRP/dr4GVV4w2fnmrk5Hxc90T51LZjv0JA=
github.com/bmatcuk/doublestar/v4 v4.9.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
github.com/campoy/embedmd v1.0.0 h1:V4kI2qTJJLf4J29RzI/MAt2c3Bl4dQSYPuflzwFH2hY=
github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8=
github.com/chromedp/cdproto v0.0.0-20250403032234-65de8f5d025b h1:jJmiCljLNTaq/O1ju9Bzz2MPpFlmiTn0F7LwCoeDZVw=
github.com/chromedp/cdproto v0.0.0-20250403032234-65de8f5d025b/go.mod h1:NItd7aLkcfOA/dcMXvl8p1u+lQqioRMq/SqDp71Pb/k=
github.com/chromedp/chromedp v0.13.6 h1:xlNunMyzS5bu3r/QKrb3fzX6ow3WBQ6oao+J65PGZxk=
github.com/chromedp/chromedp v0.13.6/go.mod h1:h8GPP6ZtLMLsU8zFbTcb7ZDGCvCy8j/vRoFmRltQx9A=
github.com/chromedp/chromedp v0.13.7 h1:vt+mslxscyvUr58eC+6DLSeeo74jpV/HI2nWetjv/W4=
github.com/chromedp/chromedp v0.13.7/go.mod h1:h8GPP6ZtLMLsU8zFbTcb7ZDGCvCy8j/vRoFmRltQx9A=
github.com/chromedp/sysutil v1.1.0 h1:PUFNv5EcprjqXZD9nJb9b/c9ibAbxiYo4exNWZyipwM=
github.com/chromedp/sysutil v1.1.0/go.mod h1:WiThHUdltqCNKGc4gaU50XgYjwjYIhKWoHGPTUfWTJ8=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
@ -35,8 +35,8 @@ github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yA
github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/dop251/goja v0.0.0-20240927123429-241b342198c2 h1:Ux9RXuPQmTB4C1MKagNLme0krvq8ulewfor+ORO/QL4=
github.com/dop251/goja v0.0.0-20240927123429-241b342198c2/go.mod h1:MxLav0peU43GgvwVgNbLAj1s/bSGboKkhuULvq/7hx4=
github.com/dreampuf/mermaid.go v0.0.27 h1:uriWHpcc4clTaAUdJqpyDzyGvAZumeLb61n2VBxc0ZQ=
github.com/dreampuf/mermaid.go v0.0.27/go.mod h1:13PeW5y49ouLGlP3RdZm6ke+lQIcz3z7rdVoqRkt5hY=
github.com/dreampuf/mermaid.go v0.0.29 h1:zfgm/dQupk5gKjstXKQI/o+itgOkHxeXbbtIHpVfd98=
github.com/dreampuf/mermaid.go v0.0.29/go.mod h1:tgTP8Znzkj9wmrX1G8dd4zqI1VUk1n1wkqjAk/E8Fpc=
github.com/go-fonts/liberation v0.3.1 h1:9RPT2NhUpxQ7ukUvz3jeUckmN42T9D9TpjtQcqK/ceM=
github.com/go-fonts/liberation v0.3.1/go.mod h1:jdJ+cqF+F4SUL2V+qxBth8fvBpBDS7yloUL5Fi8GTGY=
github.com/go-json-experiment/json v0.0.0-20250211171154-1ae217ad3535 h1:yE7argOs92u+sSCRgqqe6eF+cDaVhSPlioy1UkA0p/w=
@ -90,12 +90,14 @@ github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/stefanfritsch/goldmark-admonitions v1.1.1 h1:SncsICdQrIYYaq02Ta+zyc9gNmMfYqQH2qwLSCJYxA4=
github.com/stefanfritsch/goldmark-admonitions v1.1.1/go.mod h1:cOZK5O0gE6eWfpxTdjGUmeONW2IL9j3Zujv3KlZWlLo=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/urfave/cli-altsrc/v3 v3.0.1 h1:v+gHk59syLk8ao9rYybZs43+D5ut/gzj0omqQ1XYl8k=
github.com/urfave/cli-altsrc/v3 v3.0.1/go.mod h1:8UtsKKcxFVzvaoySFPfvQOk413T+IXJhaCWyyoPW3yM=
github.com/urfave/cli/v3 v3.3.3 h1:byCBaVdIXuLPIDm5CYZRVG6NvT7tv1ECqdU4YzlEa3I=
github.com/urfave/cli/v3 v3.3.3/go.mod h1:FJSKtM/9AiiTOJL4fJ6TbMUkxBXn7GO9guZqoZtpYpo=
github.com/urfave/cli/v3 v3.3.8 h1:BzolUExliMdet9NlJ/u4m5vHSotJ3PzEqSAZ1oPMa/E=
github.com/urfave/cli/v3 v3.3.8/go.mod h1:FJSKtM/9AiiTOJL4fJ6TbMUkxBXn7GO9guZqoZtpYpo=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/goldmark v1.7.12 h1:YwGP/rrea2/CnCtUHgjuolG/PnMxdQtPMO5PvaE2/nY=
github.com/yuin/goldmark v1.7.12/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
@ -116,8 +118,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -129,8 +131,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@ -140,14 +142,14 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=
golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY=
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=

View File

@ -2,6 +2,7 @@ package mark
import (
"bytes"
"slices"
"github.com/kovetskiy/mark/attachment"
cparser "github.com/kovetskiy/mark/parser"
@ -9,6 +10,7 @@ import (
"github.com/kovetskiy/mark/stdlib"
"github.com/kovetskiy/mark/types"
"github.com/reconquest/pkg/log"
mkDocsParser "github.com/stefanfritsch/goldmark-admonitions"
"github.com/yuin/goldmark"
"github.com/yuin/goldmark/extension"
@ -56,6 +58,18 @@ func (c *ConfluenceExtension) Extend(m goldmark.Markdown) {
util.Prioritized(crenderer.NewConfluenceLinkRenderer(), 100),
))
if slices.Contains(c.MarkConfig.Features, "mkdocsadmonitions") {
m.Parser().AddOptions(
parser.WithBlockParsers(
util.Prioritized(mkDocsParser.NewAdmonitionParser(), 100),
),
)
m.Renderer().AddOptions(renderer.WithNodeRenderers(
util.Prioritized(crenderer.NewConfluenceMkDocsAdmonitionRenderer(), 100),
))
}
m.Parser().AddOptions(parser.WithInlineParsers(
// Must be registered with a higher priority than goldmark's linkParser to make sure goldmark doesn't parse
// the <ac:*/> tags.

View File

@ -63,7 +63,7 @@ func TestCompileMarkdown(t *testing.T) {
D2Scale: 1.0,
DropFirstH1: false,
StripNewlines: false,
Features: []string{},
Features: []string{"mkdocsadmonitions"},
}
actual, _ := mark.CompileMarkdown(markdown, lib, filename, cfg)
@ -93,7 +93,7 @@ func TestCompileMarkdownDropH1(t *testing.T) {
}
var variant string
switch filename {
case "testdata/quotes.md", "testdata/header.md":
case "testdata/quotes.md", "testdata/header.md", "testdata/admonitions.md":
variant = "-droph1"
default:
variant = ""
@ -106,7 +106,7 @@ func TestCompileMarkdownDropH1(t *testing.T) {
D2Scale: 1.0,
DropFirstH1: true,
StripNewlines: false,
Features: []string{},
Features: []string{"mkdocsadmonitions"},
}
actual, _ := mark.CompileMarkdown(markdown, lib, filename, cfg)
@ -137,7 +137,7 @@ func TestCompileMarkdownStripNewlines(t *testing.T) {
}
var variant string
switch filename {
case "testdata/quotes.md", "testdata/codes.md", "testdata/newlines.md", "testdata/macro-include.md":
case "testdata/quotes.md", "testdata/codes.md", "testdata/newlines.md", "testdata/macro-include.md", "testdata/admonitions.md":
variant = "-stripnewlines"
default:
variant = ""
@ -151,7 +151,7 @@ func TestCompileMarkdownStripNewlines(t *testing.T) {
D2Scale: 1.0,
DropFirstH1: false,
StripNewlines: true,
Features: []string{},
Features: []string{"mkdocsadmonitions"},
}
actual, _ := mark.CompileMarkdown(markdown, lib, filename, cfg)

View File

@ -0,0 +1,150 @@
package renderer
import (
"fmt"
parser "github.com/stefanfritsch/goldmark-admonitions"
"github.com/yuin/goldmark/ast"
"github.com/yuin/goldmark/renderer"
"github.com/yuin/goldmark/renderer/html"
"github.com/yuin/goldmark/util"
)
// HeadingAttributeFilter defines attribute names which heading elements can have
var MkDocsAdmonitionAttributeFilter = html.GlobalAttributeFilter
// A Renderer struct is an implementation of renderer.NodeRenderer that renders
// nodes as (X)HTML.
type ConfluenceMkDocsAdmonitionRenderer struct {
html.Config
LevelMap MkDocsAdmonitionLevelMap
}
// NewConfluenceRenderer creates a new instance of the ConfluenceRenderer
func NewConfluenceMkDocsAdmonitionRenderer(opts ...html.Option) renderer.NodeRenderer {
return &ConfluenceMkDocsAdmonitionRenderer{
Config: html.NewConfig(),
LevelMap: nil,
}
}
// RegisterFuncs implements NodeRenderer.RegisterFuncs.
func (r *ConfluenceMkDocsAdmonitionRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) {
reg.Register(parser.KindAdmonition, r.renderMkDocsAdmonition)
}
// Define MkDocsAdmonitionType enum
type MkDocsAdmonitionType int
const (
AInfo MkDocsAdmonitionType = iota
ANote
AWarn
ATip
ANone
)
func (t MkDocsAdmonitionType) String() string {
return []string{"info", "note", "warning", "tip", "none"}[t]
}
type MkDocsAdmonitionLevelMap map[ast.Node]int
func (m MkDocsAdmonitionLevelMap) Level(node ast.Node) int {
return m[node]
}
func ParseMkDocsAdmonitionType(node ast.Node) MkDocsAdmonitionType {
n, ok := node.(*parser.Admonition)
if !ok {
return ANone
}
switch string(n.AdmonitionClass) {
case "info":
return AInfo
case "note":
return ANote
case "warning":
return AWarn
case "tip":
return ATip
default:
return ANone
}
}
// GenerateMkDocsAdmonitionLevel walks a given node and returns a map of blockquote levels
func GenerateMkDocsAdmonitionLevel(someNode ast.Node) MkDocsAdmonitionLevelMap {
// We define state variable that tracks BlockQuote level while we walk the tree
admonitionLevel := 0
AdmonitionLevelMap := make(map[ast.Node]int)
rootNode := someNode
for rootNode.Parent() != nil {
rootNode = rootNode.Parent()
}
_ = ast.Walk(rootNode, func(node ast.Node, entering bool) (ast.WalkStatus, error) {
if node.Kind() == ast.KindBlockquote && entering {
AdmonitionLevelMap[node] = admonitionLevel
admonitionLevel += 1
}
if node.Kind() == ast.KindBlockquote && !entering {
admonitionLevel -= 1
}
return ast.WalkContinue, nil
})
return AdmonitionLevelMap
}
// renderBlockQuote will render a BlockQuote
func (r *ConfluenceMkDocsAdmonitionRenderer) renderMkDocsAdmonition(writer util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
// Initialize BlockQuote level map
n := node.(*parser.Admonition)
if r.LevelMap == nil {
r.LevelMap = GenerateMkDocsAdmonitionLevel(node)
}
admonitionType := ParseMkDocsAdmonitionType(node)
admonitionLevel := r.LevelMap.Level(node)
if admonitionLevel == 0 && entering && admonitionType != ANone {
prefix := fmt.Sprintf("<ac:structured-macro ac:name=\"%s\"><ac:parameter ac:name=\"icon\">true</ac:parameter><ac:rich-text-body>\n", admonitionType)
if _, err := writer.Write([]byte(prefix)); err != nil {
return ast.WalkStop, err
}
if string(n.Title) != "" {
titleHTML := fmt.Sprintf("<p><strong>%s</strong></p>\n", string(n.Title))
if _, err := writer.Write([]byte(titleHTML)); err != nil {
return ast.WalkStop, err
}
}
return ast.WalkContinue, nil
}
if admonitionLevel == 0 && !entering && admonitionType != ANone {
suffix := "</ac:rich-text-body></ac:structured-macro>\n"
if _, err := writer.Write([]byte(suffix)); err != nil {
return ast.WalkStop, err
}
return ast.WalkContinue, nil
}
return r.renderMkDocsAdmon(writer, source, node, entering)
}
func (r *ConfluenceMkDocsAdmonitionRenderer) renderMkDocsAdmon(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
n := node.(*parser.Admonition)
if entering {
if n.Attributes() != nil {
_, _ = w.WriteString("<blockquote")
html.RenderAttributes(w, n, MkDocsAdmonitionAttributeFilter)
_ = w.WriteByte('>')
} else {
_, _ = w.WriteString("<blockquote>\n")
}
} else {
_, _ = w.WriteString("</blockquote>\n")
}
return ast.WalkContinue, nil
}

83
testdata/admonitions-droph1.html vendored Normal file
View File

@ -0,0 +1,83 @@
<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>
<ol>
<li>Note number one</li>
<li>Note number two</li>
</ol>
<ac:structured-macro ac:name="note"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
<p>a<br />
b</p>
</ac:rich-text-body></ac:structured-macro>
<p><strong>Warn (Should not be picked as blockquote type)</strong></p>
</ac:rich-text-body></ac:structured-macro>
<h2 id="Second-Heading">Second Heading</h2>
<ac:structured-macro ac:name="warning"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
<p><strong>"Warn"</strong></p>
<ul>
<li>Warn bullet 1</li>
<li>Warn bullet 2</li>
</ul>
</ac:rich-text-body></ac:structured-macro>
<ul>
<li>Regular list
that runs long</li>
</ul>
<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>
<p>Test</p>
</ac:rich-text-body></ac:structured-macro>
<h2 id="Fourth-Heading---Warn-should-not-get-picked-as-block-quote">Fourth Heading - Warn should not get picked as block quote</h2>
<ac:structured-macro ac:name="tip"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
<p><strong>"TIP:"</strong></p>
<ol>
<li>Note number one</li>
<li>Note number two</li>
</ol>
<ac:structured-macro ac:name="tip"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
<p>a<br />
b</p>
</ac:rich-text-body></ac:structured-macro>
<p><strong>Warn (Should not be picked as blockquote type)</strong></p>
</ac:rich-text-body></ac:structured-macro>
<h2 id="Simple-Blockquote">Simple Blockquote</h2>
<blockquote>
<p>This paragraph is a simple blockquote</p>
</blockquote>
<h2 id="GH-Alerts-Heading">GH Alerts Heading</h2>
<h3 id="Note-Type-Alert-Heading">Note Type Alert Heading</h3>
<ac:structured-macro ac:name="note"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
<ul>
<li>Note bullet 1</li>
<li>Note bullet 2</li>
</ul>
</ac:rich-text-body></ac:structured-macro>
<h3 id="Tip-Type-Alert-Heading">Tip Type Alert Heading</h3>
<ac:structured-macro ac:name="tip"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
<ul>
<li>Tip bullet 1</li>
<li>Tip bullet 2</li>
</ul>
</ac:rich-text-body></ac:structured-macro>
<h3 id="Warning-Type-Alert-Heading">Warning Type Alert Heading</h3>
<ac:structured-macro ac:name="warning"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
<ul>
<li>Warning bullet 1</li>
<li>Warning bullet 2</li>
</ul>
</ac:rich-text-body></ac:structured-macro>
<h3 id="Important/Caution-Type-Alert-Heading">Important/Caution Type Alert Heading</h3>
<ac:structured-macro ac:name="info"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
<p><strong>"[!IMPORTANT]"</strong></p>
<ul>
<li>Important bullet 1</li>
<li>Important bullet 2</li>
</ul>
</ac:rich-text-body></ac:structured-macro>
<ac:structured-macro ac:name="warning"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
<p><strong>"[!CAUTION]"</strong></p>
<ul>
<li>Important bullet 1</li>
<li>Important bullet 2</li>
</ul>
</ac:rich-text-body></ac:structured-macro>

83
testdata/admonitions-stripnewlines.html vendored Normal file
View File

@ -0,0 +1,83 @@
<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>
<ol>
<li>Note number one</li>
<li>Note number two</li>
</ol>
<ac:structured-macro ac:name="note"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
<p>a<br />
b</p>
</ac:rich-text-body></ac:structured-macro>
<p><strong>Warn (Should not be picked as blockquote type)</strong></p>
</ac:rich-text-body></ac:structured-macro>
<h2 id="Second-Heading">Second Heading</h2>
<ac:structured-macro ac:name="warning"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
<p><strong>"Warn"</strong></p>
<ul>
<li>Warn bullet 1</li>
<li>Warn bullet 2</li>
</ul>
</ac:rich-text-body></ac:structured-macro>
<ul>
<li>Regular list that runs long</li>
</ul>
<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>
<p>Test</p>
</ac:rich-text-body></ac:structured-macro>
<h2 id="Fourth-Heading---Warn-should-not-get-picked-as-block-quote">Fourth Heading - Warn should not get picked as block quote</h2>
<ac:structured-macro ac:name="tip"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
<p><strong>"TIP:"</strong></p>
<ol>
<li>Note number one</li>
<li>Note number two</li>
</ol>
<ac:structured-macro ac:name="tip"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
<p>a<br />
b</p>
</ac:rich-text-body></ac:structured-macro>
<p><strong>Warn (Should not be picked as blockquote type)</strong></p>
</ac:rich-text-body></ac:structured-macro>
<h2 id="Simple-Blockquote">Simple Blockquote</h2>
<blockquote>
<p>This paragraph is a simple blockquote</p>
</blockquote>
<h2 id="GH-Alerts-Heading">GH Alerts Heading</h2>
<h3 id="Note-Type-Alert-Heading">Note Type Alert Heading</h3>
<ac:structured-macro ac:name="note"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
<ul>
<li>Note bullet 1</li>
<li>Note bullet 2</li>
</ul>
</ac:rich-text-body></ac:structured-macro>
<h3 id="Tip-Type-Alert-Heading">Tip Type Alert Heading</h3>
<ac:structured-macro ac:name="tip"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
<ul>
<li>Tip bullet 1</li>
<li>Tip bullet 2</li>
</ul>
</ac:rich-text-body></ac:structured-macro>
<h3 id="Warning-Type-Alert-Heading">Warning Type Alert Heading</h3>
<ac:structured-macro ac:name="warning"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
<ul>
<li>Warning bullet 1</li>
<li>Warning bullet 2</li>
</ul>
</ac:rich-text-body></ac:structured-macro>
<h3 id="Important/Caution-Type-Alert-Heading">Important/Caution Type Alert Heading</h3>
<ac:structured-macro ac:name="info"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
<p><strong>"[!IMPORTANT]"</strong></p>
<ul>
<li>Important bullet 1</li>
<li>Important bullet 2</li>
</ul>
</ac:rich-text-body></ac:structured-macro>
<ac:structured-macro ac:name="warning"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
<p><strong>"[!CAUTION]"</strong></p>
<ul>
<li>Important bullet 1</li>
<li>Important bullet 2</li>
</ul>
</ac:rich-text-body></ac:structured-macro>

84
testdata/admonitions.html vendored Normal file
View File

@ -0,0 +1,84 @@
<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>
<ol>
<li>Note number one</li>
<li>Note number two</li>
</ol>
<ac:structured-macro ac:name="note"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
<p>a<br />
b</p>
</ac:rich-text-body></ac:structured-macro>
<p><strong>Warn (Should not be picked as blockquote type)</strong></p>
</ac:rich-text-body></ac:structured-macro>
<h2 id="Second-Heading">Second Heading</h2>
<ac:structured-macro ac:name="warning"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
<p><strong>"Warn"</strong></p>
<ul>
<li>Warn bullet 1</li>
<li>Warn bullet 2</li>
</ul>
</ac:rich-text-body></ac:structured-macro>
<ul>
<li>Regular list
that runs long</li>
</ul>
<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>
<p>Test</p>
</ac:rich-text-body></ac:structured-macro>
<h2 id="Fourth-Heading---Warn-should-not-get-picked-as-block-quote">Fourth Heading - Warn should not get picked as block quote</h2>
<ac:structured-macro ac:name="tip"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
<p><strong>"TIP:"</strong></p>
<ol>
<li>Note number one</li>
<li>Note number two</li>
</ol>
<ac:structured-macro ac:name="tip"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
<p>a<br />
b</p>
</ac:rich-text-body></ac:structured-macro>
<p><strong>Warn (Should not be picked as blockquote type)</strong></p>
</ac:rich-text-body></ac:structured-macro>
<h2 id="Simple-Blockquote">Simple Blockquote</h2>
<blockquote>
<p>This paragraph is a simple blockquote</p>
</blockquote>
<h2 id="GH-Alerts-Heading">GH Alerts Heading</h2>
<h3 id="Note-Type-Alert-Heading">Note Type Alert Heading</h3>
<ac:structured-macro ac:name="note"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
<ul>
<li>Note bullet 1</li>
<li>Note bullet 2</li>
</ul>
</ac:rich-text-body></ac:structured-macro>
<h3 id="Tip-Type-Alert-Heading">Tip Type Alert Heading</h3>
<ac:structured-macro ac:name="tip"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
<ul>
<li>Tip bullet 1</li>
<li>Tip bullet 2</li>
</ul>
</ac:rich-text-body></ac:structured-macro>
<h3 id="Warning-Type-Alert-Heading">Warning Type Alert Heading</h3>
<ac:structured-macro ac:name="warning"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
<ul>
<li>Warning bullet 1</li>
<li>Warning bullet 2</li>
</ul>
</ac:rich-text-body></ac:structured-macro>
<h3 id="Important/Caution-Type-Alert-Heading">Important/Caution Type Alert Heading</h3>
<ac:structured-macro ac:name="info"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
<p><strong>"[!IMPORTANT]"</strong></p>
<ul>
<li>Important bullet 1</li>
<li>Important bullet 2</li>
</ul>
</ac:rich-text-body></ac:structured-macro>
<ac:structured-macro ac:name="warning"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
<p><strong>"[!CAUTION]"</strong></p>
<ul>
<li>Important bullet 1</li>
<li>Important bullet 2</li>
</ul>
</ac:rich-text-body></ac:structured-macro>

74
testdata/admonitions.md vendored Normal file
View File

@ -0,0 +1,74 @@
# Main Heading
## First Heading
!!! note "NOTES:"
1. Note number one
1. Note number two
!!! note
a
b
**Warn (Should not be picked as blockquote type)**
## Second Heading
!!! warning "Warn"
* Warn bullet 1
* Warn bullet 2
* Regular list
that runs long
## Third Heading
!!! info
Test
## Fourth Heading - Warn should not get picked as block quote
!!! tip "TIP:"
1. Note number one
1. Note number two
!!! tip
a
b
**Warn (Should not be picked as blockquote type)**
## Simple Blockquote
> This paragraph is a simple blockquote
## GH Alerts Heading
### Note Type Alert Heading
!!! note
* Note bullet 1
* Note bullet 2
### Tip Type Alert Heading
!!! tip
* Tip bullet 1
* Tip bullet 2
### Warning Type Alert Heading
!!! warning
* Warning bullet 1
* Warning bullet 2
### Important/Caution Type Alert Heading
!!! info "[!IMPORTANT]"
* Important bullet 1
* Important bullet 2
!!! warning "[!CAUTION]"
* Important bullet 1
* Important bullet 2

View File

@ -190,7 +190,7 @@ var Flags = []cli.Flag{
&cli.StringSliceFlag{
Name: "features",
Value: []string{"mermaid"},
Usage: "Enables optional features. Current features: d2, mermaid",
Usage: "Enables optional features. Current features: d2, mermaid, mkdocsadmonitions",
Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_FEATURES"), altsrctoml.TOML("features", altsrc.NewStringPtrSourcer(&filename))),
},
}