diff --git a/.asf.yaml b/.asf.yaml
index 14874b4723..3b032102cc 100644
--- a/.asf.yaml
+++ b/.asf.yaml
@@ -22,7 +22,7 @@ notifications:
jira_options: link worklog
github:
- description: "Apache Cassandra®"
+ description: "Open source transactional distributed database. Linear scalability and proven fault-tolerance on commodity hardware or cloud infrastructure without compromising performance."
homepage: https://cassandra.apache.org/
enabled_merge_buttons:
squash: false
diff --git a/.build/build-artifacts.sh b/.build/build-artifacts.sh
index 3214f273f8..348faad400 100755
--- a/.build/build-artifacts.sh
+++ b/.build/build-artifacts.sh
@@ -24,5 +24,5 @@ command -v ant >/dev/null 2>&1 || { echo >&2 "ant needs to be installed"; exit 1
[ -f "${CASSANDRA_DIR}/build.xml" ] || { echo >&2 "${CASSANDRA_DIR}/build.xml must exist"; exit 1; }
# execute
-ant -f "${CASSANDRA_DIR}/build.xml" artifacts -Dant.gen-doc.skip=true -Dcheck.skip=true
+ant -f "${CASSANDRA_DIR}/build.xml" artifacts-with-docs -Dcheck.skip=true
exit $?
diff --git a/.build/docker/_build-debian.sh b/.build/docker/_build-debian.sh
index 071c42a499..98f15a67b6 100755
--- a/.build/docker/_build-debian.sh
+++ b/.build/docker/_build-debian.sh
@@ -119,7 +119,8 @@ if [ $buildxml_version != $git_version ]; then
echo "Warning: build.xml version ($buildxml_version) not matching git/dpkg derived version ($git_version)">&2
fi
-# build package
+# build package (gen-asciidoc needs to happen before quilt patches are applied)
+ant gen-doc -Dcheck.skip=true
dpkg-buildpackage -rfakeroot -uc -us -tc --source-option=--tar-ignore=.git
set +e
diff --git a/.build/docker/_build-redhat.sh b/.build/docker/_build-redhat.sh
index 8acfb2b51a..6bce9cdf78 100755
--- a/.build/docker/_build-redhat.sh
+++ b/.build/docker/_build-redhat.sh
@@ -91,7 +91,8 @@ else
fi
# Artifact will only be used internally for build process and won't be found with snapshot suffix
-ant artifacts -Drelease=true -Dant.gen-doc.skip=true -Djavadoc.skip=true -Dcheck.skip=true
+rm -rf ${DIST_DIR}/apache-cassandra-*.jar # realclean fails on permissions inside docker
+ant clean artifacts-with-docs -Drelease=true -Djavadoc.skip=true -Dcheck.skip=true
cp ${DIST_DIR}/apache-cassandra-*-src.tar.gz ${RPM_BUILD_DIR}/SOURCES/
# if CASSANDRA_VERSION is -alphaN, -betaN, -rcN, then rpmbuild fails on the '-' char; replace with '~'
diff --git a/.build/docker/almalinux-build.docker b/.build/docker/almalinux-build.docker
index 43faed1578..312c62b326 100644
--- a/.build/docker/almalinux-build.docker
+++ b/.build/docker/almalinux-build.docker
@@ -38,17 +38,23 @@ RUN echo "Building with arguments:" \
# install deps
RUN yum -y install \
- ant \
- git \
- java-11-openjdk-devel \
- java-17-openjdk-devel \
- java-21-openjdk-devel \
- make \
- rpm-build \
- sudo \
- python3-pip \
- procps \
- rsync
+ ant git make rpm-build sudo python3-pip procps \
+ java-11-openjdk-devel java-17-openjdk-devel java-21-openjdk-devel \
+ rsync wget curl
+
+# Install pandoc from GitHub releases (not available in AlmaLinux 8 repos)
+ARG PANDOC_VERSION="3.9.0.2"
+RUN sh -c '\
+ set -ex ;\
+ PANDOC_ARCH=amd64 ;\
+ [ $(uname -m) = "aarch64" ] && PANDOC_ARCH=arm64 ;\
+ PANDOC_VERSION_SHAS="a69abfababda8a56969a254b09f9553a7be89ddec00d4e0fe9fd585d71a67508 b6d21e8f9c3b15744f5a7ab40248019157ed7793875dbe0383d4c82ff572b528" ;\
+ PANDOC_TAR="pandoc-${PANDOC_VERSION}-linux-${PANDOC_ARCH}.tar.gz" ;\
+ wget -q "https://github.com/jgm/pandoc/releases/download/${PANDOC_VERSION}/${PANDOC_TAR}" --no-check-certificate ;\
+ PANDOC_SHA="$(sha256sum ${PANDOC_TAR} | cut -d" " -f1)" ;\
+ echo "$PANDOC_VERSION_SHAS" | sed "s/ /\n/g" | grep -q "$PANDOC_SHA" || { echo "SHA256 mismatch for ${PANDOC_TAR} ${PANDOC_SHA}"; exit 1; } ;\
+ tar -xzf "${PANDOC_TAR}" -C /usr/local --strip-components=1 ;\
+ rm "${PANDOC_TAR}"'
RUN until curl -f -S -s --retry 9 --retry-connrefused --retry-delay 1 https://vault.centos.org/7.9.2009/os/x86_64/Packages/ant-junit-1.9.4-2.el7.noarch.rpm -o ant-junit-1.9.4-2.el7.noarch.rpm ; do echo "curl failed… trying again in 10s… " ; sleep 10 ; done
@@ -56,3 +62,42 @@ RUN rpm -i --nodeps ant-junit-1.9.4-2.el7.noarch.rpm
# python3 is needed for the gen-doc target
RUN pip3 install --upgrade pip
+
+# Install Node.js for Antora (documentation generation)
+RUN sh -c '\
+ set -ex ;\
+ NODE_VERSION="v20.16.0" ;\
+ NODE_PLATFORM=x64 ;\
+ [ $(uname -m) = "aarch64" ] && NODE_PLATFORM=arm64 ;\
+ NODE_VERSION_SHAS="c30af7dfea46de7d8b9b370fa33b8b15440bc93f0a686af8601bbb48b82f16c0 1d9929e72f692179f884cd676b2dfabd879cb77defa7869dc8cfc802619277fb" ;\
+ NODE_TAR="node-${NODE_VERSION}-linux-${NODE_PLATFORM}.tar.xz" ;\
+ wget -q "https://nodejs.org/dist/${NODE_VERSION}/${NODE_TAR}" --no-check-certificate ;\
+ NODE_SHA="$(sha256sum ${NODE_TAR} | cut -d" " -f1)" ;\
+ echo "$NODE_VERSION_SHAS" | sed "s/ /\n/g" | grep -q "$NODE_SHA" || { echo "SHA256 mismatch for ${NODE_TAR} ${NODE_SHA}"; exit 1; } ;\
+ tar -xJf "${NODE_TAR}" -C /usr/local --strip-components=1 ;\
+ rm "${NODE_TAR}" ;\
+ ln -s /usr/local/bin/node /usr/local/bin/nodejs'
+
+# Install Antora for documentation generation
+RUN npm i -g @antora/cli@2.3 @antora/site-generator-default@2.3 @djencks/asciidoctor-openblock
+
+# install golang. GO_VERSION_SHA must be updated with VERSION
+
+RUN sh -c '\
+ set -ex ;\
+ GO_VERSION="1.26.1" ;\
+ GO_VERSION_SHAS="031f088e5d955bab8657ede27ad4e3bc5b7c1ba281f05f245bcc304f327c987a a290581cfe4fe28ddd737dde3095f3dbeb7f2e4065cab4eae44dfc53b760c2f7 65773dab2f8cc4cd23d93ba6d0a805de150ca0b78378879292be0b903b8cdd08 353df43a7811ce284c8938b5f3c7df40b7bfb6f56cb165b150bc40b5e2dd541f" ;\
+ GO_OS=linux ;\
+ [ $(uname) = "Darwin" ] && GO_OS=darwin ;\
+ GO_PLATFORM=amd64 ;\
+ [ $(uname -m) = "aarch64" ] && GO_PLATFORM=arm64 ;\
+ GO_TAR="go${GO_VERSION}.${GO_OS}-${GO_PLATFORM}.tar.gz" ;\
+ curl -L --fail --silent --retry 2 --retry-delay 5 --max-time 3600 https://go.dev/dl/$GO_TAR -o $GO_TAR ;\
+ GO_SHA="$(sha256sum $GO_TAR | cut -d" " -f2)" ;\
+ echo "$GO_VERSION_SHAS" | sed "s/ /\n/g" | grep -q "$GO_SHA" || { echo "SHA256 mismatch for $GO_TAR $GO_SHA"; exit 1; } ;\
+ tar -C /usr/local -xzf $GO_TAR ;\
+ rm $GO_TAR'
+
+ENV GOROOT="/usr/local/go"
+ENV GOPATH="$BUILD_HOME/go"
+ENV PATH="$PATH:/usr/local/go/bin"
\ No newline at end of file
diff --git a/.build/docker/build-docs.sh b/.build/docker/build-docs.sh
new file mode 100755
index 0000000000..09b40ff511
--- /dev/null
+++ b/.build/docker/build-docs.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Build in-tree HTML documentation using the cassandra-website Docker image
+# This allows building docs without installing Antora locally
+
+set -e
+
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
+DOC_DIR="${REPO_ROOT}/doc"
+DOCKER_IMAGE="apache/cassandra-website:latest"
+
+echo "Building in-tree HTML documentation using Docker..."
+echo "Docker image: ${DOCKER_IMAGE}"
+
+# Run the full doc build in Docker (generates asciidoc + builds HTML)
+# Use --entrypoint to bypass the cassandra-website entrypoint and ant gen-doc directly
+echo "Running documentation build in Docker..."
+docker run --rm \
+ --entrypoint /bin/bash \
+ -v "${REPO_ROOT}:/cassandra" \
+ -w /cassandra/ \
+ "${DOCKER_IMAGE}" \
+ -c "ant gen-doc"
+
+echo "Documentation built in ${REPO_ROOT}/build/html/"
diff --git a/.build/docker/debian-build.docker b/.build/docker/debian-build.docker
index db38a0b9ab..207d5fd961 100644
--- a/.build/docker/debian-build.docker
+++ b/.build/docker/debian-build.docker
@@ -37,7 +37,7 @@ RUN echo 'Acquire::ftp::Timeout "60";' >> /etc/apt/apt.conf.d/80proxy.conf
# install deps
RUN until apt-get update && apt-get -y install ant build-essential curl devscripts ed git sudo \
- python3-pip rsync procps dh-python quilt bash-completion ; \
+ python3-pip rsync procps dh-python quilt bash-completion pandoc wget ; \
do echo "apt failed… trying again in 10s… " ; sleep 10 ; done
RUN until apt-get install -y --no-install-recommends openjdk-11-jdk openjdk-17-jdk; \
@@ -45,6 +45,7 @@ RUN until apt-get install -y --no-install-recommends openjdk-11-jdk openjdk-17-j
# Download and install OpenJDK 21.0.2 for the current architecture
RUN sh -c '\
+ set -ex ;\
JDK_OS=linux ;\
JDK_TAR="openjdk-21.0.2_${JDK_OS}-$(uname -m | sed "s/x86_64/x64/")_bin.tar.gz" ;\
JDK_VERSION_SHAS="08db1392a48d4eb5ea5315cf8f18b89dbaf36cda663ba882cf03c704c9257ec2 a2def047a73941e01a73739f92755f86b895811afb1f91243db214cff5bdac3f 8fd09e15dc406387a0aba70bf5d99692874e999bf9cd9208b452b5d76ac922d3 b3d588e16ec1e0ef9805d8a696591bd518a5cea62567da8f53b5ce32d11d22e4" ;\
@@ -68,10 +69,29 @@ RUN pip install --upgrade pip
# dependencies for .build/ci/ci_parser.py
RUN pip install beautifulsoup4==4.12.3 jinja2==3.1.3
+# Install Node.js for Antora (documentation generation)
+RUN sh -c '\
+ set -ex ;\
+ NODE_VERSION="v20.16.0" ;\
+ NODE_PLATFORM=x64 ;\
+ [ $(uname -m) = "aarch64" ] && NODE_PLATFORM=arm64 ;\
+ NODE_VERSION_SHAS="c30af7dfea46de7d8b9b370fa33b8b15440bc93f0a686af8601bbb48b82f16c0 1d9929e72f692179f884cd676b2dfabd879cb77defa7869dc8cfc802619277fb" ;\
+ NODE_TAR="node-${NODE_VERSION}-linux-${NODE_PLATFORM}.tar.xz" ;\
+ wget "https://nodejs.org/dist/${NODE_VERSION}/${NODE_TAR}" --no-check-certificate ;\
+ NODE_SHA="$(sha256sum ${NODE_TAR} | cut -d" " -f1)" ;\
+ echo "$NODE_VERSION_SHAS" | sed "s/ /\n/g" | grep -q "$NODE_SHA" || { echo "SHA256 mismatch for ${NODE_TAR} ${NODE_SHA}"; exit 1; } ;\
+ tar -xJf "${NODE_TAR}" -C /usr/local --strip-components=1 ;\
+ rm "${NODE_TAR}" ;\
+ ln -s /usr/local/bin/node /usr/local/bin/nodejs'
+
+# Install Antora for documentation generation
+RUN npm i -g @antora/cli@2.3 @antora/site-generator-default@2.3 @djencks/asciidoctor-openblock
+
# install golang. GO_VERSION_SHA must be updated with VERSION
RUN sh -c '\
- GO_VERSION="1.24.3" ;\
- GO_VERSION_SHAS="3333f6ea53afa971e9078895eaa4ac7204a8c6b5c68c10e6bc9a33e8e391bdd8 a463cb59382bd7ae7d8f4c68846e73c4d589f223c589ac76871b66811ded7836 13e6fe3fcf65689d77d40e633de1e31c6febbdbcb846eb05fc2434ed2213e92b 64a3fa22142f627e78fac3018ce3d4aeace68b743eff0afda8aae0411df5e4fb" ;\
+ set -ex ;\
+ GO_VERSION="1.26.1" ;\
+ GO_VERSION_SHAS="031f088e5d955bab8657ede27ad4e3bc5b7c1ba281f05f245bcc304f327c987a a290581cfe4fe28ddd737dde3095f3dbeb7f2e4065cab4eae44dfc53b760c2f7 65773dab2f8cc4cd23d93ba6d0a805de150ca0b78378879292be0b903b8cdd08 353df43a7811ce284c8938b5f3c7df40b7bfb6f56cb165b150bc40b5e2dd541f" ;\
GO_OS=linux ;\
GO_TAR="go${GO_VERSION}.${GO_OS}-$(dpkg --print-architecture).tar.gz" ;\
curl -L --fail --silent --retry 2 --retry-delay 5 --max-time 3600 https://go.dev/dl/$GO_TAR -o $GO_TAR ;\
diff --git a/.gitignore b/.gitignore
index 4f560f57b2..28c3457035 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,9 +10,6 @@ logs/
data/
!test/data
conf/hotspot_compiler
-doc/antora.yml
-doc/cql3/CQL.html
-doc/build/
lib/
pylib/src/
**/cqlshlib.xml
@@ -81,6 +78,9 @@ Thumbs.db
.ant_targets
# Generated files from the documentation
+doc/antora.yml
+doc/cql3/CQL.html
+doc/lib/
doc/modules/cassandra/pages/managing/configuration/cass_yaml_file.adoc
doc/modules/cassandra/pages/reference/native-protocol.adoc
doc/modules/cassandra/attachments/native_protocol_v*.html
diff --git a/CHANGES.txt b/CHANGES.txt
index 4eee5cba9e..cd6fce2ac6 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,9 +1,9 @@
6.0-alpha2
- * Add tooling to repair system peers and peers_v2 if inconsistent with cluster metadata (CASSANDRA-21187)
+ * In-tree docs are included in binary artifacts (tarball, deb, rpm) as html and man pages (CASSANDRA-17260)
+ * Add tooling to repair system peers and peers_v2 if inconsistent with cluster metadata (CASSANDRA-21187)
* Fix a removed TTLed row re-appearance in a materialized view after a cursor compaction (CASSANDRA-21152)
* Rework ZSTD dictionary compression logic to create a trainer per training (CASSANDRA-21209)
Merged from 5.0:
- * Backport Automated Repair Inside Cassandra for CEP-37 (CASSANDRA-21138)
Merged from 4.1:
* Harden data resurrection startup check with atomic heartbeat file write with fallback (CASSANDRA-21290)
Merged from 4.0:
diff --git a/build.xml b/build.xml
index 96f454a047..4910ce298d 100644
--- a/build.xml
+++ b/build.xml
@@ -614,6 +614,7 @@
+
@@ -697,7 +698,7 @@
-
+
@@ -993,6 +994,8 @@
+
@@ -1012,8 +1015,12 @@
-
-
+
+
+
+
+
+
@@ -1048,6 +1055,10 @@
+
+
+
diff --git a/debian/cassandra.install b/debian/cassandra.install
index 0573128ddd..09a4cad27f 100644
--- a/debian/cassandra.install
+++ b/debian/cassandra.install
@@ -32,3 +32,5 @@ lib/*.jar usr/share/cassandra/lib
lib/*.zip usr/share/cassandra/lib
lib/x86_64/* usr/share/cassandra/lib/x86_64
lib/aarch64/* usr/share/cassandra/lib/aarch64
+build/html/* usr/share/doc/cassandra/html
+build/man/*.7.gz usr/share/man/man7
diff --git a/debian/rules b/debian/rules
index 70305b41e9..cb8d1b357a 100755
--- a/debian/rules
+++ b/debian/rules
@@ -41,9 +41,7 @@ build: build-stamp
build-stamp: $(QUILT_STAMPFN)
dh_testdir
printf "version=%s" $(VERSION) > build.properties
-
- $(ANT) generate-cql-html
- $(ANT) jar -Dno-checkstyle=true -Drat.skip=true -Dant.gen-doc.skip=true
+ $(ANT) jar -Djavadoc.skip=true -Dcheck.skip=true -Dant.gen-doc.skip=true
cd pylib && python3 setup.py install --no-compile --install-layout deb \
--root $(CURDIR)/debian/cassandra
diff --git a/doc/Makefile b/doc/Makefile
index efa16f308f..3b7225f444 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -15,10 +15,32 @@ GENERATE_ANTORA_YML = ./scripts/gen-antora-yml.py
GENERATE_NODETOOL_DOCS = ./scripts/gen-nodetool-docs.py
MAKE_CASSANDRA_YAML = ./scripts/convert_yaml_to_adoc.py ../conf/cassandra.yaml ./modules/cassandra/pages/managing/configuration/cass_yaml_file.adoc
PROCESS_NATIVE_PROC_SPECS = ./scripts/process-native-protocol-specs-in-docker.sh
+TABS_BLOCK_JS_URL = https://raw.githubusercontent.com/apache/cassandra-website/trunk/site-content/lib/tabs-block.js
+
+.PHONY: init
+init:
+ @# Antora requires a git repository (remove after antora 3.2+)
+ @if [ ! -d ../.git ]; then \
+ echo "creating temporary git repository for Antora..."; \
+ cd ..; \
+ git init -b "tmp-antora-build" ; \
+ git config user.email "build@cassandra.apache.org" && git config user.name "Cassandra Build" ; \
+ git add doc ; git commit --author="Cassandra Build " -m "temp commit for antora build" ; \
+ cd doc; \
+ fi
+ @command -v antora >/dev/null 2>&1 || { echo "Error: antora not found. Install it globally or use .build/docker/build-docs.sh"; exit 1; }
+ @echo "Downloading Antora extension dependencies..."
+ @mkdir -p lib
+ @if [ ! -f lib/tabs-block.js ]; then \
+ echo "Downloading tabs-block.js..."; \
+ curl -fsSL -o lib/tabs-block.js $(TABS_BLOCK_JS_URL); \
+ fi
.PHONY: html
-html:
- @# hack until a local basic antora build is put in
+html: init
+ @echo "Building in-tree HTML documentation with Antora..."
+ antora site-local.yml
+ @echo "Documentation built in build/html/"
.PHONY: gen-asciidoc
gen-asciidoc:
@@ -28,3 +50,31 @@ gen-asciidoc:
python3 $(GENERATE_NODETOOL_DOCS)
python3 $(MAKE_CASSANDRA_YAML)
$(PROCESS_NATIVE_PROC_SPECS)
+
+.PHONY: manpages
+manpages:
+ @echo "Generating man page from HTML documentation..."
+ @mkdir -p ../build/man && rm -f ../build/man/cassandra-docs-combined.html
+ @# Concatenate HTML files using sitemap.xml order
+ @echo "Using sitemap.xml for navigation order..."
+ @grep -o '[^<]*' ../build/html/sitemap.xml | \
+ sed 's|||g; s|||g' | sed 's|^https\{0,1\}://[^/]*/||' | sed 's|^doc/||' | grep '/cassandra/' \
+ > ../build/man/urls.txt
+ @while read url; do \
+ file="../build/html/$$url"; \
+ rel_path=$$(echo "$$url" | sed 's|^.*/cassandra/|cassandra/|'); \
+ echo "
$$rel_path
" >> ../build/man/cassandra-docs-combined.html; \
+ python3 ./scripts/extract-html-content.py "$$file" >> ../build/man/cassandra-docs-combined.html 2>/dev/null; \
+ done < ../build/man/urls.txt
+ @# Convert combined HTML to man page format using pandoc
+ @command -v pandoc >/dev/null 2>&1 || { echo "Error: pandoc not found."; exit 1; }
+ @pandoc -s -f html -t man \
+ --metadata title="Apache Cassandra Documentation" \
+ --metadata section=7 \
+ --metadata date="$$(date +'%B %Y')" \
+ --metadata footer="Apache Cassandra" \
+ -o ../build/man/cassandra.7 \
+ ../build/man/cassandra-docs-combined.html
+ @gzip -f ../build/man/cassandra.7
+ @rm -f ../build/man/urls.txt ../build/man/cassandra-docs-combined.html
+ echo "Man page generated, view with: man build/man/cassandra.7.gz"
diff --git a/doc/README.md b/doc/README.md
index 0d534a52b9..0bed6d8e2b 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -32,32 +32,41 @@ Cassandra. This directory contains the following documents:
Official documentation
----------------------
-The source for the official documentation for Apache Cassandra can be found in
-the `modules/cassandra/pages` subdirectory. The documentation uses [antora](http://www.antora.org/)
-and is thus written in [asciidoc](http://asciidoc.org).
+The source for the official documentation for Apache Cassandra can be found in the `modules/cassandra/pages` subdirectory. The documentation uses [antora](http://www.antora.org/) and is thus written in [asciidoc](http://asciidoc.org).
-The `antora.yml` file is auto-generated and should not be manually edited. It is generated from the version in `build.xml` using `scripts/gen-antora-yml.py` and automatically detects whether building from a release tag or branch HEAD to set the appropriate version.
+The `antora.yml` file is auto-generated and should not be manually edited. It is generated from the version in `build.xml` using `scripts/gen-antora-yml.py` and automatically detects whether building from a release tag or branch HEAD to set the appropriate full or short version.
-To generate the asciidoc files (including antora.yml) for cassandra.yaml and the nodetool commands, run (from project root):
-```bash
-ant gen-asciidoc
-```
-or (from this directory):
+The antora.yml and some of the asciidoc files are dynamically generated using `ant gen-asciidoc`.
-```bash
-make gen-asciidoc
-```
+## Building HTML Pages
+To build the HTML documentation for this version only, you have two options:
-(The following has not yet been implemented, for now see the build instructions in the [cassandra-website](https://github.com/apache/cassandra-website) repo.)
-To build the documentation, run (from project root):
-
+**Option 1: Using globally installed Antora** (requires Node.js, Antora and Pandoc installed):
```bash
ant gen-doc
```
-or (from this directory):
+This uses the `site-local.yml` antora playbook to build only the current in-tree version.
+**Option 2: Using Docker**:
```bash
-make html
+.build/docker/build-docs.sh
+```
+This uses the same Docker image as cassandra-website, with all tooling pre-installed.
+
+The HTML will be generated in `build/html/`.
+
+For building documentation across multiple Cassandra versions, see the build instructions in the [cassandra-website](https://github.com/apache/cassandra-website) repo.
+
+
+## Building Man Pages
+
+Building the html documentation also generates a manpages file.
+
+**View the man page**:
+```bash
+man ../build/man/cassandra-docs.7.gz
```
+**Note**: This creates a single comprehensive reference manual (section 7) containing all documentation.
+
diff --git a/doc/modules/ROOT/nav.adoc b/doc/modules/ROOT/nav.adoc
index 3d367ad242..3c1a3b8c45 100644
--- a/doc/modules/ROOT/nav.adoc
+++ b/doc/modules/ROOT/nav.adoc
@@ -1,4 +1,5 @@
* xref:index.adoc[Main]
+ifndef::local-build[]
** xref:master@_:ROOT:glossary.adoc[Glossary]
** xref:master@_:ROOT:bugs.adoc[How to report bugs]
** xref:master@_:ROOT:contactus.adoc[Contact us]
@@ -14,3 +15,4 @@
*** xref:master@_:ROOT:development/ci.adoc[Jenkins CI environment]
*** xref:master@_:ROOT:development/dependencies.adoc[Dependency management]
*** xref:master@_:ROOT:development/release_process.adoc[Release process]
+endif::[]
diff --git a/doc/modules/ROOT/pages/index.adoc b/doc/modules/ROOT/pages/index.adoc
index beeb121f22..0ba9816b6d 100644
--- a/doc/modules/ROOT/pages/index.adoc
+++ b/doc/modules/ROOT/pages/index.adoc
@@ -46,9 +46,19 @@ If you would like to contribute to this documentation, you are welcome to do so
== Meta information
+ifndef::local-build[]
* xref:master@_:ROOT:bugs.adoc[Reporting bugs]
* xref:master@_:ROOT:contactus.adoc[Contact us]
* xref:master@_:ROOT:development/index.adoc[Contributing code]
* xref:master@_:ROOT:docdev/index.adoc[Contributing to the docs]
* xref:master@_:ROOT:community.adoc[Community]
* xref:master@_:ROOT:download.adoc[Download]
+endif::[]
+ifdef::local-build[]
+* https://cassandra.apache.org/_/bugs.html[Reporting bugs]
+* https://cassandra.apache.org/_/contactus.html[Contact us]
+* https://cassandra.apache.org/_/development/index.html[Contributing code]
+* https://cassandra.apache.org/_/docdev/index.html[Contributing to the docs]
+* https://cassandra.apache.org/_/community.html[Community]
+* https://cassandra.apache.org/download/[Download]
+endif::[]
diff --git a/doc/scripts/extract-html-content.py b/doc/scripts/extract-html-content.py
new file mode 100755
index 0000000000..b20a860ed8
--- /dev/null
+++ b/doc/scripts/extract-html-content.py
@@ -0,0 +1,88 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+"""
+Extract main content from HTML files for man page generation.
+Strips navigation, headers, footers, and other boilerplate.
+"""
+
+import sys
+import re
+from pathlib import Path
+
+def extract_content(html_content):
+ """
+ Extract main content from HTML, removing navigation and boilerplate.
+ Uses simple regex-based approach to avoid external dependencies.
+ """
+ # Remove script and style tags
+ html_content = re.sub(r'', '', html_content, flags=re.DOTALL | re.IGNORECASE)
+ html_content = re.sub(r'', '', html_content, flags=re.DOTALL | re.IGNORECASE)
+
+ # Try to extract main content area (Antora uses or )
+ # Look for common content containers
+ patterns = [
+ r']*>(.*?)',
+ r']*>(.*?)',
+ r'
]*class="[^"]*doc[^"]*"[^>]*>(.*?)
',
+ r'
]*class="[^"]*content[^"]*"[^>]*>(.*?)
',
+ ]
+
+ for pattern in patterns:
+ match = re.search(pattern, html_content, flags=re.DOTALL | re.IGNORECASE)
+ if match:
+ content = match.group(1)
+ # Remove navigation elements within content
+ content = re.sub(r'', '', content, flags=re.DOTALL | re.IGNORECASE)
+ content = re.sub(r'