|
#!/usr/bin/env bash |
|
set -euo pipefail |
|
|
|
VERSION_DEFAULT="main" |
|
README_API_URL="https://dash.readme.com/api/v1" |
|
SCRIPT_DIR=$(dirname "$0") |
|
EXPORT_HIDDEN_DOCS_DEFAULT="false" |
|
|
|
error_exit() { |
|
echo "錯誤: $1" >&2 |
|
exit 1 |
|
} |
|
|
|
warning_msg() { |
|
echo "警告: $1" >&2 |
|
} |
|
|
|
if [[ -f "$SCRIPT_DIR/.env" ]]; then |
|
echo "正在從 $SCRIPT_DIR/.env 讀取設定..." |
|
set -o allexport |
|
# shellcheck source=/dev/null |
|
source "$SCRIPT_DIR/.env" |
|
set +o allexport |
|
echo ".env 檔案已載入。" |
|
fi |
|
|
|
README_API_KEY="${README_API_KEY:-}" |
|
while [[ -z "${README_API_KEY}" ]]; do |
|
read -r -p "請輸入您的 ReadMe API 金鑰: " README_API_KEY |
|
done |
|
|
|
if [[ -z "${PROJECT_VERSION:-}" ]]; then |
|
read -r -p "請輸入要匯出的專案版本 (預設: $VERSION_DEFAULT): " PROJECT_VERSION_INPUT |
|
PROJECT_VERSION="${PROJECT_VERSION_INPUT:-$VERSION_DEFAULT}" |
|
else |
|
echo "正在從環境變數讀取專案版本: $PROJECT_VERSION" |
|
fi |
|
|
|
FINAL_EXPORT_HIDDEN_DOCS="${EXPORT_HIDDEN_DOCS:-$EXPORT_HIDDEN_DOCS_DEFAULT}" |
|
echo "準備匯出專案版本: $PROJECT_VERSION" |
|
[[ "$FINAL_EXPORT_HIDDEN_DOCS" == "true" ]] && echo "將會匯出隱藏文件。" |
|
|
|
OUTPUT_DIR_BASE="$SCRIPT_DIR/exported" |
|
OUTPUT_DIR="$OUTPUT_DIR_BASE/$PROJECT_VERSION" |
|
mkdir -p "$OUTPUT_DIR" |
|
echo "所有文件將匯出至: $OUTPUT_DIR" |
|
echo "" |
|
|
|
echo "正在擷取分類列表..." |
|
all_categories_json="[]" |
|
current_page=1 |
|
per_page=100 |
|
total_categories=0 |
|
|
|
while true; do |
|
echo "正在擷取第 $current_page 頁分類..." |
|
page_categories_json=$(curl -s -H "x-readme-version: $PROJECT_VERSION" -u "$README_API_KEY:" "$README_API_URL/categories?page=$current_page&perPage=$per_page") |
|
|
|
if [[ -z "$page_categories_json" ]]; then |
|
[[ "$current_page" -eq 1 ]] && error_exit "無法擷取分類列表,或 API 回應為空。請檢查 API 金鑰、版本和網路連線。" |
|
echo "第 $current_page 頁無回應,停止分頁擷取。" |
|
break |
|
fi |
|
|
|
if echo "$page_categories_json" | jq -e 'if type == "object" then .error else null end' | grep -q -v null; then |
|
[[ "$current_page" -eq 1 ]] && error_exit "分類列表的 API 回應包含錯誤: $(echo "$page_categories_json" | jq '.')" |
|
echo "第 $current_page 頁包含錯誤,停止分頁擷取。" |
|
break |
|
fi |
|
|
|
page_num_categories=$(echo "$page_categories_json" | jq '. | length') |
|
if [[ "$page_num_categories" -eq 0 ]]; then |
|
echo "第 $current_page 頁沒有更多分類,完成擷取。" |
|
break |
|
fi |
|
|
|
all_categories_json=$(echo "$all_categories_json" "$page_categories_json" | jq -s '.[0] + .[1]') |
|
total_categories=$((total_categories + page_num_categories)) |
|
|
|
echo "第 $current_page 頁找到 $page_num_categories 個分類。" |
|
|
|
if [[ "$page_num_categories" -lt "$per_page" ]]; then |
|
echo "已到達最後一頁,完成擷取。" |
|
break |
|
fi |
|
|
|
current_page=$((current_page + 1)) |
|
done |
|
|
|
categories_json="$all_categories_json" |
|
|
|
if [[ "$total_categories" -eq 0 ]]; then |
|
warning_msg "在版本 '$PROJECT_VERSION' 中找不到任何分類。" |
|
exit 0 |
|
fi |
|
echo "總共找到 $total_categories 個分類。" |
|
echo "" |
|
|
|
echo "$categories_json" | jq -c '.[]' | while IFS= read -r category_item; do |
|
category_type=$(echo "$category_item" | jq -r '.type') |
|
category_slug=$(echo "$category_item" | jq -r '.slug') |
|
category_title=$(echo "$category_item" | jq -r '.title') |
|
|
|
echo "--------------------------------------------------" |
|
echo "正在處理分類: '$category_title' (類型: ${category_type}, Slug: $category_slug)" |
|
|
|
category_docs_dir="$OUTPUT_DIR/$category_type/$category_slug" |
|
mkdir -p "$category_docs_dir" |
|
|
|
echo " 正在擷取分類 '$category_slug' 中的文件(包含子文件)..." |
|
docs_in_category_json=$(curl -s -H "x-readme-version: $PROJECT_VERSION" -u "$README_API_KEY:" "$README_API_URL/categories/$category_slug/docs") |
|
|
|
if [[ -z "$docs_in_category_json" ]]; then |
|
warning_msg " 無法擷取分類 '$category_slug' 的文件,或者該分類為空。" |
|
continue |
|
fi |
|
if echo "$docs_in_category_json" | jq -e 'if type == "object" then .error else null end' | grep -q -v null; then |
|
warning_msg " 分類 '$category_slug' 中文件列表的 API 回應包含錯誤: $(echo "$docs_in_category_json" | jq '.') " |
|
continue |
|
fi |
|
|
|
num_docs_in_category=$(echo "$docs_in_category_json" | jq '. | length') |
|
if [[ "$num_docs_in_category" -eq 0 ]]; then |
|
echo " 注意: 分類 '$category_slug' 中沒有文件。" |
|
continue |
|
fi |
|
|
|
total_docs_count=$(echo "$docs_in_category_json" | jq '[.. | objects | select(has("slug")) | select(.slug != null)] | length') |
|
echo " 找到 $num_docs_in_category 份頂層文件,總共 $total_docs_count 份文件(包含子文件)。" |
|
|
|
process_document_hierarchy() { |
|
local doc_item="$1" |
|
local indent_level="${2:-0}" |
|
local parent_path="${3:-""}" |
|
local indent_prefix="" |
|
for ((i=0; i<indent_level; i++)); do |
|
indent_prefix=" $indent_prefix" |
|
done |
|
|
|
local doc_slug doc_title is_hidden |
|
doc_slug=$(echo "$doc_item" | jq -r '.slug') |
|
doc_title=$(echo "$doc_item" | jq -r '.title') |
|
is_hidden=$(echo "$doc_item" | jq -r '.hidden') |
|
|
|
local current_doc_dir |
|
if [[ -z "$parent_path" ]]; then |
|
current_doc_dir="$category_docs_dir" |
|
else |
|
current_doc_dir="$category_docs_dir/$parent_path" |
|
mkdir -p "$current_doc_dir" |
|
fi |
|
|
|
local child_parent_path |
|
if [[ -z "$parent_path" ]]; then |
|
child_parent_path="$doc_slug" |
|
else |
|
child_parent_path="$parent_path/$doc_slug" |
|
fi |
|
|
|
if [[ "$is_hidden" == "true" && "$FINAL_EXPORT_HIDDEN_DOCS" != "true" ]]; then |
|
echo "${indent_prefix} 略過隱藏文件: '$doc_title'" |
|
local children_json |
|
children_json=$(echo "$doc_item" | jq -r '.children // []') |
|
if [[ "$children_json" != "[]" && "$children_json" != "null" ]]; then |
|
echo "$children_json" | jq -c '.[]' | while IFS= read -r child_doc; do |
|
process_document_hierarchy "$child_doc" $((indent_level + 1)) "$child_parent_path" |
|
done |
|
fi |
|
return |
|
fi |
|
|
|
doc_content_json=$(curl -s -H "x-readme-version: $PROJECT_VERSION" -u "$README_API_KEY:" "$README_API_URL/docs/$doc_slug") |
|
|
|
if [[ -z "$doc_content_json" ]]; then |
|
warning_msg "${indent_prefix} 無法擷取文件 '$doc_slug' 的內容 (回應為空)。" |
|
return |
|
fi |
|
|
|
echo "${indent_prefix} ------------------------------------" |
|
echo "${indent_prefix} 正在處理文件: '$doc_title' (Slug: $doc_slug)" |
|
echo "${indent_prefix} 存放目錄: $current_doc_dir" |
|
|
|
local doc_image_storage_dir="$current_doc_dir/images" |
|
mkdir -p "$doc_image_storage_dir" |
|
|
|
markdown_body=$(echo "$doc_content_json" | jq -r '.body') |
|
if echo "$doc_content_json" | jq -e 'if type == "object" then .error else null end' | grep -q -v null; then |
|
warning_msg "${indent_prefix} 文件 '$doc_slug' 內容的 API 回應包含 .error 欄位,但仍嘗試處理 .body。錯誤詳細資訊: $(echo "$doc_content_json" | jq -c '.error')" |
|
fi |
|
|
|
# Check for API documents with empty body but swagger path |
|
is_api=$(echo "$doc_content_json" | jq -r '.isApi // false') |
|
swagger_path=$(echo "$doc_content_json" | jq -r '.swagger.path // null') |
|
|
|
if [[ "$markdown_body" == "null" || -z "$markdown_body" ]]; then |
|
if [[ "$is_api" == "true" && "$swagger_path" != "null" && -n "$swagger_path" ]]; then |
|
echo "${indent_prefix} 發現 API 文件,body 為空但有 swagger 路徑: $swagger_path" |
|
markdown_body="OpenAPI Path: $swagger_path" |
|
else |
|
echo "${indent_prefix} 跳過建立空白文件: '$doc_title' (body 和 swagger 皆為空)" |
|
# Process children even if parent document is skipped |
|
local children_json children_count |
|
children_json=$(echo "$doc_item" | jq -r '.children // []') |
|
if [[ "$children_json" != "[]" && "$children_json" != "null" ]]; then |
|
children_count=$(echo "$children_json" | jq '. | length') |
|
if [[ "$children_count" -gt 0 ]]; then |
|
echo "${indent_prefix} 找到 $children_count 個子文件,正在遞歸處理..." |
|
echo "$children_json" | jq -c '.[]' | while IFS= read -r child_doc; do |
|
process_document_hierarchy "$child_doc" $((indent_level + 1)) "$child_parent_path" |
|
done |
|
fi |
|
fi |
|
return |
|
fi |
|
fi |
|
|
|
# Process custom API documents with api property |
|
if [[ "$is_api" == "true" ]]; then |
|
api_data=$(echo "$doc_content_json" | jq -r '.api // null') |
|
if [[ "$api_data" != "null" ]]; then |
|
echo "${indent_prefix} 發現自訂 API 文件,正在處理 API 屬性..." |
|
|
|
# Extract API information |
|
api_method=$(echo "$api_data" | jq -r '.method // ""') |
|
api_url=$(echo "$api_data" | jq -r '.url // ""') |
|
api_auth=$(echo "$api_data" | jq -r '.auth // ""') |
|
|
|
# Build API info table with proper escaping |
|
api_table=$'\n\n## API 資訊\n\n' |
|
api_table+=$'| 屬性 | 值 |\n' |
|
api_table+=$'|------|----|\n' |
|
[[ -n "$api_method" ]] && api_table+="| Method | \`$api_method\` |"$'\n' |
|
[[ -n "$api_url" ]] && api_table+="| URL | \`$api_url\` |"$'\n' |
|
[[ -n "$api_auth" ]] && api_table+="| Auth | \`$api_auth\` |"$'\n' |
|
|
|
# Process parameters |
|
params_data=$(echo "$api_data" | jq -r '.params // []') |
|
if [[ "$params_data" != "[]" && "$params_data" != "null" ]]; then |
|
api_table+=$'\n## 參數\n\n' |
|
api_table+=$'| 名稱 | 類型 | 必填 | 預設值 | 描述 |\n' |
|
api_table+=$'|------|------|------|--------|------|\n' |
|
|
|
echo "$params_data" | jq -c '.[]' | while IFS= read -r param; do |
|
param_name=$(echo "$param" | jq -r '.name // ""') |
|
param_type=$(echo "$param" | jq -r '.type // ""') |
|
param_required=$(echo "$param" | jq -r '.required // false') |
|
param_default=$(echo "$param" | jq -r '.default // ""') |
|
param_desc=$(echo "$param" | jq -r '.desc // ""') |
|
|
|
# Clean up description (remove markdown links for table) |
|
param_desc_clean=$(echo "$param_desc" | sed 's/\[\([^]]*\)\]([^)]*)/\1/g') |
|
|
|
echo "| \`$param_name\` | \`$param_type\` | $param_required | \`$param_default\` | $param_desc_clean |" >> /tmp/api_params_$$ |
|
done |
|
|
|
if [[ -f "/tmp/api_params_$$" ]]; then |
|
while IFS= read -r line; do |
|
api_table+="$line"$'\n' |
|
done < "/tmp/api_params_$$" |
|
rm "/tmp/api_params_$$" |
|
fi |
|
fi |
|
|
|
# Process response codes |
|
results_data=$(echo "$api_data" | jq -r '.results.codes // []') |
|
if [[ "$results_data" != "[]" && "$results_data" != "null" ]]; then |
|
api_table+=$'\n\n## 回應範例\n\n' |
|
api_table+=$'| 狀態碼 | 名稱 | 回應內容 |\n' |
|
api_table+=$'|--------|------|----------|\n' |
|
|
|
echo "$results_data" | jq -c '.[]' | while IFS= read -r result; do |
|
result_status=$(echo "$result" | jq -r '.status // ""') |
|
result_name=$(echo "$result" | jq -r '.name // ""') |
|
result_code=$(echo "$result" | jq -r '.code // ""') |
|
|
|
# Properly escape and format code for table |
|
result_code_clean=$(echo "$result_code" | sed 's/|/\\|/g' | sed 's/$/\\n/g' | tr -d '\n' | sed 's/\\n$//g') |
|
|
|
echo "| $result_status | $result_name | \`$result_code_clean\` |" >> /tmp/api_results_$$ |
|
done |
|
|
|
if [[ -f "/tmp/api_results_$$" ]]; then |
|
while IFS= read -r line; do |
|
api_table+="$line"$'\n' |
|
done < "/tmp/api_results_$$" |
|
rm "/tmp/api_results_$$" |
|
fi |
|
fi |
|
|
|
# Append API table to markdown |
|
markdown_body="$markdown_body$api_table" |
|
fi |
|
fi |
|
|
|
processed_markdown="$markdown_body" |
|
|
|
# Convert [block:image] to standard Markdown |
|
if [[ "$processed_markdown" == *"[block:image]"* ]]; then |
|
echo "${indent_prefix} 正在將 [block:image] 區塊轉換為標準 Markdown 語法..." |
|
temp_markdown="$processed_markdown" |
|
processed_markdown="" |
|
|
|
while true; do |
|
block_start="[block:image]" |
|
block_end="[/block]" |
|
prefix="${temp_markdown%%"$block_start"*}" |
|
|
|
if [[ "$prefix" == "$temp_markdown" ]]; then |
|
processed_markdown="$processed_markdown$temp_markdown" |
|
break |
|
fi |
|
|
|
processed_markdown="$processed_markdown$prefix" |
|
remainder="${temp_markdown#*"$prefix"}" |
|
after_start="${remainder#"$block_start"}" |
|
content="${after_start%%"$block_end"*}" |
|
|
|
if [[ "$content" == "$after_start" ]]; then |
|
warning_msg "${indent_prefix} 格式錯誤的 [block:image]: 缺少 '$block_end'。" |
|
processed_markdown="$processed_markdown$block_start$after_start" |
|
break |
|
fi |
|
|
|
suffix="${after_start#*"$content$block_end"}" |
|
img_url=$(printf "%s" "$content" | perl -0777 -ne 'if (/"image":\s*\[\s*"([^"]+)"/) { print $1; exit }') |
|
|
|
if [[ -n "$img_url" && "$img_url" != "null" ]]; then |
|
processed_markdown="$processed_markdown" |
|
echo "${indent_prefix} 已將 [block:image] (URL: $img_url) 轉換為 Markdown 語法" |
|
else |
|
warning_msg "${indent_prefix} 在 [block:image] 中未找到圖片 URL。" |
|
processed_markdown="$processed_markdown$block_start$content$block_end" |
|
fi |
|
|
|
temp_markdown="$suffix" |
|
done |
|
echo "${indent_prefix} 完成轉換 [block:image] 區塊。" |
|
fi |
|
|
|
# Convert [block:parameters] to Markdown table |
|
if [[ "$processed_markdown" == *"[block:parameters]"* ]]; then |
|
echo "${indent_prefix} 正在將 [block:parameters] 區塊轉換為 Markdown 表格..." |
|
temp_markdown="$processed_markdown" |
|
processed_markdown="" |
|
|
|
while true; do |
|
block_start="[block:parameters]" |
|
block_end="[/block]" |
|
prefix="${temp_markdown%%"$block_start"*}" |
|
|
|
if [[ "$prefix" == "$temp_markdown" ]]; then |
|
processed_markdown="$processed_markdown$temp_markdown" |
|
break |
|
fi |
|
|
|
processed_markdown="$processed_markdown$prefix" |
|
remainder="${temp_markdown#*"$prefix"}" |
|
after_start="${remainder#"$block_start"}" |
|
content="${after_start%%"$block_end"*}" |
|
|
|
if [[ "$content" == "$after_start" ]]; then |
|
warning_msg "${indent_prefix} 格式錯誤的 [block:parameters]: 缺少 '$block_end'。" |
|
processed_markdown="$processed_markdown$block_start$after_start" |
|
break |
|
fi |
|
|
|
suffix="${after_start#*"$content$block_end"}" |
|
|
|
# Parse JSON content from parameters block |
|
param_json=$(printf "%s" "$content" | jq '.' 2>/dev/null) |
|
if [[ -n "$param_json" && "$param_json" != "null" ]]; then |
|
echo "${indent_prefix} 正在解析參數表格資料..." |
|
|
|
# Extract table data |
|
cols=$(echo "$param_json" | jq -r '.cols // 0') |
|
rows=$(echo "$param_json" | jq -r '.rows // 0') |
|
|
|
if [[ "$cols" -gt 0 && "$rows" -gt 0 ]]; then |
|
# Build Markdown table |
|
table_md=$'\n\n' |
|
|
|
# Build header row |
|
header_row="| " |
|
for ((col=0; col<cols; col++)); do |
|
header_cell=$(echo "$param_json" | jq -r ".data.\"h-$col\" // \"\"") |
|
header_row+="$header_cell | " |
|
done |
|
table_md+="$header_row"$'\n' |
|
|
|
# Build separator row |
|
separator_row="|" |
|
for ((col=0; col<cols; col++)); do |
|
separator_row+="------|" |
|
done |
|
table_md+="$separator_row"$'\n' |
|
|
|
# Build data rows |
|
for ((row=0; row<rows; row++)); do |
|
data_row="| " |
|
for ((col=0; col<cols; col++)); do |
|
cell_data=$(echo "$param_json" | jq -r ".data.\"$row-$col\" // \"\"") |
|
# Handle newlines and pipe characters for Markdown table compatibility |
|
cell_data_clean=$(echo "$cell_data" | sed 's/\\n/<br>/g' | tr '\n' ' ' | sed 's/|/\\|/g' | sed 's/ */ /g' | sed 's/^ *//;s/ *$//') |
|
data_row+="$cell_data_clean | " |
|
done |
|
table_md+="$data_row"$'\n' |
|
done |
|
|
|
table_md+=$'\n' |
|
processed_markdown="$processed_markdown$table_md" |
|
echo "${indent_prefix} 已將 [block:parameters] 轉換為 Markdown 表格 (${rows}行 ${cols}列)" |
|
else |
|
warning_msg "${indent_prefix} [block:parameters] 資料格式錯誤:行列數無效" |
|
processed_markdown="$processed_markdown$block_start$content$block_end" |
|
fi |
|
else |
|
warning_msg "${indent_prefix} 在 [block:parameters] 中未找到有效的 JSON 資料。" |
|
processed_markdown="$processed_markdown$block_start$content$block_end" |
|
fi |
|
|
|
temp_markdown="$suffix" |
|
done |
|
echo "${indent_prefix} 完成轉換 [block:parameters] 區塊。" |
|
fi |
|
|
|
# Extract and download images |
|
echo "${indent_prefix} 正在解析和下載圖片..." |
|
temp_img_list=$(mktemp) |
|
|
|
echo "$processed_markdown" | awk ' |
|
{ |
|
line = $0 |
|
while ( (start_alt = index(line, "![")) > 0 ) { |
|
end_alt = index(substr(line, start_alt), "]") |
|
if (end_alt == 0) { break } |
|
|
|
if (substr(line, start_alt + end_alt, 1) == "(") { |
|
link_start = start_alt + end_alt + 1 |
|
link_end = index(substr(line, link_start), ")") |
|
if (link_end == 0) { break } |
|
|
|
full_link = substr(line, link_start, link_end - 1) |
|
space_pos = index(full_link, " ") |
|
|
|
if (space_pos > 0) { |
|
img_url = substr(full_link, 1, space_pos - 1) |
|
} else { |
|
img_url = full_link |
|
} |
|
|
|
gsub(/^[\x22\x27]+/, "", img_url); |
|
gsub(/[\x22\x27]+$/, "", img_url); |
|
|
|
if (img_url ~ /^https?:\/\//) { |
|
print img_url |
|
} |
|
line = substr(line, link_start + link_end) |
|
} else { |
|
line = substr(line, start_alt + 2) |
|
} |
|
} |
|
}' | sort -u > "$temp_img_list" |
|
|
|
images_downloaded=0 |
|
perl_script=$(mktemp) |
|
cat > "$perl_script" <<'EOF' |
|
my ($markdown_in, $search_url_in, $replace_path_in) = @ARGV; |
|
$markdown_in =~ s#(!\[([^\]]*)\]\()(\Q$search_url_in\E)(\s*(?:\"[^\"]*\"|\'[^\']*\')?\))#$1$replace_path_in$4#g; |
|
print $markdown_in; |
|
EOF |
|
|
|
while IFS= read -r img_url; do |
|
[[ -z "$img_url" ]] && continue |
|
|
|
img_filename_raw=$(basename "$img_url") |
|
img_filename_base="${img_filename_raw%%\?*}" |
|
img_filename_sane="${img_filename_base//[^a-zA-Z0-9._-]/_}" |
|
|
|
if [[ -z "$img_filename_sane" ]]; then |
|
img_hash=$(echo -n "$img_url" | md5sum | cut -d' ' -f1) |
|
img_filename_sane="image_${img_hash}.png" |
|
fi |
|
|
|
if [[ ! "$img_filename_sane" == *.* ]]; then |
|
original_ext="${img_url##*.}" |
|
original_ext="${original_ext%%\?*}" |
|
if [[ "$original_ext" =~ ^(jpe?g|png|gif|svg|webp|ico|bmp|tiff?)$ ]]; then |
|
img_filename_sane="${img_filename_sane}.${original_ext}" |
|
else |
|
img_filename_sane="${img_filename_sane}.png" |
|
fi |
|
fi |
|
|
|
img_path_relative="images/$img_filename_sane" |
|
img_download_path="$doc_image_storage_dir/$img_filename_sane" |
|
|
|
echo "${indent_prefix} 正在下載圖片: $img_url -> $img_download_path" |
|
if curl -s -L "$img_url" -o "$img_download_path"; then |
|
processed_markdown=$(perl "$perl_script" "$processed_markdown" "$img_url" "$img_path_relative") |
|
images_downloaded=$((images_downloaded + 1)) |
|
else |
|
warning_msg "${indent_prefix} 下載圖片 $img_url 失敗" |
|
fi |
|
done < "$temp_img_list" |
|
|
|
rm "$temp_img_list" "$perl_script" |
|
|
|
if [[ "$images_downloaded" -gt 0 ]]; then |
|
echo "${indent_prefix} 已成功下載此文件的 $images_downloaded 張圖片。" |
|
else |
|
echo "${indent_prefix} 未找到或下載此文件的新圖片。" |
|
fi |
|
|
|
output_md_file="$current_doc_dir/${doc_slug}.md" |
|
echo "${indent_prefix} 正在儲存 Markdown 到: $output_md_file" |
|
printf "%s" "$processed_markdown" >"$output_md_file" |
|
[[ $? -ne 0 ]] && warning_msg "${indent_prefix} 儲存 Markdown 檔案 $output_md_file 失敗。" |
|
echo "${indent_prefix} 文件 '$doc_title' (Slug: $doc_slug) 處理完成。" |
|
|
|
local children_json children_count |
|
children_json=$(echo "$doc_item" | jq -r '.children // []') |
|
if [[ "$children_json" != "[]" && "$children_json" != "null" ]]; then |
|
children_count=$(echo "$children_json" | jq '. | length') |
|
if [[ "$children_count" -gt 0 ]]; then |
|
echo "${indent_prefix} 找到 $children_count 個子文件,正在遞歸處理..." |
|
echo "$children_json" | jq -c '.[]' | while IFS= read -r child_doc; do |
|
process_document_hierarchy "$child_doc" $((indent_level + 1)) "$child_parent_path" |
|
done |
|
fi |
|
fi |
|
} |
|
|
|
echo "$docs_in_category_json" | jq -c '.[]' | while IFS= read -r doc_item_summary; do |
|
process_document_hierarchy "$doc_item_summary" 0 |
|
done |
|
echo " 分類 '$category_title' (Slug: $category_slug) 中的所有可處理文件均已處理完畢。" |
|
echo "" |
|
done |
|
|
|
echo "==================================================" |
|
echo "所有操作已完成!" |
|
echo "文件已儲存在 '$OUTPUT_DIR' 下的子目錄中。" |
|
echo "==================================================" |
|
|
|
exit 0 |