package confluence import "strings" // Confluence storage format macro helpers. func CodeMacro(language string, body string) string { return CodeMacroWithID(language, body, "", "") } func CodeMacroWithID(language string, body string, macroID string, attrOrder string) string { var lang string if language != "" { lang = `` + language + `` } tag := buildStructuredMacroTag("code", macroID, attrOrder) return tag + lang + `` + `` } // buildStructuredMacroTag builds an opening tag // with attributes in the specified order. attrOrder is a comma-separated // list of short attribute names (e.g. "name,schema-version,macro-id"). func buildStructuredMacroTag(name string, macroID string, attrOrder string) string { attrValues := map[string]string{ "name": name, "schema-version": "1", } if macroID != "" { attrValues["macro-id"] = macroID } var order []string if attrOrder != "" { order = strings.Split(attrOrder, ",") } else { // Default order when no original order is known order = []string{"name", "schema-version"} if macroID != "" { order = append(order, "macro-id") } } var buf strings.Builder buf.WriteString("") return buf.String() } func InfoPanel(body string) string { return `` + `` + body + `` + `` } func NotePanel(body string) string { return `` + `` + body + `` + `` } func WarningPanel(body string) string { return `` + `` + body + `` + `` } func ImageExternal(url string) string { return `` } // escapeCDATA splits ]]> sequences so they don't break CDATA sections. func escapeCDATA(s string) string { result := make([]byte, 0, len(s)) for i := 0; i < len(s); i++ { if i+2 < len(s) && s[i] == ']' && s[i+1] == ']' && s[i+2] == '>' { result = append(result, ']', ']', '>', '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[') i += 2 } else { result = append(result, s[i]) } } return string(result) }