///|
/// Render a project report as Markdown.
pub fn render_markdown(
report : ProjectReport,
all_issues? : Bool = true,
lang? : String = "zh",
) -> String {
let lines : Array[String] = []
lines.push(
if is_zh(lang) {
"# MoonDocCheck 报告"
} else {
"# MoonDocCheck Report"
},
)
lines.push("")
lines.push(if is_zh(lang) { "## 摘要" } else { "## Summary" })
lines.push("")
lines.push(
"| " +
(if is_zh(lang) { "项目" } else { "Item" }) +
" | " +
(if is_zh(lang) { "值" } else { "Value" }) +
" |",
)
lines.push("|---|---:|")
lines.push(
"| " +
(if is_zh(lang) { "扫描文件数" } else { "Files scanned" }) +
" | " +
report.files_scanned.to_string() +
" |",
)
lines.push(
"| " +
(if is_zh(lang) { "MoonBit 源文件数" } else { "MoonBit source files" }) +
" | " +
report.moonbit_source_files.to_string() +
" |",
)
lines.push(
"| " +
(if is_zh(lang) { "公开 API" } else { "Public APIs" }) +
" | " +
report.public_api_total.to_string() +
" |",
)
lines.push(
"| " +
(if is_zh(lang) { "已文档化 API" } else { "Documented APIs" }) +
" | " +
report.public_api_documented.to_string() +
" |",
)
lines.push(
"| " +
(if is_zh(lang) { "缺失文档" } else { "Missing docs" }) +
" | " +
report.public_api_missing_docs.to_string() +
" |",
)
lines.push(
"| " +
(if is_zh(lang) { "文档覆盖率" } else { "Documentation coverage" }) +
" | " +
report.documentation_coverage.to_string() +
"% |",
)
lines.push("")
lines.push(
if is_zh(lang) {
"## 总体评价"
} else {
"## Overall Assessment"
},
)
lines.push("")
lines.push(
"- " +
(if is_zh(lang) { "等级: " } else { "Level: " }) +
readiness_level(report, lang),
)
lines.push(
"- " +
(if is_zh(lang) { "说明: " } else { "Comment: " }) +
readiness_comment(report, lang),
)
lines.push(
"- " +
(if is_zh(lang) {
"摘要: " +
report.public_api_total.to_string() +
" 个公开 API 中有 " +
report.public_api_missing_docs.to_string() +
" 个缺少文档。"
} else {
"Summary: " +
report.public_api_missing_docs.to_string() +
" of " +
report.public_api_total.to_string() +
" public APIs are missing docs."
}),
)
let top_files = top_missing_files(report, 5)
if !top_files.is_empty() {
lines.push("")
lines.push(
if is_zh(lang) {
"### 缺文档重灾区"
} else {
"### Top Missing-Doc Files"
},
)
lines.push("")
lines.push(
"| " +
(if is_zh(lang) { "文件" } else { "File" }) +
" | " +
(if is_zh(lang) { "缺失" } else { "Missing" }) +
" | " +
(if is_zh(lang) { "覆盖率" } else { "Coverage" }) +
" |",
)
lines.push("|---|---:|---:|")
for summary in top_files {
lines.push(
"| `" +
display_path(report, summary.file) +
"` | " +
summary.public_api_missing_docs.to_string() +
" | " +
summary.documentation_coverage.to_string() +
"% |",
)
}
}
if !report.file_coverage.is_empty() {
lines.push("")
lines.push(
if is_zh(lang) {
"## 文件覆盖率"
} else {
"## File Coverage"
},
)
lines.push("")
lines.push(
"| " +
(if is_zh(lang) { "文件" } else { "File" }) +
" | " +
(if is_zh(lang) { "公开 API" } else { "Public APIs" }) +
" | " +
(if is_zh(lang) { "已文档化" } else { "Documented" }) +
" | " +
(if is_zh(lang) { "缺失" } else { "Missing" }) +
" | " +
(if is_zh(lang) { "覆盖率" } else { "Coverage" }) +
" |",
)
lines.push("|---|---:|---:|---:|---:|")
for summary in report.file_coverage {
lines.push(
"| `" +
display_path(report, summary.file) +
"` | " +
summary.public_api_total.to_string() +
" | " +
summary.public_api_documented.to_string() +
" | " +
summary.public_api_missing_docs.to_string() +
" | " +
summary.documentation_coverage.to_string() +
"% |",
)
}
}
lines.push("")
lines.push("## README")
lines.push("")
lines.push(
"- " +
(if is_zh(lang) { "找到: " } else { "Found: " }) +
yes_no_lang(report.readme.found, lang),
)
lines.push(
"- " +
(if is_zh(lang) { "有项目介绍: " } else { "Has overview: " }) +
yes_no_lang(report.readme.has_overview, lang),
)
lines.push(
"- " +
(if is_zh(lang) { "有文档入口: " } else { "Has docs entry: " }) +
yes_no_lang(report.readme.has_usage, lang),
)
lines.push(
"- " +
(if is_zh(lang) { "提到许可证: " } else { "Has license mention: " }) +
yes_no_lang(report.readme.has_license_mention, lang),
)
lines.push("")
lines.push(if is_zh(lang) { "## Moon 元数据" } else { "## Moon Metadata" })
lines.push("")
lines.push("- `moon.mod`: " + yes_no_lang(report.moon_mod.found, lang))
lines.push(
"- `moon.mod.json`: " + yes_no_lang(report.moon_mod.legacy_json_found, lang),
)
lines.push(
"- `description`: " + yes_no_lang(report.moon_mod.has_description, lang),
)
lines.push(
"- `repository`: " + yes_no_lang(report.moon_mod.has_repository, lang),
)
lines.push("- `license`: " + yes_no_lang(report.moon_mod.has_license, lang))
lines.push("- `keywords`: " + yes_no_lang(report.moon_mod.has_keywords, lang))
lines.push("")
lines.push(
if is_zh(lang) {
"## 生成的接口摘要"
} else {
"## Generated Interface"
},
)
lines.push("")
lines.push(
"- `pkg.generated.mbti`: " + yes_no_lang(report.has_generated_mbti, lang),
)
if !report.has_generated_mbti {
lines.push(
if is_zh(lang) {
"- 建议: 发布或评审前运行 `moon info`。"
} else {
"- Suggestion: run `moon info` before publishing or review."
},
)
}
lines.push("")
lines.push(if is_zh(lang) { "## 示例" } else { "## Examples" })
lines.push("")
lines.push(
"- " +
(if is_zh(lang) { "代码块: " } else { "Code blocks: " }) +
report.markdown.code_blocks.to_string(),
)
lines.push("- `mbt check`: " + report.markdown.mbt_check_blocks.to_string())
lines.push(
"- `mbt nocheck`: " + report.markdown.mbt_nocheck_blocks.to_string(),
)
lines.push(
"- " +
(if is_zh(lang) {
"普通 MoonBit 代码块: "
} else {
"Ordinary MoonBit blocks: "
}) +
report.markdown.moonbit_blocks.to_string(),
)
lines.push("")
lines.push("## CI")
lines.push("")
lines.push(
"- " +
(if is_zh(lang) { "Workflow 文件数: " } else { "Workflow files: " }) +
report.ci.workflow_files.to_string(),
)
lines.push("- `moon check`: " + yes_no_lang(report.ci.has_moon_check, lang))
lines.push("- `moon test`: " + yes_no_lang(report.ci.has_moon_test, lang))
lines.push("- `moon fmt`: " + yes_no_lang(report.ci.has_moon_fmt, lang))
lines.push("- `moon info`: " + yes_no_lang(report.ci.has_moon_info, lang))
lines.push(
"- " +
(if is_zh(lang) { "脚本式验证: " } else { "Script validation: " }) +
yes_no_lang(report.ci.has_script_validation, lang),
)
lines.push("")
lines.push(if is_zh(lang) { "## 问题清单" } else { "## Issues" })
lines.push("")
if report.issues.is_empty() {
lines.push(
if is_zh(lang) {
"未发现问题。"
} else {
"No issues found."
},
)
} else {
let limit = if all_issues {
report.issues.length()
} else if report.issues.length() > 20 {
20
} else {
report.issues.length()
}
for index in 0.. display_path(report, issue.file) + ":" + line.to_string()
None => display_path(report, issue.file)
}
lines.push("- `" + location + "` " + issue_message(issue, lang))
lines.push(
" " +
(if is_zh(lang) { "修复: " } else { "Fix: " }) +
fix_hint(issue, lang),
)
}
if report.issues.length() > limit {
lines.push("")
lines.push(
if is_zh(lang) {
"... 还有 " +
(report.issues.length() - limit).to_string() +
" 个问题。使用 `--all-issues` 查看全部。"
} else {
"... " +
(report.issues.length() - limit).to_string() +
" more issues. Run with `--all-issues` to show everything."
},
)
}
}
lines.push("")
lines.push(if is_zh(lang) { "## 下一步" } else { "## Next Steps" })
lines.push("")
for step in next_steps(report, lang) {
lines.push("- " + step)
}
lines.join("\n")
}