feat(doc): expand callout type= shorthand into background-color and border-color#467
feat(doc): expand callout type= shorthand into background-color and border-color#467herbertliu wants to merge 1 commit intomainfrom
Conversation
…order-color When users write <callout type="warning" emoji="📝"> without an explicit background-color, the Feishu doc renders the block with no color. This commit adds fixCalloutType() which maps the semantic type= attribute to the corresponding background-color/border-color pair accepted by create-doc. - warning → light-yellow/yellow - info/note → light-blue/blue - tip/success/check → light-green/green - error/danger → light-red/red - caution → light-orange/orange - important → light-purple/purple Explicit background-color or border-color attributes are always preserved. The fix is applied via prepareMarkdownForCreate() in both +create and +update paths, and also inside fixExportedMarkdown() for round-trip fidelity. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.
📝 WalkthroughWalkthroughThe PR adds automatic color injection for callout tags in Markdown documentation. When creating or updating docs, markdown is now preprocessed through a new Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🚀 PR Preview Install Guide🧰 CLI updatenpm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@a59a0d0e6eee5c765845fcd84427e47676e087be🧩 Skill updatenpx skills add larksuite/cli#feat/callout-type-to-color -y -g |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
shortcuts/doc/markdown_fix.go (1)
38-40: Broaden fence detection for create-time preprocessing.
prepareMarkdownForCreatenow runs on hand-authored markdown, butapplyOutsideCodeFencesonly recognizes bare triple-backtick fences. That can misclassify~~~, 4+-backtick fences, or blockquote-prefixed fences and lead to missed/incorrect transformations around code blocks. Consider centralizing fence parsing (prefix + marker + length) and reusing it here.Based on learnings:
applyOutsideCodeFences ... only recognize bare triple-backtick fences ... accepted limitation ... because fetch-doc export currently emits only bare triple-backtick fences.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@shortcuts/doc/markdown_fix.go` around lines 38 - 40, prepareMarkdownForCreate currently delegates to applyOutsideCodeFences which only recognizes bare triple-backtick fences; update the code so fence detection is centralized and supports fence prefix (optional blockquote '>' or spaces), marker char (` or ~), and variable length (3+). Introduce or reuse a shared fence-parsing helper (e.g., parseFence or fenceRegex used by applyOutsideCodeFences) and call it from both applyOutsideCodeFences and prepareMarkdownForCreate (or make applyOutsideCodeFences accept the new parser) so create-time preprocessing correctly skips/handles fences like ~~~, 4+ backticks, and blockquote-prefixed fences while preserving existing behavior for fetch-doc exports.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@shortcuts/doc/markdown_fix.go`:
- Around line 262-265: fixCalloutType currently uses typeRe :=
regexp.MustCompile(`\btype="([^"]*)"`) which only matches double-quoted
attributes and leaves single-quoted callouts (e.g., <callout type='warning'>)
unchanged; update the regex used in fixCalloutType (variable typeRe and its use
with attrs and tag) to accept either single or double quotes (for example use a
pattern that captures quote with backreference or a pattern like
\btype=(?:'|")([^'"]*)(?:'|")) and adjust how you read the capture groups from
typeParts accordingly so single-quoted and double-quoted type attributes are
both handled.
---
Nitpick comments:
In `@shortcuts/doc/markdown_fix.go`:
- Around line 38-40: prepareMarkdownForCreate currently delegates to
applyOutsideCodeFences which only recognizes bare triple-backtick fences; update
the code so fence detection is centralized and supports fence prefix (optional
blockquote '>' or spaces), marker char (` or ~), and variable length (3+).
Introduce or reuse a shared fence-parsing helper (e.g., parseFence or fenceRegex
used by applyOutsideCodeFences) and call it from both applyOutsideCodeFences and
prepareMarkdownForCreate (or make applyOutsideCodeFences accept the new parser)
so create-time preprocessing correctly skips/handles fences like ~~~, 4+
backticks, and blockquote-prefixed fences while preserving existing behavior for
fetch-doc exports.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 99b5687c-bc19-48c5-bb18-d0fd4e78ba9a
📒 Files selected for processing (4)
shortcuts/doc/docs_create.goshortcuts/doc/docs_update.goshortcuts/doc/markdown_fix.goshortcuts/doc/markdown_fix_test.go
| typeRe := regexp.MustCompile(`\btype="([^"]*)"`) | ||
| typeParts := typeRe.FindStringSubmatch(attrs) | ||
| if len(typeParts) != 2 { | ||
| return tag // no type= attribute |
There was a problem hiding this comment.
fixCalloutType misses single-quoted type attributes.
Line 262 only matches type="...". Tags like <callout type='warning'> are left unchanged, so shorthand expansion silently fails.
[sraise_minor_fix_note]
🔧 Proposed fix
var calloutTypeRe = regexp.MustCompile(`<callout(\s[^>]*)?>`)
+var calloutTypeAttrRe = regexp.MustCompile(`\btype=(?:"([^"]*)"|'([^']*)')`)
func fixCalloutType(md string) string {
return calloutTypeRe.ReplaceAllStringFunc(md, func(tag string) string {
attrs := ""
if m := calloutTypeRe.FindStringSubmatch(tag); len(m) == 2 {
attrs = m[1]
}
- // Extract type value.
- typeRe := regexp.MustCompile(`\btype="([^"]*)"`)
- typeParts := typeRe.FindStringSubmatch(attrs)
- if len(typeParts) != 2 {
+ typeParts := calloutTypeAttrRe.FindStringSubmatch(attrs)
+ if len(typeParts) != 3 {
return tag // no type= attribute
}
- typeName := typeParts[1]
+ typeName := typeParts[1]
+ if typeName == "" {
+ typeName = typeParts[2]
+ }
colors, ok := calloutTypeColors[typeName]
if !ok {
return tag // unknown type — leave as-is
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| typeRe := regexp.MustCompile(`\btype="([^"]*)"`) | |
| typeParts := typeRe.FindStringSubmatch(attrs) | |
| if len(typeParts) != 2 { | |
| return tag // no type= attribute | |
| var calloutTypeRe = regexp.MustCompile(`<callout(\s[^>]*)?>`) | |
| var calloutTypeAttrRe = regexp.MustCompile(`\btype=(?:"([^"]*)"|'([^']*)')`) | |
| func fixCalloutType(md string) string { | |
| return calloutTypeRe.ReplaceAllStringFunc(md, func(tag string) string { | |
| attrs := "" | |
| if m := calloutTypeRe.FindStringSubmatch(tag); len(m) == 2 { | |
| attrs = m[1] | |
| } | |
| typeParts := calloutTypeAttrRe.FindStringSubmatch(attrs) | |
| if len(typeParts) != 3 { | |
| return tag // no type= attribute | |
| } | |
| typeName := typeParts[1] | |
| if typeName == "" { | |
| typeName = typeParts[2] | |
| } | |
| colors, ok := calloutTypeColors[typeName] | |
| if !ok { | |
| return tag // unknown type — leave as-is | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@shortcuts/doc/markdown_fix.go` around lines 262 - 265, fixCalloutType
currently uses typeRe := regexp.MustCompile(`\btype="([^"]*)"`) which only
matches double-quoted attributes and leaves single-quoted callouts (e.g.,
<callout type='warning'>) unchanged; update the regex used in fixCalloutType
(variable typeRe and its use with attrs and tag) to accept either single or
double quotes (for example use a pattern that captures quote with backreference
or a pattern like \btype=(?:'|")([^'"]*)(?:'|")) and adjust how you read the
capture groups from typeParts accordingly so single-quoted and double-quoted
type attributes are both handled.
|
Thanks for the PR and the thorough test coverage! The mapping (e.g. warning → light-yellow) is not defined by any Feishu spec — it's a convention we'd be inventing and then silently applying. Suggested alternatives: File a feature request for create-doc to natively support type= on callout blocks. Happy to discuss further! |
Summary
When users write
<callout type="warning" emoji="📝">without an explicitbackground-color, the Feishu doc renders the callout block with no color. This PR addsfixCalloutType()which maps the semantictype=attribute to the correspondingbackground-color/border-colorpair thatcreate-docaccepts.Changes
shortcuts/doc/markdown_fix.go: AddcalloutTypeColorsmapping table,fixCalloutType()function, andprepareMarkdownForCreate()helper; integratefixCalloutTypeintofixExportedMarkdown()for round-trip fidelityshortcuts/doc/docs_create.go: ApplyprepareMarkdownForCreate()to markdown before sending to MCPshortcuts/doc/docs_update.go: Same as above for the update path (both DryRun and Execute)shortcuts/doc/markdown_fix_test.go: AddTestFixCalloutTypewith 11 table-driven casestype → color mapping
warninglight-yellowyellowinfo/notelight-bluebluetip/success/checklight-greengreenerror/dangerlight-redredcautionlight-orangeorangeimportantlight-purplepurpleExplicit
background-colororborder-colorattributes on the tag are always preserved (never overwritten).Test Plan
go test ./shortcuts/doc/...) — coverage 64.5%go vet ./...cleangolangci-lint run --new-from-rev=origin/main— 0 issuesgofmtcleanRelated Issues
type=semantic shorthand🤖 Generated with Claude Code
Summary by CodeRabbit