This is an automated email from the ASF dual-hosted git repository.
jin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-hugegraph-doc.git
The following commit(s) were added to refs/heads/master by this push:
new 202d930d feat: harden documentation link validation to prevent false
CI passes (#452)
202d930d is described below
commit 202d930db67e59c3774adbf2098be1d0664d095b
Author: Himanshu Verma <[email protected]>
AuthorDate: Thu Feb 12 12:39:34 2026 +0530
feat: harden documentation link validation to prevent false CI passes (#452)
* feat: enhance link validator to catch all internal links
- Add support for relative link validation
- Check absolute root paths (e.g., /language/*)
- Skip asset files (.png, .xml, .css, etc.)
- Strip code blocks from validation
- Add case-insensitive protocol detection
---
content/cn/docs/SUMMARY.md | 126 ++++-----
content/cn/docs/clients/restful-api/auth.md | 2 +-
content/cn/docs/clients/restful-api/edgelabel.md | 2 +-
content/cn/docs/clients/restful-api/gremlin.md | 4 +-
content/cn/docs/clients/restful-api/indexlabel.md | 2 +-
content/cn/docs/clients/restful-api/rebuild.md | 6 +-
content/cn/docs/clients/restful-api/vertexlabel.md | 2 +-
content/cn/docs/config/config-guide.md | 2 +-
.../cn/docs/contribution-guidelines/contribute.md | 2 +-
content/cn/docs/quickstart/hugegraph-studio.md | 2 +-
content/en/docs/SUMMARY.md | 103 ++++---
content/en/docs/clients/restful-api/auth.md | 2 +-
content/en/docs/clients/restful-api/edgelabel.md | 2 +-
content/en/docs/clients/restful-api/gremlin.md | 4 +-
content/en/docs/clients/restful-api/indexlabel.md | 2 +-
content/en/docs/clients/restful-api/rebuild.md | 6 +-
content/en/docs/clients/restful-api/vertexlabel.md | 2 +-
content/en/docs/config/config-guide.md | 2 +-
.../en/docs/contribution-guidelines/contribute.md | 2 +-
content/en/docs/quickstart/hugegraph-studio.md | 2 +-
dist/validate-links.sh | 315 ++++++++++++++++++---
21 files changed, 404 insertions(+), 188 deletions(-)
diff --git a/content/cn/docs/SUMMARY.md b/content/cn/docs/SUMMARY.md
index 48f910d0..ab5e32bf 100644
--- a/content/cn/docs/SUMMARY.md
+++ b/content/cn/docs/SUMMARY.md
@@ -1,81 +1,77 @@
# HugeGraph Docs
-* [Download](download.md)
+* [Download](download/download)
## Quickstart
-* [Install HugeGraph-Server](quickstart/hugegraph-server.md)
-* [Load data with HugeGraph-Loader](quickstart/hugegraph-loader.md)
-* [Visual with HugeGraph-Hubble](quickstart/hugegraph-hubble.md)
-* [Develop with HugeGraph-Client](quickstart/hugegraph-client.md)
-* [Manage with HugeGraph-Tools](quickstart/hugegraph-tools.md)
-* [Analysis with HugeGraph-Computer](quickstart/hugegraph-computer.md)
-* [Display with HugeGraph-Studio](quickstart/hugegraph-studio.md)
+* [Install HugeGraph-Server](quickstart/hugegraph/hugegraph-server)
+* [Load data with HugeGraph-Loader](quickstart/toolchain/hugegraph-loader)
+* [Visual with HugeGraph-Hubble](quickstart/toolchain/hugegraph-hubble)
+* [Develop with HugeGraph-Client](quickstart/client/hugegraph-client)
+* [Manage with HugeGraph-Tools](quickstart/toolchain/hugegraph-tools)
+* [Analysis with HugeGraph-Computer](quickstart/computing/hugegraph-computer)
## Config
-* [Config Guide](config/config-guide.md)
-* [Config Options](config/config-option.md)
-* [Config Authentication](config/config-authentication.md)
-* [Config HTTPS](config/config-https.md)
-* [Config Computer](config/config-computer.md)
+* [Config Guide](config/config-guide)
+* [Config Options](config/config-option)
+* [Config Authentication](config/config-authentication)
+* [Config HTTPS](config/config-https)
+* [Config Computer](quickstart/computing/hugegraph-computer)
## API
-* [RESTful API](clients/hugegraph-api.md)
- * [Schema](clients/restful-api/schema.md)
- * [PropertyKey](clients/restful-api/propertykey.md)
- * [VertexLabel](clients/restful-api/vertexlabel.md)
- * [EdgeLabel](clients/restful-api/edgelabel.md)
- * [IndexLabel](clients/restful-api/indexlabel.md)
- * [Rebuild](clients/restful-api/rebuild.md)
- * [Vertex](clients/restful-api/vertex.md)
- * [Edge](clients/restful-api/edge.md)
- * [Traverser](clients/restful-api/traverser.md)
- * [Rank](clients/restful-api/rank.md)
- * [Variable](clients/restful-api/variable.md)
- * [Graphs](clients/restful-api/graphs.md)
- * [Task](clients/restful-api/task.md)
- * [Gremlin](clients/restful-api/gremlin.md)
- * [Cypher](clients/restful-api/cypher.md)
- * [Authentication](clients/restful-api/auth.md)
- * [Other](clients/restful-api/other.md)
-* [Java Client](clients/hugegraph-client.md)
-* [Gremlin Console](clients/gremlin-console.md)
+* [RESTful API](clients/restful-api)
+ * [Schema](clients/restful-api/schema)
+ * [PropertyKey](clients/restful-api/propertykey)
+ * [VertexLabel](clients/restful-api/vertexlabel)
+ * [EdgeLabel](clients/restful-api/edgelabel)
+ * [IndexLabel](clients/restful-api/indexlabel)
+ * [Rebuild](clients/restful-api/rebuild)
+ * [Vertex](clients/restful-api/vertex)
+ * [Edge](clients/restful-api/edge)
+ * [Traverser](clients/restful-api/traverser)
+ * [Rank](clients/restful-api/rank)
+ * [Variable](clients/restful-api/variable)
+ * [Graphs](clients/restful-api/graphs)
+ * [Task](clients/restful-api/task)
+ * [Gremlin](clients/restful-api/gremlin)
+ * [Cypher](clients/restful-api/cypher)
+ * [Authentication](clients/restful-api/auth)
+ * [Other](clients/restful-api/other)
+* [Java Client](clients/hugegraph-client)
+* [Gremlin Console](clients/gremlin-console)
## Guides
-* [Architecture Overview](guides/architectural.md)
-* [Design Concepts](guides/desgin-concept.md)
-* [Custom Plugins](guides/custom-plugin.md)
-* [Backup Restore](guides/backup-restore.md)
-* [FAQ](guides/faq.md)
+* [Architecture Overview](guides/architectural)
+* [Design Concepts](guides/desgin-concept)
+* [Custom Plugins](guides/custom-plugin)
+* [Backup Restore](guides/backup-restore)
+* [FAQ](guides/faq)
## Query Language
-* [Gremlin Query Language](language/hugegraph-gremlin.md)
-* [HugeGraph Examples](language/hugegraph-example.md)
+* [Gremlin Query Language](language/hugegraph-gremlin)
+* [HugeGraph Examples](language/hugegraph-example)
## Performance
-* [HugeGraph Benchmark Performance](performance/hugegraph-benchmark-0.5.6.md)
-* [HugeGraph API
Performance-Outdated](content/cn/docs/performance/api-performance/_index.md)
- * [v0.5.6
Stand-alone(RocksDB)](content/cn/docs/performance/api-performance/hugegraph-api-0.5.6-rocksdb.md)
- * [v0.5.6
Cluster(Cassandra)](content/cn/docs/performance/api-performance/hugegraph-api-0.5.6-cassandra.md)
- *
[v0.4.4](content/cn/docs/performance/api-performance/hugegraph-api-0.4.4.md)
- * [v0.2](content/cn/docs/performance/api-performance/hugegraph-api-0.2.md)
-* [HugeGraph-Loader Performance](performance/hugegraph-loader-performance.md)
+* [HugeGraph Benchmark Performance](performance/hugegraph-benchmark-0.5.6)
+* [HugeGraph API Performance-Outdated](performance/api-performance)
+ * [v0.5.6
Stand-alone(RocksDB)](performance/api-performance/hugegraph-api-0.5.6-rocksdb)
+ * [v0.5.6
Cluster(Cassandra)](performance/api-performance/hugegraph-api-0.5.6-cassandra)
+ * [v0.4.4](performance/api-performance/hugegraph-api-0.4.4)
+ * [v0.2](performance/api-performance/hugegraph-api-0.2)
+* [HugeGraph-Loader Performance](performance/hugegraph-loader-performance)
## ChangeLogs
-* [Release-1.3.0](changelog/hugegraph-1.3.0-release-notes.md)
-* [Release-1.2.0](changelog/hugegraph-1.2.0-release-notes.md)
-* [Release-1.0.0](changelog/hugegraph-1.0.0-release-notes.md)
-
----
-
-* [Release-0.12.0](changelog/hugegraph-0.12.0-release-notes.md)
-* [Release-0.11.2](changelog/hugegraph-0.11.2-release-notes.md)
-* [Release-0.10.4](changelog/hugegraph-0.10.4-release-notes.md)
-* [Release-0.9.2](changelog/hugegraph-0.9.2-release-notes.md)
-* [Release-0.8.0](changelog/hugegraph-0.8.0-release-notes.md)
-* [Release-0.7.4](changelog/hugegraph-0.7.4-release-notes.md)
-* [Release-0.6.1](changelog/hugegraph-0.6.1-release-notes.md)
-* [Release-0.5.6](changelog/hugegraph-0.5.6-release-notes.md)
-* [Release-0.4.4](changelog/hugegraph-0.4.4-release-notes.md)
-* [Release-0.3.3](changelog/hugegraph-0.3.3-release-notes.md)
-* [Release-0.2.4](changelog/hugegraph-0.2.4-release-notes.md)
-* [Release-0.2](changelog/hugegraph-0.2-release-notes.md)
+* [Release-1.3.0](changelog/hugegraph-1.3.0-release-notes)
+* [Release-1.2.0](changelog/hugegraph-1.2.0-release-notes)
+* [Release-1.0.0](changelog/hugegraph-1.0.0-release-notes)
+* [Release-0.12.0](changelog/hugegraph-0.12.0-release-notes)
+* [Release-0.11.2](changelog/hugegraph-0.11.2-release-notes)
+* [Release-0.10.4](changelog/hugegraph-0.10.4-release-notes)
+* [Release-0.9.2](changelog/hugegraph-0.9.2-release-notes)
+* [Release-0.8.0](changelog/hugegraph-0.8.0-release-notes)
+* [Release-0.7.4](changelog/hugegraph-0.7.4-release-notes)
+* [Release-0.6.1](changelog/hugegraph-0.6.1-release-notes)
+* [Release-0.5.6](changelog/hugegraph-0.5.6-release-notes)
+* [Release-0.4.4](changelog/hugegraph-0.4.4-release-notes)
+* [Release-0.3.3](changelog/hugegraph-0.3.3-release-notes)
+* [Release-0.2.4](changelog/hugegraph-0.2.4-release-notes)
+* [Release-0.2](changelog/hugegraph-0.2-release-notes)
diff --git a/content/cn/docs/clients/restful-api/auth.md
b/content/cn/docs/clients/restful-api/auth.md
index 84db93aa..ffcc7b92 100644
--- a/content/cn/docs/clients/restful-api/auth.md
+++ b/content/cn/docs/clients/restful-api/auth.md
@@ -1049,7 +1049,7 @@ GET
http://localhost:8080/graphspaces/DEFAULT/auth/accesses/S-69:all>-88>11>S-77
### 10.7 图空间管理员(Manager)API
-**重要提示**:在使用以下 API 之前,需要先创建图空间(graphspace)。请参考 [Graphspace API](../graphspace)
创建名为 `gs1` 的图空间。文档中的示例均假设已存在名为 `gs1` 的图空间
+**重要提示**:在使用以下 API 之前,需要先创建图空间(graphspace)。请参考 [Graphspace API](./graphspace)
创建名为 `gs1` 的图空间。文档中的示例均假设已存在名为 `gs1` 的图空间
1. 图空间管理员 API 用于在 graphspace 维度给用户授予/回收管理员角色,并查询当前用户或其他用户在该 graphspace
下的角色信息。角色类型可取 `SPACE`、`SPACE_MEMBER`、`ADMIN` 。
diff --git a/content/cn/docs/clients/restful-api/edgelabel.md
b/content/cn/docs/clients/restful-api/edgelabel.md
index 0d1e71bc..33f1ad54 100644
--- a/content/cn/docs/clients/restful-api/edgelabel.md
+++ b/content/cn/docs/clients/restful-api/edgelabel.md
@@ -311,4 +311,4 @@ DELETE
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/edgelab
注:
-> 可以通过`GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/1`(其中"1"是
task_id)来查询异步任务的执行状态,更多[异步任务 RESTful API](../task)
+> 可以通过`GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/1`(其中"1"是
task_id)来查询异步任务的执行状态,更多[异步任务 RESTful API](./task)
diff --git a/content/cn/docs/clients/restful-api/gremlin.md
b/content/cn/docs/clients/restful-api/gremlin.md
index 144f485c..ab22c1cf 100644
--- a/content/cn/docs/clients/restful-api/gremlin.md
+++ b/content/cn/docs/clients/restful-api/gremlin.md
@@ -229,7 +229,7 @@ POST
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/jobs/gremlin
注:
-> 可以通过`GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/1`(其中"1"是
task_id)来查询异步任务的执行状态,更多[异步任务 RESTful API](../task)
+> 可以通过`GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/1`(其中"1"是
task_id)来查询异步任务的执行状态,更多[异步任务 RESTful API](./task)
**查询边**
@@ -260,4 +260,4 @@ POST
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/jobs/gremlin
注:
-> 可以通过`GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/2`(其中"2"是
task_id)来查询异步任务的执行状态,更多[异步任务 RESTful API](../task)
+> 可以通过`GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/2`(其中"2"是
task_id)来查询异步任务的执行状态,更多[异步任务 RESTful API](./task)
diff --git a/content/cn/docs/clients/restful-api/indexlabel.md
b/content/cn/docs/clients/restful-api/indexlabel.md
index 22756799..0a51d23f 100644
--- a/content/cn/docs/clients/restful-api/indexlabel.md
+++ b/content/cn/docs/clients/restful-api/indexlabel.md
@@ -174,4 +174,4 @@ DELETE
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/indexla
注:
-> 可以通过`GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/1`(其中"1"是
task_id)来查询异步任务的执行状态,更多[异步任务 RESTful API](../task)
+> 可以通过`GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/1`(其中"1"是
task_id)来查询异步任务的执行状态,更多[异步任务 RESTful API](./task)
diff --git a/content/cn/docs/clients/restful-api/rebuild.md
b/content/cn/docs/clients/restful-api/rebuild.md
index b9c043d3..db6281ac 100644
--- a/content/cn/docs/clients/restful-api/rebuild.md
+++ b/content/cn/docs/clients/restful-api/rebuild.md
@@ -31,7 +31,7 @@ PUT
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/jobs/rebuild/inde
注:
-> 可以通过`GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/1`(其中"1"是
task_id)来查询异步任务的执行状态,更多[异步任务 RESTful API](../task)
+> 可以通过`GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/1`(其中"1"是
task_id)来查询异步任务的执行状态,更多[异步任务 RESTful API](./task)
#### 1.6.2 VertexLabel 对应的全部索引重建
@@ -57,7 +57,7 @@ PUT
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/jobs/rebuild/vert
注:
-> 可以通过`GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/2`(其中"2"是
task_id)来查询异步任务的执行状态,更多[异步任务 RESTful API](../task)
+> 可以通过`GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/2`(其中"2"是
task_id)来查询异步任务的执行状态,更多[异步任务 RESTful API](./task)
#### 1.6.3 EdgeLabel 对应的全部索引重建
@@ -83,4 +83,4 @@ PUT
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/jobs/rebuild/edge
注:
-> 可以通过`GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/3`(其中"3"是
task_id)来查询异步任务的执行状态,更多[异步任务 RESTful API](../task)
+> 可以通过`GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/3`(其中"3"是
task_id)来查询异步任务的执行状态,更多[异步任务 RESTful API](./task)
diff --git a/content/cn/docs/clients/restful-api/vertexlabel.md
b/content/cn/docs/clients/restful-api/vertexlabel.md
index 9c2bfd2c..9d15589f 100644
--- a/content/cn/docs/clients/restful-api/vertexlabel.md
+++ b/content/cn/docs/clients/restful-api/vertexlabel.md
@@ -308,4 +308,4 @@ DELETE
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/vertexl
注:
-> 可以通过`GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/1`(其中"1"是
task_id)来查询异步任务的执行状态,更多[异步任务 RESTful API](../task)
+> 可以通过`GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/1`(其中"1"是
task_id)来查询异步任务的执行状态,更多[异步任务 RESTful API](./task)
diff --git a/content/cn/docs/config/config-guide.md
b/content/cn/docs/config/config-guide.md
index 43517a45..fed7ba85 100644
--- a/content/cn/docs/config/config-guide.md
+++ b/content/cn/docs/config/config-guide.md
@@ -138,7 +138,7 @@ ssl: {
- graphs:GremlinServer 启动时需要打开的图,该项是一个 map 结构,key 是图的名字,value 是该图的配置文件路径;
- channelizer:GremlinServer 与客户端有两种通信方式,分别是 WebSocket 和 HTTP(默认)。如果选择
WebSocket,
-用户可以通过 [Gremlin-Console](/clients/gremlin-console.html) 快速体验 HugeGraph
的特性,但是不支持大规模数据导入,
+用户可以通过 [Gremlin-Console](../clients/gremlin-console) 快速体验 HugeGraph
的特性,但是不支持大规模数据导入,
推荐使用 HTTP 的通信方式,HugeGraph 的外围组件都是基于 HTTP 实现的;
默认 GremlinServer 是服务在 localhost:8182,如果需要修改,配置 host、port 即可
diff --git a/content/cn/docs/contribution-guidelines/contribute.md
b/content/cn/docs/contribution-guidelines/contribute.md
index 83884b8c..5f4407c1 100644
--- a/content/cn/docs/contribution-guidelines/contribute.md
+++ b/content/cn/docs/contribution-guidelines/contribute.md
@@ -74,7 +74,7 @@ vim
hugegraph-core/src/main/java/org/apache/hugegraph/HugeFactory.java
# run test locally (optional)
mvn test -Pcore-test,memory
```
-Note: In order to be consistent with the code style easily, if you use
[IDEA](https://www.jetbrains.com/idea/) as your IDE, you can directly
[import](https://www.jetbrains.com/help/idea/configuring-code-style.html) our
code style [configuration file](./hugegraph-style.xml).
+Note: In order to be consistent with the code style easily, if you use IDEA as
your IDE, you can import our code style configuration file.
##### 3.2.1 添加第三方依赖
diff --git a/content/cn/docs/quickstart/hugegraph-studio.md
b/content/cn/docs/quickstart/hugegraph-studio.md
index 89b8a118..ac7c820c 100644
--- a/content/cn/docs/quickstart/hugegraph-studio.md
+++ b/content/cn/docs/quickstart/hugegraph-studio.md
@@ -145,7 +145,7 @@
graph.schema().propertyKey("price").asInt().ifNotExist().create()
**在这里有几点需要说明**
1、上述语句是`groovy`语言形式(类似但不是`java`)的`gremlin`语句,这些`gremlin`语句会被发送到`HugeGraphServer`上执行。
-关于`gremlin`本身可以参考[Gremlin Query
Language](/language/hugegraph-gremlin.md)或[Tinkerpop官网](http://tinkerpop.apache.org/);
+关于`gremlin`本身可以参考[Gremlin Query
Language](../language/hugegraph-gremlin)或[Tinkerpop官网](http://tinkerpop.apache.org/);
2、上述语句是通过`graph.schema()`获取到`SchemaManager`对象后操作元数据,通过`gremlin`语句操作Schema可参考文档[HugeGraph-Client](/docs/clients/hugegraph-client),
需要注意的是`HugeGraph-Client`是`java`语法,大体上与`gremlin`风格是一致的,具体的差异见文档`HugeGraph-Client`中的说明。
diff --git a/content/en/docs/SUMMARY.md b/content/en/docs/SUMMARY.md
index 283ddb6f..44321bcf 100644
--- a/content/en/docs/SUMMARY.md
+++ b/content/en/docs/SUMMARY.md
@@ -1,69 +1,66 @@
# HugeGraph Docs
-* [Download](download.md)
+* [Download](download/download)
## Quickstart
-* [Install HugeGraph-Server](quickstart/hugegraph-server.md)
-* [Load data with HugeGraph-Loader](quickstart/hugegraph-loader.md)
-* [Visual with HugeGraph-Hubble](quickstart/hugegraph-hubble.md)
-* [Develop with HugeGraph-Client](quickstart/hugegraph-client.md)
-* [Manage with HugeGraph-Tools](quickstart/hugegraph-tools.md)
-* [Analysis with HugeGraph-Computer](quickstart/hugegraph-computer.md)
-* [Display with HugeGraph-Studio](quickstart/hugegraph-studio.md)
+* [Install HugeGraph-Server](quickstart/hugegraph/hugegraph-server)
+* [Load data with HugeGraph-Loader](quickstart/toolchain/hugegraph-loader)
+* [Visual with HugeGraph-Hubble](quickstart/toolchain/hugegraph-hubble)
+* [Develop with HugeGraph-Client](quickstart/client/hugegraph-client)
+* [Manage with HugeGraph-Tools](quickstart/toolchain/hugegraph-tools)
+* [Analysis with HugeGraph-Computer](quickstart/computing/hugegraph-computer)
## Config
-* [Config Guide](config/config-guide.md)
-* [Config Options](config/config-option.md)
-* [Config Authentication](config/config-authentication.md)
-* [Config HTTPS](config/config-https.md)
-* [Config Computer](config/config-computer.md)
-
+* [Config Guide](config/config-guide)
+* [Config Options](config/config-option)
+* [Config Authentication](config/config-authentication)
+* [Config HTTPS](config/config-https)
+* [Config Computer](quickstart/computing/hugegraph-computer)
## API
-* [RESTful API](clients/hugegraph-api.md)
- * [Schema](clients/restful-api/schema.md)
- * [PropertyKey](clients/restful-api/propertykey.md)
- * [VertexLabel](clients/restful-api/vertexlabel.md)
- * [EdgeLabel](clients/restful-api/edgelabel.md)
- * [IndexLabel](clients/restful-api/indexlabel.md)
- * [Rebuild](clients/restful-api/rebuild.md)
- * [Vertex](clients/restful-api/vertex.md)
- * [Edge](clients/restful-api/edge.md)
- * [Traverser](clients/restful-api/traverser.md)
- * [Rank](clients/restful-api/rank.md)
- * [Variable](clients/restful-api/variable.md)
- * [Graphs](clients/restful-api/graphs.md)
- * [Task](clients/restful-api/task.md)
- * [Gremlin](clients/restful-api/gremlin.md)
- * [Cypher](clients/restful-api/cypher.md)
- * [Authentication](clients/restful-api/auth.md)
- * [Other](clients/restful-api/other.md)
-* [Java Client](clients/hugegraph-client.md)
-* [Gremlin Console](clients/gremlin-console.md)
+* [RESTful API](clients/restful-api)
+ * [Schema](clients/restful-api/schema)
+ * [PropertyKey](clients/restful-api/propertykey)
+ * [VertexLabel](clients/restful-api/vertexlabel)
+ * [EdgeLabel](clients/restful-api/edgelabel)
+ * [IndexLabel](clients/restful-api/indexlabel)
+ * [Rebuild](clients/restful-api/rebuild)
+ * [Vertex](clients/restful-api/vertex)
+ * [Edge](clients/restful-api/edge)
+ * [Traverser](clients/restful-api/traverser)
+ * [Rank](clients/restful-api/rank)
+ * [Variable](clients/restful-api/variable)
+ * [Graphs](clients/restful-api/graphs)
+ * [Task](clients/restful-api/task)
+ * [Gremlin](clients/restful-api/gremlin)
+ * [Cypher](clients/restful-api/cypher)
+ * [Authentication](clients/restful-api/auth)
+ * [Other](clients/restful-api/other)
+* [Java Client](clients/hugegraph-client)
+* [Gremlin Console](clients/gremlin-console)
## Guides
-* [Architecture Overview](guides/architectural.md)
-* [Design Concepts](guides/desgin-concept.md)
-* [Custom Plugins](guides/custom-plugin.md)
-* [Backup Restore](guides/backup-restore.md)
-* [FAQ](guides/faq.md)
+* [Architecture Overview](guides/architectural)
+* [Design Concepts](guides/desgin-concept)
+* [Custom Plugins](guides/custom-plugin)
+* [Backup Restore](guides/backup-restore)
+* [FAQ](guides/faq)
## Query Language
-* [Gremlin Query Language](language/hugegraph-gremlin.md)
-* [HugeGraph Examples](language/hugegraph-example.md)
+* [Gremlin Query Language](language/hugegraph-gremlin)
+* [HugeGraph Examples](language/hugegraph-example)
## Performance
-* [HugeGraph Benchmark Performance](performance/hugegraph-benchmark-0.5.6.md)
-* [HugeGraph API
Performance—Outdated](content/cn/docs/performance/api-performance/_index.md)
- * [v0.5.6
Stand-alone(RocksDB)](content/cn/docs/performance/api-performance/hugegraph-api-0.5.6-rocksdb.md)
- * [v0.5.6
Cluster(Cassandra)](content/cn/docs/performance/api-performance/hugegraph-api-0.5.6-cassandra.md)
- *
[v0.4.4](content/cn/docs/performance/api-performance/hugegraph-api-0.4.4.md)
- * [v0.2](content/cn/docs/performance/api-performance/hugegraph-api-0.2.md)
-* [HugeGraph-Loader Performance](performance/hugegraph-loader-performance.md)
+* [HugeGraph Benchmark Performance](performance/hugegraph-benchmark-0.5.6)
+* [HugeGraph API Performance—Outdated](performance/api-performance)
+ * [v0.5.6
Stand-alone(RocksDB)](performance/api-performance/hugegraph-api-0.5.6-rocksdb)
+ * [v0.5.6
Cluster(Cassandra)](performance/api-performance/hugegraph-api-0.5.6-cassandra)
+ * [v0.4.4](performance/api-performance/hugegraph-api-0.4.4)
+ * [v0.2](performance/api-performance/hugegraph-api-0.2)
+* [HugeGraph-Loader Performance](performance/hugegraph-loader-performance)
## ChangeLogs
-* [Release-1.3.0](changelog/hugegraph-1.3.0-release-notes.md)
-* [Release-1.2.0](changelog/hugegraph-1.2.0-release-notes.md)
-* [Release-1.0.0](changelog/hugegraph-1.0.0-release-notes.md)
-* [Release-0.12.0](changelog/hugegraph-0.12.0-release-notes.md)
-
+* [Release-1.3.0](changelog/hugegraph-1.3.0-release-notes)
+* [Release-1.2.0](changelog/hugegraph-1.2.0-release-notes)
+* [Release-1.0.0](changelog/hugegraph-1.0.0-release-notes)
+* [Release-0.12.0](changelog/hugegraph-0.12.0-release-notes)
diff --git a/content/en/docs/clients/restful-api/auth.md
b/content/en/docs/clients/restful-api/auth.md
index f23e48f5..a3af6339 100644
--- a/content/en/docs/clients/restful-api/auth.md
+++ b/content/en/docs/clients/restful-api/auth.md
@@ -1049,7 +1049,7 @@ GET
http://localhost:8080/graphspaces/DEFAULT/auth/accesses/S-69:all>-88>11>S-77
### 10.7 Graphspace Manager (Manager) API
-> **Note**: Before using the following APIs, you need to create a graphspace
first. For example, create a graphspace named `gs1` via the [Graphspace
API](../graphspace). The examples below assume that `gs1` already exists.
+> **Note**: Before using the following APIs, you need to create a graphspace
first. For example, create a graphspace named `gs1` via the [Graphspace
API](./graphspace). The examples below assume that `gs1` already exists.
1. The graphspace manager API is used to grant/revoke manager roles for users
at the graphspace level, and to query the roles of the current user or other
users in a graphspace. Supported role types include `SPACE`, `SPACE_MEMBER`,
and `ADMIN`.
diff --git a/content/en/docs/clients/restful-api/edgelabel.md
b/content/en/docs/clients/restful-api/edgelabel.md
index 34e7bba0..a452ec5e 100644
--- a/content/en/docs/clients/restful-api/edgelabel.md
+++ b/content/en/docs/clients/restful-api/edgelabel.md
@@ -311,4 +311,4 @@ DELETE
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/edgelab
Note:
-> You can query the execution status of an asynchronous task by using `GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/1` (where "1"
is the task_id). For more information, refer to the [Asynchronous Task RESTful
API](../task).
+> You can query the execution status of an asynchronous task by using `GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/1` (where "1"
is the task_id). For more information, refer to the [Asynchronous Task RESTful
API](./task).
diff --git a/content/en/docs/clients/restful-api/gremlin.md
b/content/en/docs/clients/restful-api/gremlin.md
index f308e58b..ccd72686 100644
--- a/content/en/docs/clients/restful-api/gremlin.md
+++ b/content/en/docs/clients/restful-api/gremlin.md
@@ -225,7 +225,7 @@ Note:
Note:
-> You can query the execution status of an asynchronous task by using `GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/1` (where "1"
is the task_id). For more information, refer to the [Asynchronous Task RESTful
API](../task).
+> You can query the execution status of an asynchronous task by using `GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/1` (where "1"
is the task_id). For more information, refer to the [Asynchronous Task RESTful
API](./task).
**Querying edges**
@@ -256,4 +256,4 @@ Note:
Note:
-> You can query the execution status of an asynchronous task by using `GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/2` (where "2"
is the task_id). For more information, refer to the [Asynchronous Task RESTful
API](../task).
+> You can query the execution status of an asynchronous task by using `GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/2` (where "2"
is the task_id). For more information, refer to the [Asynchronous Task RESTful
API](./task).
diff --git a/content/en/docs/clients/restful-api/indexlabel.md
b/content/en/docs/clients/restful-api/indexlabel.md
index fbfb68dd..d56c156a 100644
--- a/content/en/docs/clients/restful-api/indexlabel.md
+++ b/content/en/docs/clients/restful-api/indexlabel.md
@@ -174,4 +174,4 @@ DELETE
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/indexla
Note:
-> You can query the execution status of an asynchronous task by using `GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/1` (where "1"
is the task_id). For more information, refer to the [Asynchronous Task RESTful
API](../task).
+> You can query the execution status of an asynchronous task by using `GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/1` (where "1"
is the task_id). For more information, refer to the [Asynchronous Task RESTful
API](./task).
diff --git a/content/en/docs/clients/restful-api/rebuild.md
b/content/en/docs/clients/restful-api/rebuild.md
index 37b6ae12..ef76d6e4 100644
--- a/content/en/docs/clients/restful-api/rebuild.md
+++ b/content/en/docs/clients/restful-api/rebuild.md
@@ -30,7 +30,7 @@ PUT
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/jobs/rebuild/inde
```
Note:
-> You can get the asynchronous job status by `GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/${task_id}`
(the task_id here should be 1). See More [AsyncJob RESTfull API](../task)
+> You can get the asynchronous job status by `GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/${task_id}`
(the task_id here should be 1). See More [AsyncJob RESTfull API](./task)
#### 1.6.2 Rebulid all Indexs of VertexLabel
@@ -56,7 +56,7 @@ PUT
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/jobs/rebuild/vert
Note:
-> You can get the asynchronous job status by `GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/${task_id}`
(the task_id here should be 2). See More [AsyncJob RESTfull API](../task)
+> You can get the asynchronous job status by `GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/${task_id}`
(the task_id here should be 2). See More [AsyncJob RESTfull API](./task)
#### 1.6.3 Rebulid all Indexs of EdgeLabel
@@ -82,4 +82,4 @@ PUT
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/jobs/rebuild/edge
Note:
-> You can get the asynchronous job status by `GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/${task_id}`
(the task_id here should be 3). See More [AsyncJob RESTfull API](../task)
\ No newline at end of file
+> You can get the asynchronous job status by `GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/${task_id}`
(the task_id here should be 3). See More [AsyncJob RESTfull API](./task)
\ No newline at end of file
diff --git a/content/en/docs/clients/restful-api/vertexlabel.md
b/content/en/docs/clients/restful-api/vertexlabel.md
index 1369a5b7..6e6388a7 100644
--- a/content/en/docs/clients/restful-api/vertexlabel.md
+++ b/content/en/docs/clients/restful-api/vertexlabel.md
@@ -308,4 +308,4 @@ DELETE
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/schema/vertexl
Note:
-> You can use `GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/1` (where "1"
is the task_id) to query the execution status of the asynchronous task. For
more information, refer to the [Asynchronous Task RESTful API](../task).
+> You can use `GET
http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/tasks/1` (where "1"
is the task_id) to query the execution status of the asynchronous task. For
more information, refer to the [Asynchronous Task RESTful API](./task).
diff --git a/content/en/docs/config/config-guide.md
b/content/en/docs/config/config-guide.md
index 8857010d..8d5c3699 100644
--- a/content/en/docs/config/config-guide.md
+++ b/content/en/docs/config/config-guide.md
@@ -137,7 +137,7 @@ ssl: {
There are many configuration options mentioned above, but for now, let's focus
on the following options: `channelizer` and `graphs`.
- `graphs`: This option specifies the graphs that need to be opened when the
GremlinServer starts. It is a map structure where the key is the name of the
graph and the value is the configuration file path for that graph.
-- `channelizer`: The GremlinServer supports two communication modes with
clients: WebSocket and HTTP (default). If WebSocket is chosen, users can
quickly experience the features of HugeGraph using
[Gremlin-Console](/clients/gremlin-console.html), but it does not support
importing large-scale data. It is recommended to use HTTP for communication, as
all peripheral components of HugeGraph are implemented based on HTTP.
+- `channelizer`: The GremlinServer supports two communication modes with
clients: WebSocket and HTTP (default). If WebSocket is chosen, users can
quickly experience the features of HugeGraph using
[Gremlin-Console](../clients/gremlin-console), but it does not support
importing large-scale data. It is recommended to use HTTP for communication, as
all peripheral components of HugeGraph are implemented based on HTTP.
By default, the GremlinServer serves at `localhost:8182`. If you need to
modify it, configure the `host` and `port` settings.
diff --git a/content/en/docs/contribution-guidelines/contribute.md
b/content/en/docs/contribution-guidelines/contribute.md
index 9a9c6edf..8f3e9697 100644
--- a/content/en/docs/contribution-guidelines/contribute.md
+++ b/content/en/docs/contribution-guidelines/contribute.md
@@ -72,7 +72,7 @@ vim
hugegraph-core/src/main/java/org/apache/hugegraph/HugeFactory.java
# run test locally (optional)
mvn test -Pcore-test,memory
```
-Note: In order to be consistent with the code style easily, if you use
[IDEA](https://www.jetbrains.com/idea/) as your IDE, you can directly
[import](https://www.jetbrains.com/help/idea/configuring-code-style.html) our
code style [configuration file](./hugegraph-style.xml).
+Note: In order to be consistent with the code style easily, if you use IDEA as
your IDE, you can import our code style configuration file.
##### 3.2.1 Check licenses
If we want to add new third-party dependencies to the `HugeGraph` project, we
need to do the following things:
diff --git a/content/en/docs/quickstart/hugegraph-studio.md
b/content/en/docs/quickstart/hugegraph-studio.md
index e6503a0f..864b5589 100644
--- a/content/en/docs/quickstart/hugegraph-studio.md
+++ b/content/en/docs/quickstart/hugegraph-studio.md
@@ -145,7 +145,7 @@
graph.schema().propertyKey("price").asInt().ifNotExist().create()
**在这里有几点需要说明**
1、上述语句是`groovy`语言形式(类似但不是`java`)的`gremlin`语句,这些`gremlin`语句会被发送到`HugeGraphServer`上执行。
-关于`gremlin`本身可以参考[Gremlin Query
Language](/language/hugegraph-gremlin.md)或[Tinkerpop官网](http://tinkerpop.apache.org/);
+关于`gremlin`本身可以参考[Gremlin Query
Language](../language/hugegraph-gremlin)或[Tinkerpop官网](http://tinkerpop.apache.org/);
2、上述语句是通过`graph.schema()`获取到`SchemaManager`对象后操作元数据,通过`gremlin`语句操作Schema可参考文档[HugeGraph-Client](/docs/clients/hugegraph-client),
需要注意的是`HugeGraph-Client`是`java`语法,大体上与`gremlin`风格是一致的,具体的差异见文档`HugeGraph-Client`中的说明。
diff --git a/dist/validate-links.sh b/dist/validate-links.sh
index 224eeeeb..23e9069d 100755
--- a/dist/validate-links.sh
+++ b/dist/validate-links.sh
@@ -1,63 +1,286 @@
#!/bin/bash
+set -o errexit
+set -o pipefail
-# Configuration
CONTENT_DIR="content"
EXIT_CODE=0
-echo "Starting link validation..."
+VERBOSE="${VERBOSE:-0}"
+
+log_verbose() {
+ if [[ "$VERBOSE" == "1" ]]; then
+ echo "Info: $*"
+ fi
+}
+
+ASSET_EXTENSIONS_REGEX='png|jpg|jpeg|svg|gif|webp|avif|ico|xml|yaml|yml|json|css|js|pdf|zip|tar\.gz|woff|woff2|ttf|eot|mp4|webm'
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" || exit 1
+REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" || exit 1
+CONTENT_ROOT="$(cd "$REPO_ROOT/$CONTENT_DIR" && pwd)" || exit 1
+
+if [[ ! -d "$CONTENT_ROOT" ]]; then
+ echo "Error: content directory not found. Run from repository root."
+ exit 1
+fi
+
+normalize_link() {
+ local link="$1"
+
+ # Decode common URL-encoded characters explicitly
+ link="${link//%20/ }" # space
+ link="${link//%23/#}" # hash
+ link="${link//%2F/\/}" # forward slash
+
+ # Generic percent-decoding for remaining cases
+ link="${link//%/\\x}"
+ link="$(printf '%b' "$link")"
+
+ link="${link%%#*}"
+ link="${link%%\?*}"
+
+ if [[ "$link" != "/" ]]; then
+ link="${link%/}"
+ fi
+
+ printf "%s" "$link"
+}
+
+canonicalize_path() {
+ local path="$1"
+ local result=()
+ local part
+ local parts
+
+ # Bash 3.2 compatible: use here-string
+ IFS='/' read -r -a parts <<< "$path"
+
+ for part in "${parts[@]}"; do
+ if [[ -z "$part" || "$part" == "." ]]; then
+ continue
+ elif [[ "$part" == ".." ]]; then
+ # Bash 3.2 compatible: calculate last index instead of using -1
+ if [[ ${#result[@]} -gt 0 ]]; then
+ local last_idx=$((${#result[@]} - 1))
+ unset "result[$last_idx]"
+ fi
+ else
+ result+=("$part")
+ fi
+ done
+
+ if [[ ${#result[@]} -eq 0 ]]; then
+ printf "/"
+ else
+ ( IFS='/'; printf "/%s" "${result[*]}" )
+ fi
+}
+
+resolve_real_path() {
+ local path="$1"
+
+ if command -v python3 >/dev/null 2>&1; then
+ # Use Python to compute realpath which resolves symlinks AND
normalizes paths
+ # Python's os.path.realpath is tolerant of non-existent final targets
+ python3 - <<'PY' "$path"
+import os
+import sys
+p = sys.argv[1]
+print(os.path.realpath(p))
+PY
+ else
+ # Fallback: Normalize without symlink resolution if Python3 unavailable
+ # Note: This won't resolve symlinks, only normalize .. and . components
+ canonicalize_path "$path"
+ fi
+}
+
+check_internal_link() {
+ local link="$1"
+ local file="$2"
+ local line_no="$3"
+ local clean_link
+ local target_path
+ local location
+
+ clean_link="$(normalize_link "$link")"
+
+ [[ -z "$clean_link" || "$clean_link" == "#" ]] && return 0
+
+ if [[ "$clean_link" == "{{"* ]]; then
+ log_verbose "Skipping Hugo shortcode link: $link ($file:$line_no)"
+ return 0
+ fi
+
+ local clean_lower
+ clean_lower="$(printf "%s" "$clean_link" | tr '[:upper:]' '[:lower:]')"
+
+ if [[ "$clean_lower" == http://* || "$clean_lower" == https://* ||
"$clean_lower" == "//"* ]]; then
+ log_verbose "Skipping external link: $link ($file:$line_no)"
+ return 0
+ fi
+
+ case "$clean_lower" in
+ mailto:*|tel:*|javascript:*|data:*)
+ return 0
+ ;;
+ esac
+
+ if [[ "$clean_link" == /docs/* ]]; then
+ target_path="$CONTENT_ROOT/en${clean_link}"
+
+ elif [[ "$clean_link" == /cn/docs/* ]]; then
+ target_path="$CONTENT_ROOT${clean_link}"
+
+ elif [[ "$clean_link" == /community/* ]]; then
+ target_path="$CONTENT_ROOT/en${clean_link}"
-# Find all markdown files and verify links
-while read -r FILE; do
- # Extract internal links starting with /docs/ or /cn/docs/
- # We look for [text](url) pattern where url starts with /docs/ or /cn/docs/
- # Using grep to find all matching links in the file
- while read -r MATCH; do
- if [ -z "$MATCH" ]; then continue; fi
-
- # Extract URL from ](url)
- LINK=${MATCH#*](}
- LINK=${LINK%)}
-
- # Remove anchor and query parameters
- CLEAN_LINK=$(echo "$LINK" | cut -d'#' -f1 | cut -d'?' -f1)
- CLEAN_LINK=${CLEAN_LINK%/}
-
- # Determine target file path based on language prefix
- if [[ "$CLEAN_LINK" == /docs/* ]]; then
- TARGET_PATH="content/en${CLEAN_LINK}"
- elif [[ "$CLEAN_LINK" == /cn/docs/* ]]; then
- TARGET_PATH="content${CLEAN_LINK}"
+ elif [[ "$clean_link" == /blog/* || "$clean_link" == /cn/blog/* ]]; then
+ # Blog URLs are permalink-based and don't map 1:1 to content file paths.
+ # Skip deterministic filesystem validation for these routes.
+ log_verbose "Skipping permalink-based blog link: $link ($file:$line_no)"
+ return 0
+
+ elif [[ "$clean_link" == /language/* ]]; then
+ target_path="$CONTENT_ROOT/en${clean_link}"
+
+ elif [[ "$clean_link" == /clients/* ]]; then
+ target_path="$REPO_ROOT/static${clean_link}"
+
+ elif [[ "$clean_link" == /* ]]; then
+ location="$file"
+ [[ -n "$line_no" ]] && location="$file:$line_no"
+
+ echo "Error: Unsupported absolute internal path (cannot validate
deterministically)"
+ echo " File: $location"
+ echo " Link: $link"
+
+ EXIT_CODE=1
+ return
+
+ else
+ local file_dir
+ file_dir="$(cd "$(dirname "$file")" && pwd)"
+ target_path="$file_dir/$clean_link"
+ fi
+
+ target_path="$(canonicalize_path "$target_path")"
+ target_path="$(resolve_real_path "$target_path")"
+
+ case "$target_path" in
+ "$CONTENT_ROOT"/*) ;;
+ "$REPO_ROOT/static"/*) ;;
+ *)
+ location="$file"
+ [[ -n "$line_no" ]] && location="$file:$line_no"
+ echo "Error: Link resolves outside content directory"
+ echo " File: $location"
+ echo " Link: $link"
+ EXIT_CODE=1
+ return
+ ;;
+ esac
+
+ if [[ "$clean_lower" =~ \.(${ASSET_EXTENSIONS_REGEX})$ ]]; then
+ if [[ -f "$target_path" ]]; then
+ return 0
else
+ location="$file"
+ [[ -n "$line_no" ]] && location="$file:$line_no"
+ echo "Error: Broken link"
+ echo " File: $location"
+ echo " Link: $link"
+ echo " Target: $target_path"
+ EXIT_CODE=1
+ return
+ fi
+ fi
+
+ if [[ -f "$target_path" || -f "$target_path.md" || -f
"$target_path/_index.md" || -f "$target_path/README.md" ]]; then
+ return 0
+ fi
+
+ location="$file"
+ [[ -n "$line_no" ]] && location="$file:$line_no"
+
+ echo "Error: Broken link"
+ echo " File: $location"
+ echo " Link: $link"
+ echo " Target: $target_path"
+ EXIT_CODE=1
+}
+
+echo "Starting link validation..."
+
+while IFS= read -r FILE; do
+
+ CODE_LINES=""
+ in_fence=false
+ line_no=0
+
+ while IFS= read -r line || [[ -n "$line" ]]; do
+ ((++line_no))
+ # NOTE:
+ # Code fence detection is heuristic and does not validate proper
pairing.
+ # The logic simply toggles state when encountering ``` or ~~~ markers.
+ # If a Markdown file contains an unclosed fence or mismatched fence
types,
+ # all subsequent lines may be treated as code and skipped from
validation.
+ # This behavior is intentional to keep the validator lightweight and
+ # avoids implementing a full Markdown parser. Such cases require
manual review.
+ if [[ "$line" =~ ^[[:space:]]*(\`\`\`|~~~) ]]; then
+ # NOTE:
+ # Code fence detection assumes fences are properly paired.
+ # If a Markdown file contains an unclosed or mismatched fence,
+ # subsequent content may be treated as code and skipped.
+ # This script does not attempt full Markdown validation.
+
+ if $in_fence; then
+ in_fence=false
+ else
+ in_fence=true
+ fi
+ CODE_LINES="$CODE_LINES $line_no "
continue
fi
- # Check for file existence variations
- FOUND=false
-
- # Check 1: As .md file
- if [[ -f "${TARGET_PATH}.md" ]]; then
- FOUND=true
- # Check 2: Exact file (if extension was included)
- elif [[ -f "$TARGET_PATH" ]]; then
- FOUND=true
- # Check 3: Directory index
- elif [[ -f "${TARGET_PATH}/_index.md" ]]; then
- FOUND=true
- # Check 4: Directory README (legacy)
- elif [[ -f "${TARGET_PATH}/README.md" ]]; then
- FOUND=true
+ if $in_fence; then
+ CODE_LINES="$CODE_LINES $line_no "
+ continue
fi
- if [ "$FOUND" = false ]; then
- echo "Error: Broken link in $FILE"
- echo " Link: $LINK"
- echo " Target: $TARGET_PATH (and variants)"
- EXIT_CODE=1
+ # NOTE:
+ # Inline code detection is heuristic and intentionally simplistic.
+ # The logic assumes backticks are properly paired within a single line
+ # after removing escaped backticks. Malformed Markdown, complex inline
+ # constructs, or unusual escaping patterns may cause false positives
+ # or false negatives. This validator does not implement a full Markdown
+ # parser and therefore cannot guarantee perfect inline code detection.
+ escaped_line="${line//\\\`/}"
+ only_ticks="${escaped_line//[^\`]/}"
+ inline_count=${#only_ticks}
+ if (( inline_count % 2 == 1 )); then
+ CODE_LINES="$CODE_LINES $line_no "
fi
- done < <(grep -oE '\]\((/docs/|/cn/docs/)[^)]+\)' "$FILE")
-done < <(find "$CONTENT_DIR" -type f -name "*.md")
-if [ $EXIT_CODE -eq 0 ]; then
+ done < "$FILE"
+
+ while read -r MATCH || [[ -n "$MATCH" ]]; do
+ [[ -z "$MATCH" ]] && continue
+
+ LINE_NO="${MATCH%%:*}"
+ LINK_PART="${MATCH#*:}"
+
+ [[ "$CODE_LINES" == *" $LINE_NO "* ]] && continue
+
+ LINK="${LINK_PART#*](}"
+ LINK="${LINK%)}"
+
+ check_internal_link "$LINK" "$FILE" "$LINE_NO"
+ done < <(grep -n -oE '\]\([^)]+\)' "$FILE" || true)
+
+ unset CODE_LINES
+done < <(find "$CONTENT_ROOT" -type f -name "*.md" 2>/dev/null || true)
+
+if [[ $EXIT_CODE -eq 0 ]]; then
echo "Link validation passed!"
else
echo "Link validation failed!"