This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
just build # build binary to ./mdcx
just install # go install to $GOPATH/bin
just test # go test ./...
just test-v # verbose tests
go test ./converter/... -run TestRoundTrip # run specific tests
mdcx converts Markdown ↔ Confluence storage-format XML with round-trip fidelity. The binary lives at cmd/mdcx/.
cmd/mdcx/ CLI (cobra commands, package main)
├─ converter Core bidirectional conversion
├─ api Confluence REST client (pull/push)
├─ template Marker-based embed/extract
└─ format XML pretty-printer + ANSI colorizer
converter/
├─ md2xml.go goldmark parser → confluence.Renderer → XML
└─ xml2md.go golang.org/x/net/html walker → Markdown
confluence/
├─ renderer.go goldmark NodeRenderer (registered at priority 100)
└─ elements.go Macro builders: CodeMacro, InfoPanel, etc.
Bidirectional round-trip preservation — Confluence elements with no Markdown equivalent (inline comments, user mentions, attachment images, layout sections) survive round-trips via HTML <span data-*> attributes and <!-- comment --> markers. The md→xml renderer reconstructs proper ac:*/ri:* tags from these.
CDATA preprocessing — xml2md.go replaces <![CDATA[...]]> with <cdatacontent> fake elements before parsing, because golang.org/x/net/html doesn't handle CDATA. The reverse direction uses confluence.escapeCDATA() to split ]]> sequences.
Renderer state — confluence.Renderer tracks taskIDCounter, inTaskBody, inlineCommentDepth, and pending attributes from HTML comments. This state is per-conversion and must remain consistent across the AST walk.
Template markers — <!-- MD_CONTENT_START --> / <!-- MD_CONTENT_END --> delimit the editable region in Confluence pages. The push --template flow: fetch page → replace between markers → update with version increment.
<blockquote>)<ac:task-list><ac:structured-macro ac:name="code"> with CDATA bodyac:, ri:) are string-constructed, not from an XML library