gitbook
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGitBook Documentation Skill
GitBook文档技能
Master GitBook for publishing professional documentation and books with spaces, collections, content variants, Git synchronization, team collaboration, and API integration. Build beautiful, searchable documentation sites with powerful collaboration features.
掌握GitBook的使用,借助空间、合集、内容版本变体、Git同步、团队协作及API集成功能,发布专业文档与书籍。打造具备强大协作功能的美观、可搜索的文档站点。
When to Use This Skill
何时使用此技能
USE GitBook when:
适合使用GitBook的场景:
- Team documentation - Collaborative docs with multiple editors
- Product documentation - User guides, API docs, tutorials
- Knowledge bases - Internal wikis and knowledge management
- Multi-version docs - Maintain docs for different product versions
- Git-based workflow - Sync docs with GitHub/GitLab
- Custom branding - Need custom domains and styling
- Access control - Restrict docs to authenticated users
- Quick setup - Need docs fast without build systems
- 团队文档 - 支持多位编辑协作的文档
- 产品文档 - 用户指南、API文档、教程
- 知识库 - 内部维基与知识管理系统
- 多版本文档 - 维护不同产品版本的文档
- 基于Git的工作流 - 与GitHub/GitLab同步文档
- 自定义品牌 - 需要自定义域名与样式
- 访问控制 - 限制文档仅对已认证用户开放
- 快速搭建 - 无需构建系统,快速创建文档
DON'T USE GitBook when:
不适合使用GitBook的场景:
- Complex code docs - Use Sphinx for Python API docs
- Static site control - Use MkDocs or Docusaurus
- Offline-first - GitBook is primarily cloud-hosted
- Self-hosted required - GitBook is SaaS (legacy self-hosted deprecated)
- Free unlimited - Free tier has limitations
- 复杂代码文档 - Python API文档建议使用Sphinx
- 静态站点完全控制 - 建议使用MkDocs或Docusaurus
- 优先离线使用 - GitBook主要为云托管服务
- 必须自托管 - GitBook为SaaS服务(旧版自托管已弃用)
- 无限免费使用 - 免费版存在功能限制
Prerequisites
前置条件
GitBook Account Setup
GitBook账户设置
bash
undefinedbash
undefined1. Sign up at https://www.gitbook.com/
2. Create an organization (or use personal space)
2. 创建组织(或使用个人空间)
3. Generate API token at:
3. 在以下地址生成API令牌:
Set environment variable
设置环境变量
export GITBOOK_API_TOKEN="gb_api_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
export GITBOOK_API_TOKEN="gb_api_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Verify authentication
验证身份
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"https://api.gitbook.com/v1/user" | jq '.id, .displayName'
"https://api.gitbook.com/v1/user" | jq '.id, .displayName'
undefinedcurl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"https://api.gitbook.com/v1/user" | jq '.id, .displayName'
"https://api.gitbook.com/v1/user" | jq '.id, .displayName'
undefinedGit Sync Setup
Git同步设置
bash
undefinedbash
undefinedIn your GitBook space settings:
在GitBook空间设置中:
1. Go to Integrations > Git Sync
1. 进入Integrations > Git Sync
2. Connect GitHub/GitLab account
2. 连接GitHub/GitLab账户
3. Select repository and branch
3. 选择仓库与分支
Repository structure
仓库结构
docs-repo/
├── README.md # Main page (or SUMMARY.md)
├── SUMMARY.md # Table of contents
├── chapter-1/
│ ├── README.md # Chapter intro
│ ├── page-1.md
│ └── page-2.md
├── chapter-2/
│ └── ...
└── .gitbook.yaml # GitBook config (optional)
undefineddocs-repo/
├── README.md # 主页(或SUMMARY.md)
├── SUMMARY.md # 目录
├── chapter-1/
│ ├── README.md # 章节介绍
│ ├── page-1.md
│ └── page-2.md
├── chapter-2/
│ └── ...
└── .gitbook.yaml # GitBook配置(可选)
undefinedPython Setup
Python环境设置
bash
undefinedbash
undefinedInstall dependencies
安装依赖
pip install requests python-dateutil
pip install requests python-dateutil
Using uv
使用uv安装
uv pip install requests python-dateutil
uv pip install requests python-dateutil
Verify
验证
python -c "import requests; print('Ready for GitBook integration!')"
undefinedpython -c "import requests; print('Ready for GitBook integration!')"
undefinedCore Capabilities
核心功能
1. API Authentication
1. API身份验证
REST API Basics:
bash
undefinedREST API基础:
bash
undefinedGitBook API base URL
GitBook API基础URL
API_BASE="https://api.gitbook.com/v1"
API_BASE="https://api.gitbook.com/v1"
Get current user
获取当前用户信息
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/user" | jq
"$API_BASE/user" | jq
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/user" | jq
"$API_BASE/user" | jq
List organizations
列出所有组织
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/orgs" | jq
"$API_BASE/orgs" | jq
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/orgs" | jq
"$API_BASE/orgs" | jq
Get organization details
获取组织详情
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/orgs/ORG_ID" | jq
"$API_BASE/orgs/ORG_ID" | jq
**Python API Client:**
```python
import requests
from datetime import datetime
import os
class GitBookClient:
"""GitBook API client."""
BASE_URL = "https://api.gitbook.com/v1"
def __init__(self, api_token=None):
self.api_token = api_token or os.environ.get("GITBOOK_API_TOKEN")
self.headers = {
"Authorization": f"Bearer {self.api_token}",
"Content-Type": "application/json"
}
def _request(self, method, endpoint, data=None, params=None):
"""Make API request."""
url = f"{self.BASE_URL}{endpoint}"
response = requests.request(
method,
url,
headers=self.headers,
json=data,
params=params
)
response.raise_for_status()
return response.json() if response.text else None
def get_user(self):
"""Get current user."""
return self._request("GET", "/user")
def list_organizations(self):
"""List all organizations."""
return self._request("GET", "/orgs")
def get_organization(self, org_id):
"""Get organization details."""
return self._request("GET", f"/orgs/{org_id}")curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/orgs/ORG_ID" | jq
"$API_BASE/orgs/ORG_ID" | jq
**Python API客户端:**
```python
import requests
from datetime import datetime
import os
class GitBookClient:
"""GitBook API客户端。"""
BASE_URL = "https://api.gitbook.com/v1"
def __init__(self, api_token=None):
self.api_token = api_token or os.environ.get("GITBOOK_API_TOKEN")
self.headers = {
"Authorization": f"Bearer {self.api_token}",
"Content-Type": "application/json"
}
def _request(self, method, endpoint, data=None, params=None):
"""发起API请求。"""
url = f"{self.BASE_URL}{endpoint}"
response = requests.request(
method,
url,
headers=self.headers,
json=data,
params=params
)
response.raise_for_status()
return response.json() if response.text else None
def get_user(self):
"""获取当前用户信息。"""
return self._request("GET", "/user")
def list_organizations(self):
"""列出所有组织。"""
return self._request("GET", "/orgs")
def get_organization(self, org_id):
"""获取组织详情。"""
return self._request("GET", f"/orgs/{org_id}")Example usage
使用示例
if name == "main":
client = GitBookClient()
user = client.get_user()
print(f"User: {user['displayName']}")
orgs = client.list_organizations()
for org in orgs.get("items", []):
print(f"Org: {org['title']}")undefinedif name == "main":
client = GitBookClient()
user = client.get_user()
print(f"User: {user['displayName']}")
orgs = client.list_organizations()
for org in orgs.get("items", []):
print(f"Org: {org['title']}")undefined2. Spaces Management
2. 空间管理
REST API - Spaces:
bash
undefinedREST API - 空间操作:
bash
undefinedList spaces in organization
列出组织下的所有空间
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/orgs/ORG_ID/spaces" | jq
"$API_BASE/orgs/ORG_ID/spaces" | jq
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/orgs/ORG_ID/spaces" | jq
"$API_BASE/orgs/ORG_ID/spaces" | jq
Get space details
获取空间详情
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID" | jq
"$API_BASE/spaces/SPACE_ID" | jq
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID" | jq
"$API_BASE/spaces/SPACE_ID" | jq
Create space
创建空间
curl -s -X POST -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/orgs/ORG_ID/spaces"
-d '{ "title": "API Documentation", "visibility": "public" }' | jq
-H "Content-Type: application/json"
"$API_BASE/orgs/ORG_ID/spaces"
-d '{ "title": "API Documentation", "visibility": "public" }' | jq
curl -s -X POST -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/orgs/ORG_ID/spaces"
-d '{ "title": "API Documentation", "visibility": "public" }' | jq
-H "Content-Type: application/json"
"$API_BASE/orgs/ORG_ID/spaces"
-d '{ "title": "API Documentation", "visibility": "public" }' | jq
Update space
更新空间
curl -s -X PATCH -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID"
-d '{ "title": "Updated API Documentation", "visibility": "private" }' | jq
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID"
-d '{ "title": "Updated API Documentation", "visibility": "private" }' | jq
curl -s -X PATCH -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID"
-d '{ "title": "Updated API Documentation", "visibility": "private" }' | jq
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID"
-d '{ "title": "Updated API Documentation", "visibility": "private" }' | jq
Delete space
删除空间
curl -s -X DELETE -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID"
"$API_BASE/spaces/SPACE_ID"
curl -s -X DELETE -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID"
"$API_BASE/spaces/SPACE_ID"
Get space content (pages)
获取空间内容(页面)
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/content" | jq
"$API_BASE/spaces/SPACE_ID/content" | jq
**Python - Spaces:**
```python
class GitBookClient:
# ... previous methods ...
def list_spaces(self, org_id):
"""List all spaces in organization."""
return self._request("GET", f"/orgs/{org_id}/spaces")
def get_space(self, space_id):
"""Get space details."""
return self._request("GET", f"/spaces/{space_id}")
def create_space(self, org_id, title, visibility="public"):
"""Create a new space."""
return self._request(
"POST",
f"/orgs/{org_id}/spaces",
data={"title": title, "visibility": visibility}
)
def update_space(self, space_id, **kwargs):
"""Update space settings."""
return self._request(
"PATCH",
f"/spaces/{space_id}",
data=kwargs
)
def delete_space(self, space_id):
"""Delete a space."""
return self._request("DELETE", f"/spaces/{space_id}")
def get_space_content(self, space_id):
"""Get space content structure."""
return self._request("GET", f"/spaces/{space_id}/content")curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/content" | jq
"$API_BASE/spaces/SPACE_ID/content" | jq
**Python - 空间操作:**
```python
class GitBookClient:
# ... 之前的方法 ...
def list_spaces(self, org_id):
"""列出组织下的所有空间。"""
return self._request("GET", f"/orgs/{org_id}/spaces")
def get_space(self, space_id):
"""获取空间详情。"""
return self._request("GET", f"/spaces/{space_id}")
def create_space(self, org_id, title, visibility="public"):
"""创建新空间。"""
return self._request(
"POST",
f"/orgs/{org_id}/spaces",
data={"title": title, "visibility": visibility}
)
def update_space(self, space_id, **kwargs):
"""更新空间设置。"""
return self._request(
"PATCH",
f"/spaces/{space_id}",
data=kwargs
)
def delete_space(self, space_id):
"""删除空间。"""
return self._request("DELETE", f"/spaces/{space_id}")
def get_space_content(self, space_id):
"""获取空间内容结构。"""
return self._request("GET", f"/spaces/{space_id}/content")Example usage
使用示例
spaces = client.list_spaces("org_xxxxx")
for space in spaces.get("items", []):
print(f"Space: {space['title']} ({space['visibility']})")
spaces = client.list_spaces("org_xxxxx")
for space in spaces.get("items", []):
print(f"Space: {space['title']} ({space['visibility']})")
Create new space
创建新空间
new_space = client.create_space(
org_id="org_xxxxx",
title="Developer Guide",
visibility="public"
)
print(f"Created: {new_space['id']}")
undefinednew_space = client.create_space(
org_id="org_xxxxx",
title="Developer Guide",
visibility="public"
)
print(f"Created: {new_space['id']}")
undefined3. Content Management
3. 内容管理
REST API - Content:
bash
undefinedREST API - 内容操作:
bash
undefinedGet page content
获取页面内容
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/content/page/PAGE_ID" | jq
"$API_BASE/spaces/SPACE_ID/content/page/PAGE_ID" | jq
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/content/page/PAGE_ID" | jq
"$API_BASE/spaces/SPACE_ID/content/page/PAGE_ID" | jq
List pages in space
列出空间内的所有页面
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/content" | jq '.pages'
"$API_BASE/spaces/SPACE_ID/content" | jq '.pages'
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/content" | jq '.pages'
"$API_BASE/spaces/SPACE_ID/content" | jq '.pages'
Import content from Git
从Git导入内容
curl -s -X POST -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID/content/import/git"
-d '{ "url": "https://github.com/user/docs-repo", "ref": "main" }' | jq
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID/content/import/git"
-d '{ "url": "https://github.com/user/docs-repo", "ref": "main" }' | jq
curl -s -X POST -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID/content/import/git"
-d '{ "url": "https://github.com/user/docs-repo", "ref": "main" }' | jq
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID/content/import/git"
-d '{ "url": "https://github.com/user/docs-repo", "ref": "main" }' | jq
Export content
导出内容
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/content/export"
-o content-export.zip
"$API_BASE/spaces/SPACE_ID/content/export"
-o content-export.zip
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/content/export"
-o content-export.zip
"$API_BASE/spaces/SPACE_ID/content/export"
-o content-export.zip
Search content
搜索内容
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/search?query=installation" | jq
"$API_BASE/spaces/SPACE_ID/search?query=installation" | jq
**Python - Content:**
```python
class GitBookClient:
# ... previous methods ...
def get_page(self, space_id, page_id):
"""Get page content."""
return self._request(
"GET",
f"/spaces/{space_id}/content/page/{page_id}"
)
def list_pages(self, space_id):
"""List all pages in space."""
content = self.get_space_content(space_id)
return content.get("pages", [])
def search_content(self, space_id, query):
"""Search content in space."""
return self._request(
"GET",
f"/spaces/{space_id}/search",
params={"query": query}
)
def import_from_git(self, space_id, repo_url, ref="main"):
"""Import content from Git repository."""
return self._request(
"POST",
f"/spaces/{space_id}/content/import/git",
data={"url": repo_url, "ref": ref}
)curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/search?query=installation" | jq
"$API_BASE/spaces/SPACE_ID/search?query=installation" | jq
**Python - 内容操作:**
```python
class GitBookClient:
# ... 之前的方法 ...
def get_page(self, space_id, page_id):
"""获取页面内容。"""
return self._request(
"GET",
f"/spaces/{space_id}/content/page/{page_id}"
)
def list_pages(self, space_id):
"""列出空间内的所有页面。"""
content = self.get_space_content(space_id)
return content.get("pages", [])
def search_content(self, space_id, query):
"""在空间内搜索内容。"""
return self._request(
"GET",
f"/spaces/{space_id}/search",
params={"query": query}
)
def import_from_git(self, space_id, repo_url, ref="main"):
"""从Git仓库导入内容。"""
return self._request(
"POST",
f"/spaces/{space_id}/content/import/git",
data={"url": repo_url, "ref": ref}
)Search example
搜索示例
results = client.search_content("space_xxxxx", "getting started")
for result in results.get("items", []):
print(f"Found: {result['title']} - {result['path']}")
undefinedresults = client.search_content("space_xxxxx", "getting started")
for result in results.get("items", []):
print(f"Found: {result['title']} - {result['path']}")
undefined4. Collections Management
4. 合集管理
REST API - Collections:
bash
undefinedREST API - 合集操作:
bash
undefinedList collections
列出所有合集
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/orgs/ORG_ID/collections" | jq
"$API_BASE/orgs/ORG_ID/collections" | jq
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/orgs/ORG_ID/collections" | jq
"$API_BASE/orgs/ORG_ID/collections" | jq
Get collection
获取合集详情
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/collections/COLLECTION_ID" | jq
"$API_BASE/collections/COLLECTION_ID" | jq
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/collections/COLLECTION_ID" | jq
"$API_BASE/collections/COLLECTION_ID" | jq
Create collection
创建合集
curl -s -X POST -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/orgs/ORG_ID/collections"
-d '{ "title": "Product Documentation", "description": "All product-related documentation" }' | jq
-H "Content-Type: application/json"
"$API_BASE/orgs/ORG_ID/collections"
-d '{ "title": "Product Documentation", "description": "All product-related documentation" }' | jq
curl -s -X POST -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/orgs/ORG_ID/collections"
-d '{ "title": "Product Documentation", "description": "All product-related documentation" }' | jq
-H "Content-Type: application/json"
"$API_BASE/orgs/ORG_ID/collections"
-d '{ "title": "Product Documentation", "description": "All product-related documentation" }' | jq
Add space to collection
向合集中添加空间
curl -s -X POST -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/collections/COLLECTION_ID/spaces/SPACE_ID" | jq
"$API_BASE/collections/COLLECTION_ID/spaces/SPACE_ID" | jq
curl -s -X POST -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/collections/COLLECTION_ID/spaces/SPACE_ID" | jq
"$API_BASE/collections/COLLECTION_ID/spaces/SPACE_ID" | jq
Remove space from collection
从合集中移除空间
curl -s -X DELETE -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/collections/COLLECTION_ID/spaces/SPACE_ID"
"$API_BASE/collections/COLLECTION_ID/spaces/SPACE_ID"
curl -s -X DELETE -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/collections/COLLECTION_ID/spaces/SPACE_ID"
"$API_BASE/collections/COLLECTION_ID/spaces/SPACE_ID"
List spaces in collection
列出合集中的空间
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/collections/COLLECTION_ID/spaces" | jq
"$API_BASE/collections/COLLECTION_ID/spaces" | jq
**Python - Collections:**
```python
class GitBookClient:
# ... previous methods ...
def list_collections(self, org_id):
"""List all collections in organization."""
return self._request("GET", f"/orgs/{org_id}/collections")
def get_collection(self, collection_id):
"""Get collection details."""
return self._request("GET", f"/collections/{collection_id}")
def create_collection(self, org_id, title, description=None):
"""Create a new collection."""
data = {"title": title}
if description:
data["description"] = description
return self._request(
"POST",
f"/orgs/{org_id}/collections",
data=data
)
def add_space_to_collection(self, collection_id, space_id):
"""Add space to collection."""
return self._request(
"POST",
f"/collections/{collection_id}/spaces/{space_id}"
)
def list_collection_spaces(self, collection_id):
"""List spaces in collection."""
return self._request(
"GET",
f"/collections/{collection_id}/spaces"
)curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/collections/COLLECTION_ID/spaces" | jq
"$API_BASE/collections/COLLECTION_ID/spaces" | jq
**Python - 合集操作:**
```python
class GitBookClient:
# ... 之前的方法 ...
def list_collections(self, org_id):
"""列出组织下的所有合集。"""
return self._request("GET", f"/orgs/{org_id}/collections")
def get_collection(self, collection_id):
"""获取合集详情。"""
return self._request("GET", f"/collections/{collection_id}")
def create_collection(self, org_id, title, description=None):
"""创建新合集。"""
data = {"title": title}
if description:
data["description"] = description
return self._request(
"POST",
f"/orgs/{org_id}/collections",
data=data
)
def add_space_to_collection(self, collection_id, space_id):
"""向合集中添加空间。"""
return self._request(
"POST",
f"/collections/{collection_id}/spaces/{space_id}"
)
def list_collection_spaces(self, collection_id):
"""列出合集中的空间。"""
return self._request(
"GET",
f"/collections/{collection_id}/spaces"
)Create collection and add spaces
创建合集并添加空间
collection = client.create_collection(
org_id="org_xxxxx",
title="API Reference",
description="All API documentation"
)
client.add_space_to_collection(collection["id"], "space_xxxxx")
undefinedcollection = client.create_collection(
org_id="org_xxxxx",
title="API Reference",
description="All API documentation"
)
client.add_space_to_collection(collection["id"], "space_xxxxx")
undefined5. Content Variants (Versions)
5. 内容版本变体(多版本)
REST API - Variants:
bash
undefinedREST API - 版本变体操作:
bash
undefinedList variants for space
列出空间的所有版本变体
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/variants" | jq
"$API_BASE/spaces/SPACE_ID/variants" | jq
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/variants" | jq
"$API_BASE/spaces/SPACE_ID/variants" | jq
Create variant
创建版本变体
curl -s -X POST -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID/variants"
-d '{ "title": "v2.0", "slug": "v2" }' | jq
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID/variants"
-d '{ "title": "v2.0", "slug": "v2" }' | jq
curl -s -X POST -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID/variants"
-d '{ "title": "v2.0", "slug": "v2" }' | jq
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID/variants"
-d '{ "title": "v2.0", "slug": "v2" }' | jq
Get variant content
获取版本变体内容
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/variants/VARIANT_ID/content" | jq
"$API_BASE/spaces/SPACE_ID/variants/VARIANT_ID/content" | jq
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/variants/VARIANT_ID/content" | jq
"$API_BASE/spaces/SPACE_ID/variants/VARIANT_ID/content" | jq
Set primary variant
设置主版本变体
curl -s -X PUT -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/variants/VARIANT_ID/primary" | jq
"$API_BASE/spaces/SPACE_ID/variants/VARIANT_ID/primary" | jq
curl -s -X PUT -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/variants/VARIANT_ID/primary" | jq
"$API_BASE/spaces/SPACE_ID/variants/VARIANT_ID/primary" | jq
Delete variant
删除版本变体
curl -s -X DELETE -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/variants/VARIANT_ID"
"$API_BASE/spaces/SPACE_ID/variants/VARIANT_ID"
**Python - Variants:**
```python
class GitBookClient:
# ... previous methods ...
def list_variants(self, space_id):
"""List all variants for space."""
return self._request("GET", f"/spaces/{space_id}/variants")
def create_variant(self, space_id, title, slug):
"""Create a new variant."""
return self._request(
"POST",
f"/spaces/{space_id}/variants",
data={"title": title, "slug": slug}
)
def get_variant_content(self, space_id, variant_id):
"""Get variant content."""
return self._request(
"GET",
f"/spaces/{space_id}/variants/{variant_id}/content"
)
def set_primary_variant(self, space_id, variant_id):
"""Set variant as primary."""
return self._request(
"PUT",
f"/spaces/{space_id}/variants/{variant_id}/primary"
)curl -s -X DELETE -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/variants/VARIANT_ID"
"$API_BASE/spaces/SPACE_ID/variants/VARIANT_ID"
**Python - 版本变体操作:**
```python
class GitBookClient:
# ... 之前的方法 ...
def list_variants(self, space_id):
"""列出空间的所有版本变体。"""
return self._request("GET", f"/spaces/{space_id}/variants")
def create_variant(self, space_id, title, slug):
"""创建新的版本变体。"""
return self._request(
"POST",
f"/spaces/{space_id}/variants",
data={"title": title, "slug": slug}
)
def get_variant_content(self, space_id, variant_id):
"""获取版本变体内容。"""
return self._request(
"GET",
f"/spaces/{space_id}/variants/{variant_id}/content"
)
def set_primary_variant(self, space_id, variant_id):
"""设置主版本变体。"""
return self._request(
"PUT",
f"/spaces/{space_id}/variants/{variant_id}/primary"
)Create version variants
创建版本变体
client.create_variant("space_xxxxx", "Version 1.0", "v1")
client.create_variant("space_xxxxx", "Version 2.0", "v2")
client.set_primary_variant("space_xxxxx", "variant_v2")
undefinedclient.create_variant("space_xxxxx", "Version 1.0", "v1")
client.create_variant("space_xxxxx", "Version 2.0", "v2")
client.set_primary_variant("space_xxxxx", "variant_v2")
undefined6. Git Synchronization
6. Git同步
GitBook YAML Configuration:
yaml
undefinedGitBook YAML配置:
yaml
undefined.gitbook.yaml - Repository configuration
.gitbook.yaml - 仓库配置
Root path for documentation
文档根路径
root: ./docs/
root: ./docs/
Structure file (table of contents)
结构文件(目录)
structure:
readme: README.md
summary: SUMMARY.md
structure:
readme: README.md
summary: SUMMARY.md
Redirects for moved pages
页面移动后的重定向
redirects:
old-page: new-page.md
moved/page: new-location/page.md
**SUMMARY.md Structure:**
```markdownredirects:
old-page: new-page.md
moved/page: new-location/page.md
**SUMMARY.md结构:**
```markdownSummary
Summary
Getting Started
Getting Started
- Introduction
- Installation
- Quick Start
- Configuration
- Introduction
- Installation
- Quick Start
- Configuration
User Guide
User Guide
- Overview
- Basic Usage
- Advanced Topics
- Topic 1
- Topic 2
- Overview
- Basic Usage
- Advanced Topics
- Topic 1
- Topic 2
API Reference
API Reference
- REST API
- SDKs
- Webhooks
- REST API
- SDKs
- Webhooks
Resources
Resources
- FAQ
- Troubleshooting
- Changelog
**Git Workflow Script:**
```python
#!/usr/bin/env python3
"""gitbook_sync.py - GitBook Git synchronization helper"""
import subprocess
import os
from pathlib import Path
class GitBookSyncHelper:
"""Helper for GitBook Git synchronization."""
def __init__(self, repo_path, docs_path="docs"):
self.repo_path = Path(repo_path)
self.docs_path = self.repo_path / docs_path
def validate_structure(self):
"""Validate GitBook structure."""
issues = []
# Check for SUMMARY.md
summary_path = self.docs_path / "SUMMARY.md"
if not summary_path.exists():
issues.append("Missing SUMMARY.md")
# Check for README.md
readme_path = self.docs_path / "README.md"
if not readme_path.exists():
issues.append("Missing README.md")
# Validate SUMMARY.md links
if summary_path.exists():
with open(summary_path) as f:
content = f.read()
import re
links = re.findall(r'\[.*?\]\((.*?\.md)\)', content)
for link in links:
file_path = self.docs_path / link
if not file_path.exists():
issues.append(f"Broken link: {link}")
return issues
def generate_summary(self, exclude_patterns=None):
"""Auto-generate SUMMARY.md from directory structure."""
exclude_patterns = exclude_patterns or ["_*", ".*"]
lines = ["# Summary\n"]
def process_dir(dir_path, indent=0):
items = sorted(dir_path.iterdir())
for item in items:
# Skip excluded patterns
if any(item.match(p) for p in exclude_patterns):
continue
relative_path = item.relative_to(self.docs_path)
if item.is_dir():
# Check for README.md in directory
readme = item / "README.md"
if readme.exists():
title = self._get_title(readme) or item.name
lines.append(
f"{' ' * indent}* [{title}]({relative_path}/README.md)"
)
else:
lines.append(f"\n{' ' * indent}## {item.name}\n")
process_dir(item, indent + 1)
elif item.suffix == ".md" and item.name != "README.md":
title = self._get_title(item) or item.stem
lines.append(
f"{' ' * indent}* [{title}]({relative_path})"
)
process_dir(self.docs_path)
return "\n".join(lines)
def _get_title(self, md_path):
"""Extract title from markdown file."""
with open(md_path) as f:
for line in f:
if line.startswith("# "):
return line[2:].strip()
return None
def sync_to_git(self, message="Update documentation"):
"""Commit and push changes."""
os.chdir(self.repo_path)
subprocess.run(["git", "add", "-A"])
subprocess.run(["git", "commit", "-m", message])
subprocess.run(["git", "push"])- FAQ
- Troubleshooting
- Changelog
**Git工作流脚本:**
```python
#!/usr/bin/env python3
"""gitbook_sync.py - GitBook Git同步助手"""
import subprocess
import os
from pathlib import Path
class GitBookSyncHelper:
"""GitBook Git同步助手。"""
def __init__(self, repo_path, docs_path="docs"):
self.repo_path = Path(repo_path)
self.docs_path = self.repo_path / docs_path
def validate_structure(self):
"""验证GitBook结构。"""
issues = []
# 检查SUMMARY.md是否存在
summary_path = self.docs_path / "SUMMARY.md"
if not summary_path.exists():
issues.append("Missing SUMMARY.md")
# 检查README.md是否存在
readme_path = self.docs_path / "README.md"
if not readme_path.exists():
issues.append("Missing README.md")
# 验证SUMMARY.md中的链接
if summary_path.exists():
with open(summary_path) as f:
content = f.read()
import re
links = re.findall(r'\[.*?\]\((.*?\.md)\)', content)
for link in links:
file_path = self.docs_path / link
if not file_path.exists():
issues.append(f"Broken link: {link}")
return issues
def generate_summary(self, exclude_patterns=None):
"""根据目录结构自动生成SUMMARY.md。"""
exclude_patterns = exclude_patterns or ["_*", ".*"]
lines = ["# Summary\n"]
def process_dir(dir_path, indent=0):
items = sorted(dir_path.iterdir())
for item in items:
# 跳过排除的文件/目录
if any(item.match(p) for p in exclude_patterns):
continue
relative_path = item.relative_to(self.docs_path)
if item.is_dir():
# 检查目录中是否有README.md
readme = item / "README.md"
if readme.exists():
title = self._get_title(readme) or item.name
lines.append(
f"{' ' * indent}* [{title}]({relative_path}/README.md)"
)
else:
lines.append(f"\n{' ' * indent}## {item.name}\n")
process_dir(item, indent + 1)
elif item.suffix == ".md" and item.name != "README.md":
title = self._get_title(item) or item.stem
lines.append(
f"{' ' * indent}* [{title}]({relative_path})"
)
process_dir(self.docs_path)
return "\n".join(lines)
def _get_title(self, md_path):
"""从Markdown文件中提取标题。"""
with open(md_path) as f:
for line in f:
if line.startswith("# "):
return line[2:].strip()
return None
def sync_to_git(self, message="Update documentation"):
"""提交并推送更改。"""
os.chdir(self.repo_path)
subprocess.run(["git", "add", "-A"])
subprocess.run(["git", "commit", "-m", message])
subprocess.run(["git", "push"])Example usage
使用示例
if name == "main":
helper = GitBookSyncHelper("./my-docs-repo", "docs")
# Validate
issues = helper.validate_structure()
if issues:
print("Structure issues found:")
for issue in issues:
print(f" - {issue}")
else:
print("Structure valid!")
# Generate SUMMARY.md
summary = helper.generate_summary()
print("\nGenerated SUMMARY.md:")
print(summary)undefinedif name == "main":
helper = GitBookSyncHelper("./my-docs-repo", "docs")
# 验证结构
issues = helper.validate_structure()
if issues:
print("Structure issues found:")
for issue in issues:
print(f" - {issue}")
else:
print("Structure valid!")
# 生成SUMMARY.md
summary = helper.generate_summary()
print("\nGenerated SUMMARY.md:")
print(summary)undefined7. Team Collaboration
7. 团队协作
REST API - Members:
bash
undefinedREST API - 成员管理:
bash
undefinedList organization members
列出组织成员
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/orgs/ORG_ID/members" | jq
"$API_BASE/orgs/ORG_ID/members" | jq
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/orgs/ORG_ID/members" | jq
"$API_BASE/orgs/ORG_ID/members" | jq
Invite member
邀请成员
curl -s -X POST -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/orgs/ORG_ID/invites"
-d '{ "email": "user@example.com", "role": "editor" }' | jq
-H "Content-Type: application/json"
"$API_BASE/orgs/ORG_ID/invites"
-d '{ "email": "user@example.com", "role": "editor" }' | jq
curl -s -X POST -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/orgs/ORG_ID/invites"
-d '{ "email": "user@example.com", "role": "editor" }' | jq
-H "Content-Type: application/json"
"$API_BASE/orgs/ORG_ID/invites"
-d '{ "email": "user@example.com", "role": "editor" }' | jq
Update member role
更新成员角色
curl -s -X PATCH -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/orgs/ORG_ID/members/MEMBER_ID"
-d '{ "role": "admin" }' | jq
-H "Content-Type: application/json"
"$API_BASE/orgs/ORG_ID/members/MEMBER_ID"
-d '{ "role": "admin" }' | jq
curl -s -X PATCH -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/orgs/ORG_ID/members/MEMBER_ID"
-d '{ "role": "admin" }' | jq
-H "Content-Type: application/json"
"$API_BASE/orgs/ORG_ID/members/MEMBER_ID"
-d '{ "role": "admin" }' | jq
Remove member
移除成员
curl -s -X DELETE -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/orgs/ORG_ID/members/MEMBER_ID"
"$API_BASE/orgs/ORG_ID/members/MEMBER_ID"
curl -s -X DELETE -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/orgs/ORG_ID/members/MEMBER_ID"
"$API_BASE/orgs/ORG_ID/members/MEMBER_ID"
List pending invites
列出待处理的邀请
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/orgs/ORG_ID/invites" | jq
"$API_BASE/orgs/ORG_ID/invites" | jq
**Python - Collaboration:**
```python
class GitBookClient:
# ... previous methods ...
def list_members(self, org_id):
"""List organization members."""
return self._request("GET", f"/orgs/{org_id}/members")
def invite_member(self, org_id, email, role="editor"):
"""Invite member to organization."""
return self._request(
"POST",
f"/orgs/{org_id}/invites",
data={"email": email, "role": role}
)
def update_member_role(self, org_id, member_id, role):
"""Update member's role."""
return self._request(
"PATCH",
f"/orgs/{org_id}/members/{member_id}",
data={"role": role}
)
def remove_member(self, org_id, member_id):
"""Remove member from organization."""
return self._request(
"DELETE",
f"/orgs/{org_id}/members/{member_id}"
)curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/orgs/ORG_ID/invites" | jq
"$API_BASE/orgs/ORG_ID/invites" | jq
**Python - 协作管理:**
```python
class GitBookClient:
# ... 之前的方法 ...
def list_members(self, org_id):
"""列出组织成员。"""
return self._request("GET", f"/orgs/{org_id}/members")
def invite_member(self, org_id, email, role="editor"):
"""邀请成员加入组织。"""
return self._request(
"POST",
f"/orgs/{org_id}/invites",
data={"email": email, "role": role}
)
def update_member_role(self, org_id, member_id, role):
"""更新成员角色。"""
return self._request(
"PATCH",
f"/orgs/{org_id}/members/{member_id}",
data={"role": role}
)
def remove_member(self, org_id, member_id):
"""从组织中移除成员。"""
return self._request(
"DELETE",
f"/orgs/{org_id}/members/{member_id}"
)Roles: "admin", "creator", "editor", "reviewer", "reader"
角色选项: "admin", "creator", "editor", "reviewer", "reader"
client.invite_member("org_xxxxx", "newuser@example.com", role="editor")
undefinedclient.invite_member("org_xxxxx", "newuser@example.com", role="editor")
undefined8. Custom Domains and Branding
8. 自定义域名与品牌
REST API - Customization:
bash
undefinedREST API - 自定义设置:
bash
undefinedGet space customization
获取空间自定义设置
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/publishing/customization" | jq
"$API_BASE/spaces/SPACE_ID/publishing/customization" | jq
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/publishing/customization" | jq
"$API_BASE/spaces/SPACE_ID/publishing/customization" | jq
Update customization
更新自定义设置
curl -s -X PATCH -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID/publishing/customization"
-d '{ "favicon": "https://example.com/favicon.ico", "logo": { "light": "https://example.com/logo-light.png", "dark": "https://example.com/logo-dark.png" }, "themes": { "default": "light", "toggeable": true }, "styling": { "primaryColor": "#0066FF", "font": "Inter" } }' | jq
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID/publishing/customization"
-d '{ "favicon": "https://example.com/favicon.ico", "logo": { "light": "https://example.com/logo-light.png", "dark": "https://example.com/logo-dark.png" }, "themes": { "default": "light", "toggeable": true }, "styling": { "primaryColor": "#0066FF", "font": "Inter" } }' | jq
curl -s -X PATCH -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID/publishing/customization"
-d '{ "favicon": "https://example.com/favicon.ico", "logo": { "light": "https://example.com/logo-light.png", "dark": "https://example.com/logo-dark.png" }, "themes": { "default": "light", "toggeable": true }, "styling": { "primaryColor": "#0066FF", "font": "Inter" } }' | jq
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID/publishing/customization"
-d '{ "favicon": "https://example.com/favicon.ico", "logo": { "light": "https://example.com/logo-light.png", "dark": "https://example.com/logo-dark.png" }, "themes": { "default": "light", "toggeable": true }, "styling": { "primaryColor": "#0066FF", "font": "Inter" } }' | jq
Get custom domain settings
获取自定义域名设置
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/publishing/customization/hostname" | jq
"$API_BASE/spaces/SPACE_ID/publishing/customization/hostname" | jq
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/publishing/customization/hostname" | jq
"$API_BASE/spaces/SPACE_ID/publishing/customization/hostname" | jq
Set custom domain
设置自定义域名
curl -s -X PUT -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID/publishing/customization/hostname"
-d '{ "hostname": "docs.example.com" }' | jq
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID/publishing/customization/hostname"
-d '{ "hostname": "docs.example.com" }' | jq
**Python - Customization:**
```python
class GitBookClient:
# ... previous methods ...
def get_customization(self, space_id):
"""Get space customization settings."""
return self._request(
"GET",
f"/spaces/{space_id}/publishing/customization"
)
def update_customization(self, space_id, settings):
"""Update space customization."""
return self._request(
"PATCH",
f"/spaces/{space_id}/publishing/customization",
data=settings
)
def set_custom_domain(self, space_id, hostname):
"""Set custom domain for space."""
return self._request(
"PUT",
f"/spaces/{space_id}/publishing/customization/hostname",
data={"hostname": hostname}
)curl -s -X PUT -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID/publishing/customization/hostname"
-d '{ "hostname": "docs.example.com" }' | jq
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID/publishing/customization/hostname"
-d '{ "hostname": "docs.example.com" }' | jq
**Python - 自定义设置:**
```python
class GitBookClient:
# ... 之前的方法 ...
def get_customization(self, space_id):
"""获取空间自定义设置。"""
return self._request(
"GET",
f"/spaces/{space_id}/publishing/customization"
)
def update_customization(self, space_id, settings):
"""更新空间自定义设置。"""
return self._request(
"PATCH",
f"/spaces/{space_id}/publishing/customization",
data=settings
)
def set_custom_domain(self, space_id, hostname):
"""为空间设置自定义域名。"""
return self._request(
"PUT",
f"/spaces/{space_id}/publishing/customization/hostname",
data={"hostname": hostname}
)Update branding
更新品牌设置
client.update_customization("space_xxxxx", {
"styling": {
"primaryColor": "#6366F1",
"font": "Inter"
},
"themes": {
"default": "light",
"toggeable": True
}
})
undefinedclient.update_customization("space_xxxxx", {
"styling": {
"primaryColor": "#6366F1",
"font": "Inter"
},
"themes": {
"default": "light",
"toggeable": True
}
})
undefinedComplete Examples
完整示例
Example 1: Documentation Site Builder
示例1:文档站点构建器
python
#!/usr/bin/env python3
"""docs_site_builder.py - Build complete documentation site"""
import os
from datetime import datetime
import json
class DocsSiteBuilder:
"""Build and manage GitBook documentation sites."""
def __init__(self, api_token, org_id):
self.client = GitBookClient(api_token)
self.org_id = org_id
def create_docs_site(
self,
title,
description=None,
visibility="public",
custom_domain=None,
branding=None
):
"""
Create complete documentation site.
Args:
title: Site title
description: Site description
visibility: "public" or "private"
custom_domain: Custom domain name
branding: Branding settings dict
Returns:
Space details
"""
# Create space
space = self.client.create_space(
org_id=self.org_id,
title=title,
visibility=visibility
)
space_id = space["id"]
print(f"Created space: {space_id}")
# Apply customization
if branding:
self.client.update_customization(space_id, branding)
print("Applied branding")
# Set custom domain
if custom_domain:
self.client.set_custom_domain(space_id, custom_domain)
print(f"Set custom domain: {custom_domain}")
return space
def setup_versioned_docs(self, space_id, versions):
"""
Set up version variants for documentation.
Args:
space_id: Space ID
versions: List of version dicts with title and slug
"""
for version in versions:
variant = self.client.create_variant(
space_id,
title=version["title"],
slug=version["slug"]
)
print(f"Created variant: {version['title']}")
if version.get("primary"):
self.client.set_primary_variant(space_id, variant["id"])
print(f"Set {version['title']} as primary")
def create_docs_collection(self, title, space_ids):
"""
Create collection and add spaces.
Args:
title: Collection title
space_ids: List of space IDs to add
"""
collection = self.client.create_collection(
org_id=self.org_id,
title=title
)
for space_id in space_ids:
self.client.add_space_to_collection(collection["id"], space_id)
print(f"Created collection '{title}' with {len(space_ids)} spaces")
return collectionpython
#!/usr/bin/env python3
"""docs_site_builder.py - 构建完整的文档站点"""
import os
from datetime import datetime
import json
class DocsSiteBuilder:
"""构建并管理GitBook文档站点。"""
def __init__(self, api_token, org_id):
self.client = GitBookClient(api_token)
self.org_id = org_id
def create_docs_site(
self,
title,
description=None,
visibility="public",
custom_domain=None,
branding=None
):
"""
创建完整的文档站点。
参数:
title: 站点标题
description: 站点描述
visibility: "public" 或 "private"
custom_domain: 自定义域名
branding: 品牌设置字典
返回:
空间详情
"""
# 创建空间
space = self.client.create_space(
org_id=self.org_id,
title=title,
visibility=visibility
)
space_id = space["id"]
print(f"Created space: {space_id}")
# 应用自定义品牌设置
if branding:
self.client.update_customization(space_id, branding)
print("Applied branding")
# 设置自定义域名
if custom_domain:
self.client.set_custom_domain(space_id, custom_domain)
print(f"Set custom domain: {custom_domain}")
return space
def setup_versioned_docs(self, space_id, versions):
"""
为文档设置多版本变体。
参数:
space_id: 空间ID
versions: 包含title和slug的版本字典列表
"""
for version in versions:
variant = self.client.create_variant(
space_id,
title=version["title"],
slug=version["slug"]
)
print(f"Created variant: {version['title']}")
if version.get("primary"):
self.client.set_primary_variant(space_id, variant["id"])
print(f"Set {version['title']} as primary")
def create_docs_collection(self, title, space_ids):
"""
创建合集并添加空间。
参数:
title: 合集标题
space_ids: 要添加的空间ID列表
"""
collection = self.client.create_collection(
org_id=self.org_id,
title=title
)
for space_id in space_ids:
self.client.add_space_to_collection(collection["id"], space_id)
print(f"Created collection '{title}' with {len(space_ids)} spaces")
return collectionExample usage
使用示例
if name == "main":
builder = DocsSiteBuilder(
api_token=os.environ["GITBOOK_API_TOKEN"],
org_id="org_xxxxx"
)
# Create main docs site
space = builder.create_docs_site(
title="Product Documentation",
description="Complete product documentation",
visibility="public",
branding={
"styling": {
"primaryColor": "#0066FF",
"font": "Inter"
},
"themes": {
"default": "light",
"toggeable": True
}
}
)
# Set up versions
builder.setup_versioned_docs(space["id"], [
{"title": "v1.0", "slug": "v1"},
{"title": "v2.0", "slug": "v2", "primary": True},
{"title": "Latest", "slug": "latest"}
])undefinedif name == "main":
builder = DocsSiteBuilder(
api_token=os.environ["GITBOOK_API_TOKEN"],
org_id="org_xxxxx"
)
# 创建主文档站点
space = builder.create_docs_site(
title="Product Documentation",
description="Complete product documentation",
visibility="public",
branding={
"styling": {
"primaryColor": "#0066FF",
"font": "Inter"
},
"themes": {
"default": "light",
"toggeable": True
}
}
)
# 设置多版本
builder.setup_versioned_docs(space["id"], [
{"title": "v1.0", "slug": "v1"},
{"title": "v2.0", "slug": "v2", "primary": True},
{"title": "Latest", "slug": "latest"}
])undefinedExample 2: Content Migration Tool
示例2:内容迁移工具
python
#!/usr/bin/env python3
"""content_migration.py - Migrate content to GitBook"""
import os
from pathlib import Path
import re
import shutil
class ContentMigrator:
"""Migrate content from various formats to GitBook."""
def __init__(self, source_path, output_path):
self.source_path = Path(source_path)
self.output_path = Path(output_path)
def migrate_mkdocs(self):
"""
Migrate MkDocs project to GitBook format.
"""
# Copy markdown files
docs_src = self.source_path / "docs"
if not docs_src.exists():
docs_src = self.source_path
shutil.copytree(docs_src, self.output_path, dirs_exist_ok=True)
# Convert mkdocs.yml nav to SUMMARY.md
mkdocs_config = self.source_path / "mkdocs.yml"
if mkdocs_config.exists():
summary = self._convert_mkdocs_nav(mkdocs_config)
(self.output_path / "SUMMARY.md").write_text(summary)
# Create .gitbook.yaml
gitbook_config = """
root: ./
structure:
readme: README.md
summary: SUMMARY.md
"""
(self.output_path / ".gitbook.yaml").write_text(gitbook_config)
print(f"Migrated MkDocs project to: {self.output_path}")
def _convert_mkdocs_nav(self, mkdocs_path):
"""Convert MkDocs nav to SUMMARY.md format."""
import yaml
with open(mkdocs_path) as f:
config = yaml.safe_load(f)
nav = config.get("nav", [])
lines = ["# Summary\n"]
def process_nav(items, indent=0):
for item in items:
if isinstance(item, dict):
for title, value in item.items():
if isinstance(value, str):
lines.append(f"{' ' * indent}* [{title}]({value})")
elif isinstance(value, list):
lines.append(f"\n{' ' * indent}## {title}\n")
process_nav(value, indent + 1)
elif isinstance(item, str):
lines.append(f"{' ' * indent}* [{item}]({item})")
process_nav(nav)
return "\n".join(lines)
def migrate_docusaurus(self):
"""Migrate Docusaurus project to GitBook format."""
docs_src = self.source_path / "docs"
# Copy docs
shutil.copytree(docs_src, self.output_path, dirs_exist_ok=True)
# Convert sidebars.js to SUMMARY.md
sidebars = self.source_path / "sidebars.js"
if sidebars.exists():
# Basic conversion (would need proper JS parsing for complex sidebars)
summary = self._generate_summary_from_files()
(self.output_path / "SUMMARY.md").write_text(summary)
# Create .gitbook.yaml
(self.output_path / ".gitbook.yaml").write_text("""
root: ./
structure:
readme: intro.md
summary: SUMMARY.md
""")
print(f"Migrated Docusaurus project to: {self.output_path}")
def _generate_summary_from_files(self):
"""Generate SUMMARY.md from file structure."""
lines = ["# Summary\n"]
for md_file in sorted(self.output_path.rglob("*.md")):
if md_file.name == "SUMMARY.md":
continue
relative = md_file.relative_to(self.output_path)
title = self._extract_title(md_file) or md_file.stem
depth = len(relative.parts) - 1
lines.append(f"{' ' * depth}* [{title}]({relative})")
return "\n".join(lines)
def _extract_title(self, md_path):
"""Extract title from markdown file."""
content = md_path.read_text()
# Check for frontmatter title
if content.startswith("---"):
match = re.search(r"title:\s*[\"']?(.+?)[\"']?\n", content)
if match:
return match.group(1)
# Check for H1
match = re.search(r"^#\s+(.+)$", content, re.MULTILINE)
if match:
return match.group(1)
return None
def fix_links(self):
"""Fix relative links for GitBook."""
for md_file in self.output_path.rglob("*.md"):
content = md_file.read_text()
# Fix relative links without .md extension
content = re.sub(
r'\[([^\]]+)\]\((?!http)([^)]+)(?<!\.md)\)',
r'[\1](\2.md)',
content
)
# Fix image paths
content = re.sub(
r'!\[([^\]]*)\]\((?!http)\.\./',
r'
md_file.write_text(content)
print("Fixed links in all markdown files")python
#!/usr/bin/env python3
"""content_migration.py - 将内容迁移到GitBook"""
import os
from pathlib import Path
import re
import shutil
class ContentMigrator:
"""将各种格式的内容迁移到GitBook。"""
def __init__(self, source_path, output_path):
self.source_path = Path(source_path)
self.output_path = Path(output_path)
def migrate_mkdocs(self):
"""
将MkDocs项目迁移到GitBook格式。
"""
# 复制Markdown文件
docs_src = self.source_path / "docs"
if not docs_src.exists():
docs_src = self.source_path
shutil.copytree(docs_src, self.output_path, dirs_exist_ok=True)
# 将mkdocs.yml导航转换为SUMMARY.md
mkdocs_config = self.source_path / "mkdocs.yml"
if mkdocs_config.exists():
summary = self._convert_mkdocs_nav(mkdocs_config)
(self.output_path / "SUMMARY.md").write_text(summary)
# 创建.gitbook.yaml
gitbook_config = """
root: ./
structure:
readme: README.md
summary: SUMMARY.md
"""
(self.output_path / ".gitbook.yaml").write_text(gitbook_config)
print(f"Migrated MkDocs project to: {self.output_path}")
def _convert_mkdocs_nav(self, mkdocs_path):
"""将MkDocs导航转换为SUMMARY.md格式。"""
import yaml
with open(mkdocs_path) as f:
config = yaml.safe_load(f)
nav = config.get("nav", [])
lines = ["# Summary\n"]
def process_nav(items, indent=0):
for item in items:
if isinstance(item, dict):
for title, value in item.items():
if isinstance(value, str):
lines.append(f"{' ' * indent}* [{title}]({value})")
elif isinstance(value, list):
lines.append(f"\n{' ' * indent}## {title}\n")
process_nav(value, indent + 1)
elif isinstance(item, str):
lines.append(f"{' ' * indent}* [{item}]({item})")
process_nav(nav)
return "\n".join(lines)
def migrate_docusaurus(self):
"""
将Docusaurus项目迁移到GitBook格式。
"""
docs_src = self.source_path / "docs"
# 复制文档
shutil.copytree(docs_src, self.output_path, dirs_exist_ok=True)
# 将sidebars.js转换为SUMMARY.md
sidebars = self.source_path / "sidebars.js"
if sidebars.exists():
# 基础转换(复杂侧边栏需要专门的JS解析)
summary = self._generate_summary_from_files()
(self.output_path / "SUMMARY.md").write_text(summary)
# 创建.gitbook.yaml
(self.output_path / ".gitbook.yaml").write_text("""
root: ./
structure:
readme: intro.md
summary: SUMMARY.md
""")
print(f"Migrated Docusaurus project to: {self.output_path}")
def _generate_summary_from_files(self):
"""根据文件结构生成SUMMARY.md。"""
lines = ["# Summary\n"]
for md_file in sorted(self.output_path.rglob("*.md")):
if md_file.name == "SUMMARY.md":
continue
relative = md_file.relative_to(self.output_path)
title = self._extract_title(md_file) or md_file.stem
depth = len(relative.parts) - 1
lines.append(f"{' ' * depth}* [{title}]({relative})")
return "\n".join(lines)
def _extract_title(self, md_path):
"""从Markdown文件中提取标题。"""
content = md_path.read_text()
# 检查前置元数据中的标题
if content.startswith("---"):
match = re.search(r"title:\s*[\"']?(.+?)[\"']?\n", content)
if match:
return match.group(1)
# 检查一级标题
match = re.search(r"^#\s+(.+)$", content, re.MULTILINE)
if match:
return match.group(1)
return None
def fix_links(self):
"""修复GitBook的相对链接。"""
for md_file in self.output_path.rglob("*.md"):
content = md_file.read_text()
# 修复不带.md扩展名的相对链接
content = re.sub(
r'\[([^\]]+)\]\((?!http)([^)]+)(?<!\.md)\)',
r'[\1](\2.md)',
content
)
# 修复图片路径
content = re.sub(
r'!\[([^\]]*)\]\((?!http)\.\./',
r'
md_file.write_text(content)
print("Fixed links in all markdown files")Example usage
使用示例
if name == "main":
migrator = ContentMigrator(
source_path="./mkdocs-project",
output_path="./gitbook-docs"
)
migrator.migrate_mkdocs()
migrator.fix_links()undefinedif name == "main":
migrator = ContentMigrator(
source_path="./mkdocs-project",
output_path="./gitbook-docs"
)
migrator.migrate_mkdocs()
migrator.fix_links()undefinedExample 3: Documentation Analytics
示例3:文档分析工具
python
#!/usr/bin/env python3
"""docs_analytics.py - GitBook documentation analytics"""
import os
from datetime import datetime, timedelta
import json
class DocsAnalytics:
"""Analyze GitBook documentation usage."""
def __init__(self, api_token):
self.client = GitBookClient(api_token)
def get_space_stats(self, space_id):
"""Get statistics for a space."""
space = self.client.get_space(space_id)
content = self.client.get_space_content(space_id)
# Count pages
def count_pages(pages):
count = len(pages)
for page in pages:
if "pages" in page:
count += count_pages(page["pages"])
return count
page_count = count_pages(content.get("pages", []))
# Get variants
variants = self.client.list_variants(space_id)
return {
"space_id": space_id,
"title": space.get("title"),
"visibility": space.get("visibility"),
"page_count": page_count,
"variant_count": len(variants.get("items", [])),
"created_at": space.get("createdAt"),
"updated_at": space.get("updatedAt")
}
def audit_content(self, space_id):
"""Audit content for issues."""
content = self.client.get_space_content(space_id)
issues = []
def check_pages(pages, path=""):
for page in pages:
page_path = f"{path}/{page.get('slug', 'unknown')}"
# Check for missing titles
if not page.get("title"):
issues.append({
"type": "missing_title",
"path": page_path
})
# Check for empty pages
if not page.get("document"):
issues.append({
"type": "empty_page",
"path": page_path
})
# Recurse into child pages
if "pages" in page:
check_pages(page["pages"], page_path)
check_pages(content.get("pages", []))
return issues
def generate_report(self, org_id):
"""Generate analytics report for organization."""
spaces = self.client.list_spaces(org_id)
report = {
"generated_at": datetime.now().isoformat(),
"org_id": org_id,
"summary": {
"total_spaces": 0,
"total_pages": 0,
"public_spaces": 0,
"private_spaces": 0
},
"spaces": []
}
for space in spaces.get("items", []):
stats = self.get_space_stats(space["id"])
report["spaces"].append(stats)
report["summary"]["total_spaces"] += 1
report["summary"]["total_pages"] += stats["page_count"]
if stats["visibility"] == "public":
report["summary"]["public_spaces"] += 1
else:
report["summary"]["private_spaces"] += 1
return reportpython
#!/usr/bin/env python3
"""docs_analytics.py - GitBook文档使用分析"""
import os
from datetime import datetime, timedelta
import json
class DocsAnalytics:
"""分析GitBook文档的使用情况。"""
def __init__(self, api_token):
self.client = GitBookClient(api_token)
def get_space_stats(self, space_id):
"""获取空间统计数据。"""
space = self.client.get_space(space_id)
content = self.client.get_space_content(space_id)
# 统计页面数量
def count_pages(pages):
count = len(pages)
for page in pages:
if "pages" in page:
count += count_pages(page["pages"])
return count
page_count = count_pages(content.get("pages", []))
# 获取版本变体
variants = self.client.list_variants(space_id)
return {
"space_id": space_id,
"title": space.get("title"),
"visibility": space.get("visibility"),
"page_count": page_count,
"variant_count": len(variants.get("items", [])),
"created_at": space.get("createdAt"),
"updated_at": space.get("updatedAt")
}
def audit_content(self, space_id):
"""检查内容中的问题。"""
content = self.client.get_space_content(space_id)
issues = []
def check_pages(pages, path=""):
for page in pages:
page_path = f"{path}/{page.get('slug', 'unknown')}"
# 检查是否缺少标题
if not page.get("title"):
issues.append({
"type": "missing_title",
"path": page_path
})
# 检查是否为空页面
if not page.get("document"):
issues.append({
"type": "empty_page",
"path": page_path
})
# 递归检查子页面
if "pages" in page:
check_pages(page["pages"], page_path)
check_pages(content.get("pages", []))
return issues
def generate_report(self, org_id):
"""生成组织的文档分析报告。"""
spaces = self.client.list_spaces(org_id)
report = {
"generated_at": datetime.now().isoformat(),
"org_id": org_id,
"summary": {
"total_spaces": 0,
"total_pages": 0,
"public_spaces": 0,
"private_spaces": 0
},
"spaces": []
}
for space in spaces.get("items", []):
stats = self.get_space_stats(space["id"])
report["spaces"].append(stats)
report["summary"]["total_spaces"] += 1
report["summary"]["total_pages"] += stats["page_count"]
if stats["visibility"] == "public":
report["summary"]["public_spaces"] += 1
else:
report["summary"]["private_spaces"] += 1
return reportExample usage
使用示例
if name == "main":
analytics = DocsAnalytics(os.environ["GITBOOK_API_TOKEN"])
# Get org report
report = analytics.generate_report("org_xxxxx")
print(f"Documentation Analytics Report")
print(f"{'='*50}")
print(f"Total Spaces: {report['summary']['total_spaces']}")
print(f"Total Pages: {report['summary']['total_pages']}")
print(f"Public: {report['summary']['public_spaces']}")
print(f"Private: {report['summary']['private_spaces']}")
print(f"\nSpaces:")
for space in report["spaces"]:
print(f" - {space['title']}: {space['page_count']} pages")
# Save report
with open("docs_report.json", "w") as f:
json.dump(report, f, indent=2)undefinedif name == "main":
analytics = DocsAnalytics(os.environ["GITBOOK_API_TOKEN"])
# 获取组织报告
report = analytics.generate_report("org_xxxxx")
print(f"Documentation Analytics Report")
print(f"{'='*50}")
print(f"Total Spaces: {report['summary']['total_spaces']}")
print(f"Total Pages: {report['summary']['total_pages']}")
print(f"Public: {report['summary']['public_spaces']}")
print(f"Private: {report['summary']['private_spaces']}")
print(f"\nSpaces:")
for space in report["spaces"]:
print(f" - {space['title']}: {space['page_count']} pages")
# 保存报告
with open("docs_report.json", "w") as f:
json.dump(report, f, indent=2)undefinedIntegration Examples
集成示例
GitHub Actions for Git Sync
GitHub Actions实现Git同步
yaml
undefinedyaml
undefined.github/workflows/gitbook-sync.yml
.github/workflows/gitbook-sync.yml
name: Sync to GitBook
on:
push:
branches: [main]
paths:
- 'docs/**'
- 'SUMMARY.md'
jobs:
sync:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Validate Structure
run: |
# Check required files exist
test -f docs/README.md || echo "Missing docs/README.md"
test -f docs/SUMMARY.md || echo "Missing docs/SUMMARY.md"
# Check for broken links
python3 << 'EOF'
import re
from pathlib import Path
summary = Path("docs/SUMMARY.md").read_text()
links = re.findall(r'\[.*?\]\((.*?\.md)\)', summary)
for link in links:
path = Path("docs") / link
if not path.exists():
print(f"Broken link: {link}")
exit(1)
print("All links valid!")
EOF
- name: Notify on Success
if: success()
run: |
echo "Documentation synced successfully!"
# GitBook automatically pulls from connected repoundefinedname: Sync to GitBook
on:
push:
branches: [main]
paths:
- 'docs/**'
- 'SUMMARY.md'
jobs:
sync:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Validate Structure
run: |
# 检查必要文件是否存在
test -f docs/README.md || echo "Missing docs/README.md"
test -f docs/SUMMARY.md || echo "Missing docs/SUMMARY.md"
# 检查是否有失效链接
python3 << 'EOF'
import re
from pathlib import Path
summary = Path("docs/SUMMARY.md").read_text()
links = re.findall(r'\[.*?\]\((.*?\.md)\)', summary)
for link in links:
path = Path("docs") / link
if not path.exists():
print(f"Broken link: {link}")
exit(1)
print("All links valid!")
EOF
- name: Notify on Success
if: success()
run: |
echo "Documentation synced successfully!"
# GitBook会自动从关联仓库拉取更新undefinedSlack Notification for Updates
Slack通知文档更新
python
#!/usr/bin/env python3
"""slack_notify.py - Notify Slack of GitBook updates"""
import os
import requests
from datetime import datetime, timedelta
def notify_docs_update(space_title, update_type, details):
"""Send Slack notification for docs update."""
webhook_url = os.environ["SLACK_WEBHOOK_URL"]
message = {
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": f"Documentation Update: {space_title}"
}
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": f"*Type:*\n{update_type}"
},
{
"type": "mrkdwn",
"text": f"*Time:*\n{datetime.now().strftime('%Y-%m-%d %H:%M')}"
}
]
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": f"*Details:*\n{details}"
}
}
]
}
response = requests.post(webhook_url, json=message)
return response.status_code == 200python
#!/usr/bin/env python3
"""slack_notify.py - 文档更新时发送Slack通知"""
import os
import requests
from datetime import datetime, timedelta
def notify_docs_update(space_title, update_type, details):
"""发送Slack通知告知文档更新。"""
webhook_url = os.environ["SLACK_WEBHOOK_URL"]
message = {
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": f"Documentation Update: {space_title}"
}
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": f"*Type:*\n{update_type}"
},
{
"type": "mrkdwn",
"text": f"*Time:*\n{datetime.now().strftime('%Y-%m-%d %H:%M')}"
}
]
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": f"*Details:*\n{details}"
}
}
]
}
response = requests.post(webhook_url, json=message)
return response.status_code == 200Best Practices
最佳实践
1. Structure Content Properly
1. 合理组织内容结构
markdown
undefinedmarkdown
undefinedGood structure
良好的结构
docs/
├── README.md # Landing page
├── SUMMARY.md # Navigation
├── getting-started/
│ ├── README.md # Section intro
│ ├── installation.md
│ └── quickstart.md
└── guides/
├── README.md
└── ...
undefineddocs/
├── README.md # 首页
├── SUMMARY.md # 导航目录
├── getting-started/
│ ├── README.md # 章节介绍
│ ├── installation.md
│ └── quickstart.md
└── guides/
├── README.md
└── ...
undefined2. Use Meaningful Slugs
2. 使用有意义的路径别名
markdown
undefinedmarkdown
undefinedSUMMARY.md - Good slugs
SUMMARY.md - 良好的路径别名
- Installation Guide
- API Reference
- Installation Guide
- API Reference
Avoid
避免以下写法
- Page 1
- Untitled
undefined- Page 1
- Untitled
undefined3. Maintain Version Consistency
3. 保持版本一致性
python
undefinedpython
undefinedUse consistent version naming
使用统一的版本命名规则
versions = [
{"title": "v1.0", "slug": "v1"},
{"title": "v2.0", "slug": "v2"},
{"title": "Latest", "slug": "latest"}
]
undefinedversions = [
{"title": "v1.0", "slug": "v1"},
{"title": "v2.0", "slug": "v2"},
{"title": "Latest", "slug": "latest"}
]
undefined4. Validate Before Publish
4. 发布前验证内容
python
def validate_docs(docs_path):
"""Validate docs before publishing."""
issues = []
# Check SUMMARY.md exists
if not (docs_path / "SUMMARY.md").exists():
issues.append("Missing SUMMARY.md")
# Check all linked files exist
# Check for broken internal links
# Check image paths
return issuespython
def validate_docs(docs_path):
"""发布前验证文档。"""
issues = []
# 检查SUMMARY.md是否存在
if not (docs_path / "SUMMARY.md").exists():
issues.append("Missing SUMMARY.md")
# 检查所有链接的文件是否存在
# 检查内部失效链接
# 检查图片路径
return issuesTroubleshooting
故障排除
Common Issues
常见问题
Issue: 401 Unauthorized
bash
undefined问题:401 Unauthorized(未授权)
bash
undefinedVerify token
验证令牌有效性
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"https://api.gitbook.com/v1/user"
"https://api.gitbook.com/v1/user"
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"https://api.gitbook.com/v1/user"
"https://api.gitbook.com/v1/user"
Regenerate token at:
在以下地址重新生成令牌:
**Issue: Git sync not updating**
```bash
**问题:Git同步未更新**
```bashCheck Git connection in GitBook space settings
在GitBook空间设置中检查Git连接
Verify branch name matches
验证分支名称是否匹配
Check for merge conflicts
检查是否存在合并冲突
Force resync via API
通过API强制重新同步
curl -s -X POST -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"https://api.gitbook.com/v1/spaces/SPACE_ID/git/sync"
"https://api.gitbook.com/v1/spaces/SPACE_ID/git/sync"
**Issue: Broken links after migration**
```pythoncurl -s -X POST -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"https://api.gitbook.com/v1/spaces/SPACE_ID/git/sync"
"https://api.gitbook.com/v1/spaces/SPACE_ID/git/sync"
**问题:迁移后链接失效**
```pythonFix relative links
修复相对链接
import re
content = path.read_text()
import re
content = path.read_text()
Add .md extension to links
为链接添加.md扩展名
content = re.sub(
r'[([^]]+)]((?!http)([^)]+)(?<!.md))',
r'\1',
content
)
**Issue: Images not displaying**
```markdown
<!-- Use absolute paths from root -->

<!-- Or relative from current file -->
content = re.sub(
r'[([^]]+)]((?!http)([^)]+)(?<!.md))',
r'\1',
content
)
**问题:图片无法显示**
```markdown
<!-- 使用从根目录开始的绝对路径 -->

<!-- 或使用相对于当前文件的路径 -->
Version History
版本历史
- 1.0.0 (2026-01-17): Initial release
- Spaces management API
- Collections and variants
- Git synchronization
- Team collaboration
- Custom domains and branding
- Content migration tools
- Analytics and reporting
- GitHub Actions integration
- Best practices and troubleshooting
- 1.0.0 (2026-01-17): 初始版本
- 空间管理API
- 合集与版本变体
- Git同步
- 团队协作
- 自定义域名与品牌
- 内容迁移工具
- 分析与报告
- GitHub Actions集成
- 最佳实践与故障排除
Resources
参考资源
- GitBook Documentation: https://docs.gitbook.com/
- GitBook API Reference: https://developer.gitbook.com/
- Git Sync Guide: https://docs.gitbook.com/integrations/git-sync
- Custom Domains: https://docs.gitbook.com/published-documentation/custom-domain
Publish beautiful documentation with GitBook - spaces, collections, and seamless Git integration!
- GitBook官方文档: https://docs.gitbook.com/
- GitBook API参考: https://developer.gitbook.com/
- Git同步指南: https://docs.gitbook.com/integrations/git-sync
- 自定义域名: https://docs.gitbook.com/published-documentation/custom-domain
使用GitBook发布美观的文档——空间、合集与无缝Git集成!