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!"


Reply via email to