# utils/block_helpers.R # Block-based 输出协议 — 构造函数 # # 所有 R 工具通过这些函数构建 report_blocks[], # 前端 DynamicReport.tsx 根据 block.type 统一渲染。 # 支持 4 种 Block 类型:markdown / table / image / key_value #' 构造 Markdown 文本块 #' @param content Markdown 格式文本(支持标题、列表、加粗等) #' @param title 可选标题(前端渲染为区块标题) #' @return block list make_markdown_block <- function(content, title = NULL) { block <- list(type = "markdown", content = content) if (!is.null(title)) block$title <- title block } #' 构造表格块 #' @param headers 列名字符向量,如 c("组别", "均值", "标准差") #' @param rows 行数据列表,每行为字符向量,如 list(c("A", "5.2", "1.3"), ...) #' @param title 可选表格标题 #' @param footnote 可选脚注(如方法说明) #' @return block list make_table_block <- function(headers, rows, title = NULL, footnote = NULL, metadata = NULL) { block <- list( type = "table", headers = as.list(headers), rows = lapply(rows, as.list) ) if (!is.null(title)) block$title <- title if (!is.null(footnote)) block$footnote <- footnote if (!is.null(metadata)) block$metadata <- metadata block } #' 从 data.frame 构造表格块(便捷方法) #' @param df data.frame #' @param title 可选表格标题 #' @param footnote 可选脚注 #' @param digits 数值列保留小数位数,默认 3 #' @return block list make_table_block_from_df <- function(df, title = NULL, footnote = NULL, digits = 3) { headers <- colnames(df) rows <- lapply(seq_len(nrow(df)), function(i) { lapply(df[i, , drop = FALSE], function(val) { if (is.numeric(val)) { format(round(val, digits), nsmall = digits) } else { as.character(val) } }) }) make_table_block(headers, rows, title = title, footnote = footnote) } #' 构造图片块 #' @param base64_data 完整的 data URI,如 "data:image/png;base64,..." #' @param title 可选图片标题 #' @param alt 可选 alt 文本(无障碍 + Word 导出用) #' @return block list make_image_block <- function(base64_data, title = NULL, alt = NULL) { block <- list(type = "image", data = base64_data) if (!is.null(title)) block$title <- title if (!is.null(alt)) block$alt <- alt block } #' 构造键值对块 #' @param items 命名列表或 list(list(key=..., value=...), ...) #' @param title 可选标题 #' @return block list make_kv_block <- function(items, title = NULL) { if (!is.null(names(items)) && length(names(items)) > 0 && names(items)[1] != "") { kv_list <- lapply(names(items), function(k) { list(key = k, value = as.character(items[[k]])) }) } else { kv_list <- items } block <- list(type = "key_value", items = kv_list) if (!is.null(title)) block$title <- title block }