Переглянути джерело

Various fixes to the scripts to reduce code and user steps, and updated doc

Signed-off-by: chanmosq <[email protected]>
chanmosq 2 роки тому
батько
коміт
dda9888293

+ 3 - 0
.gitignore

@@ -1,2 +1,5 @@
 .vscode
 
+# Ignore the following files in o3de-doxygen
+/tools/o3de-doxygen/build/*
+/tools/o3de-doxygen/*.log

+ 3 - 3
tools/README.md

@@ -2,6 +2,6 @@
 
 A collection of tools and scripts for maintaining the [O3DE Documentation](https://www.o3de.org/docs).
 
-| Tool | Documentation | Description |
-| --- | --- | --- |
-| [o3de-doxygen](o3de-doxygen/) | [C++ API Reference Generation](o3de-doxygen.md) | To generate C++ API References for frameworks and Gems in [`o3de`](https://github.com/o3de/o3de) |
+| Tool | Description |
+| --- | --- |
+| [o3de-doxygen](o3de-doxygen/) | To generate C++ API References for frameworks and Gems in [`o3de`](https://github.com/o3de/o3de). |

+ 178 - 0
tools/o3de-doxygen/README.md

@@ -0,0 +1,178 @@
+# C++ API Reference Generation
+
+The [Open 3D Engine (O3DE) API Reference](https://www.o3de.org/docs/api/) is generated using [Doxygen](https://www.doxygen.nl/). With the help of the API Reference Generation (`o3de-doxygen`) scripts to automate the process, an API reference is generated for all frameworks and Gems in the [`o3de` repository](https://github.com/o3de/o3de.org) by default.  You may also configure the scripts to [generate API references for Gems in other O3DE repositories]((#generating-for-gems-outside-of-o3de)).
+
+
+## Requirements
+
+* Linux machine or Windows Subsystem for Linux (WSL)
+* Clone of the `o3de` repository in your machine
+* Clone of the `o3de.org` repository in your machine
+* [Doxygen](https://www.doxygen.nl/manual/install.html) installation
+
+## Set up 
+
+### Download `o3de-doxygen`
+
+1. Clone the  [`sig-docs-community` repository](https://github.com/o3de/sig-docs-community/), which contains the `o3de-doxygen` scripts.
+2. In the `tools` directory, find the `o3de-doxygen` scripts.
+
+
+### Install rust commands
+
+The `o3de-doxygen` scripts use some efficient Rust commands for processing the source code in `o3de`. You must install Rust and the `fd-find` cargo to run the scripts properly. 
+
+
+1. Install Rust by using [rustup](https://rustup.rs/), or by running the following command in your Linux machine: 
+
+    ```shell
+    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
+    ```
+
+1. Add rust to your environment variables.
+
+    ```shell
+    source "$HOME/.cargo/env"
+    ```
+
+1. Install the `fd-find` cargo, which is a file searching tool:
+
+    ```shell
+    cargo install fd-find
+    ```
+
+
+
+### Clean repos
+
+The C++ API reference generation scripts runs Doxygen on your local `o3de` clone. Then it outputs the generated files into your local `o3de.org` clone. Therefore, before you generate the API, you must ensure that your cloned repos are clean and have the latest changes.
+
+#### `o3de`
+
+1. In your local `o3de` clone, `git checkout` the latest updates in the `development` branch, or in the case of a major O3DE release, the `stabilization` branch. 
+
+    ```shell
+    git fetch --all
+    git checkout upstream/<branch> 
+    ```
+   -  **upstream**: Set to track the source repo, [`https://github.com/o3de/o3de.git`](https://github.com/o3de/o3de.git)
+
+1. Run  `git clean` in your local O3DE clone.
+
+#### `o3de.org`
+
+1. In your local `o3de.org` clone, `git checkout` the latest updates in the `development` branch, or in the case of a major O3DE release, the `stabilization` branch. 
+
+    ```shell
+    git fetch --all
+    git checkout upstream/<branch> 
+    ```
+   -  **upstream**: Set to track the source repo, [`https://github.com/o3de/o3de.org.git`](https://github.com/o3de/o3de.org.git)
+
+1. Create a new branch, such as `api-ref`. This branch will contain the API reference docs that you will [generate](#generate) later. 
+
+    ```shell
+    git switch -c api-ref
+    ```
+
+1. Make sure the `api-ref` branch is clean from any untracked files or changes. The branch should be at the same state as the upstream branch's HEAD. To clean, run  `git clean`, `git reset`, or `git stash` as needed.
+
+### Prepare scripts
+
+1. In `config.sh` set the following variables:
+
+   - `O3DE_PATH`: Path to your local o3de clone  (e.g. $HOME/o3de)
+
+   - `O3DEORG_PATH`: Path to your local o3de.org clone (e.g. $HOME/o3de.org)
+
+    The C++ API reference generation scripts read from `o3de` and write to `o3de.org`. 
+
+1. If this is your first time running the script, you may need to enable permissions to execute the program. In the `o3de-doxygen` directory, run the following: 
+
+```shell
+cd <path-to>/o3de-doxygen
+chmod +x *.sh
+```
+
+## Generate
+
+The following scripts generate the frameworks and Gems APIs. 
+
+### Frameworks API
+
+In the `o3de-doxygen` directory, run the script:
+
+```shell
+./o3de-framework-apis.sh
+```
+
+This generates the following files in `o3de.org`: 
+ - `content/docs/api/frameworks/_index.md`
+ - `static/docs/api/frameworks/*`
+
+### Gems API
+
+*Note: You must [install rust commands](#install-rust-commands) to run `o3de-gem-apis.sh`.*
+
+In the `o3de-doxygen` directory, run the script:
+
+```shell
+./o3de-gem-apis.sh
+```
+
+This generates the following files in `o3de.org`: 
+  - `content/docs/api/gems/_index.md`
+  - `static/docs/api/gems/*`
+
+
+
+## Publish
+
+After generating the C++ API reference and supplemental files, it's time to publish them on the website. When you [cleaned your `o3de.org` clone](#o3deorg), you set up a new clean branch, such as `api-ref`, and when you [generated](#generate) the APIs, the files were placed in that branch. 
+
+To publish the newly generated APIs, you must run `git add`, `git commit`, `git push`, and create a new pull request. For guidance through each step, please refer to the [O3DE Docs Contributions: Runbook](https://www.o3de.org/docs/contributing/to-docs/git-workflow/).
+
+
+## Generating for Gems outside of `o3de`
+
+In some cases, the O3DE API Reference must include the API for code that lives outside of the `o3de` repository. This is typically decided by O3DE members and the Release Special Interest Group (SIG). For example, a major O3DE release may include new Gems that live in the `o3de-extras` repository.
+
+To generate API References for Gems outside of `o3de`: 
+
+1. Move the Gem's directory into the `Gems` directory of your local `o3de` clone.
+
+2. [Generate the Gems API](#gems-api). 
+
+
+## Customizing the API's main page
+
+The main page is the first page you see when you open a framework or Gem's Doxygen-generated API reference. For example, open any [framework](https://www.o3de.org/docs/api/frameworks/) or [Gem](https://www.o3de.org/docs/api/gems/) in the API docs. The contents of the main page is either automatically generated, or specified by the developer by using the Doxygen command, [/mainpage](https://doxygen.nl/manual/commands.html#cmdmainpage), in the code's comments.
+
+By default, if `/mainpage` is not specified, an API's main page includes a brief introduction and a table of contents, like the following: 
+
+![Default mainpage example](files/default-mainpage-example.png)
+
+If a developer documents the API using `/mainpage`, it will replace the default introduction. However, you may still insert the table of contents by adding `o3de-doxygen-insert-table` to your `/mainpage` comment block. For example, this comment block in the AQtComponents's source code generates the following main page. 
+
+```
+/**
+ * \mainpage
+ * 
+ * Using this library, UI developers can build their own tools and
+ * extensions for Open 3D Engine, while maintaining a coherent and standardized UI experience.
+ * This custom library provides new and extended widgets, and includes a set of styles and
+ * user interaction patterns that are applied on top of the Qt framework - the C++ library
+ * that Open 3D Engine relies on for its UI. The library can be extended to support your own customizations and modifications. 
+ * 
+ * With this UI 2.0 API reference guide, we're working towards offering a full and comprehensive
+ * API reference for all tools developers that are extending Open 3D Engine. The API reference
+ * is intended for C++ programmers building tools. For UX designers looking to understand
+ * the best patterns and practices when making a tool to comfortably integrate with
+ * the Open 3D Engine editor, see the [UI 2.0 design guide](https://o3de.org/docs/tools-ui/ui-dev-intro/).
+ * 
+ * o3de-doxygen-insert-table
+ * 
+ */
+```
+
+![Main page example](files/mainpage-example.png)

+ 7 - 0
tools/o3de-doxygen/config.sh

@@ -0,0 +1,7 @@
+#!/bin/bash
+
+# Path to user's local o3de repository  (e.g. $HOME/o3de)
+O3DE_PATH=
+
+# Path to user's local o3de.org repository (e.g. $HOME/o3de.org)
+O3DEORG_PATH=

BIN
tools/o3de-doxygen/files/default-mainpage-example.png


BIN
tools/o3de-doxygen/files/mainpage-example.png


+ 4 - 4
tools/o3de-doxygen/index.md

@@ -1,7 +1,7 @@
 
-Welcome to the **Open 3D Engine (O3DE)** API Reference for the **WhiteBox Gem**!
+    Welcome to the **Open 3D Engine (O3DE)** API Reference for the **WhiteBox Gem**!
 
-INSERT_TABLE
-
-Return to the [Gems API Reference](/docs/api/gems) index page. 
+    o3de-doxygen-insert-table
 
+    Return to the [Gems API Reference](/docs/api/gems) index page. 
+    

+ 114 - 0
tools/o3de-doxygen/o3de-api-functions.sh

@@ -0,0 +1,114 @@
+#!/bin/bash
+
+# TOC_PATTERN exists in index.html files to mark a placeholder for the Table of Contents (TOC) table.
+# It's automatically written to index.md template, which is used to generate index.html files.
+# It may also be manually added to code comments, by using the Doxygen /mainpage command.
+TOC_PATTERN=o3de-doxygen-insert-table
+
+# Link to Related Pages page
+function find_pages() {
+	local line="<td><a href=\"pages.html\">Related Pages</a> </td><td>The list related documentation pages. </td></tr>"
+	[ -f $API_PATH/pages.html ] && DOXY_PAGES=$line || DOXY_ANNOTATED=""
+}
+
+function find_modules() {
+	local line="<td><a href=\"modules.html\">Modules</a> </td><td>The list all modules. </td></tr>"
+	[ -f $API_PATH/modules.html ] && DOXY_MODULES=$line || DOXY_ANNOTATED=""
+}
+
+# Link to Namespaces List page
+function find_namespace_list() {
+	local line="<td><a href=\"namespaces.html\">Namespace List</a> </td><td>The list all documented namedspaces. </td></tr>"
+	[ -f $API_PATH/namespaces.html ] && DOXY_NAMESPACELIST=$line || DOXY_ANNOTATED=""
+}
+
+# Link to Namespaces Members page
+function find_namespace_members() {
+	local line="<td><a href=\"namespacemembers.html\">Namespace Members</a> </td><td>The list all documented namedspace members. </td></tr>"
+	[ -f $API_PATH/namespacemembers.html ] && DOXY_NAMESPACEMEMBERS=$line || DOXY_ANNOTATED=""
+}
+
+# Link to Class List page
+function find_annotated() {
+	local line="<td><a href=\"annotated.html\">Class List</a> </td><td>The list of classes, structs, unions, and interfaces. </td></tr>"
+	[ -f $API_PATH/classes.html ] && DOXY_ANNOTATED=$line || DOXY_ANNOTATED=""
+}
+
+# Link to Class Index page
+function find_classes() {
+	local line="<td><a href=\"classes.html\">Class Index</a> </td><td>The list of classes, structs, unions, and interfaces. </td></tr>"
+	[ -f $API_PATH/classes.html ] && DOXY_CLASSES=$line || DOXY_CLASSES=""
+}
+
+# Link to Class Members page
+function find_functions() {
+	local line="<td><a href=\"functions.html\">Class Members</a> </td><td>The list of class members. </td></tr>"
+	[ -f $API_PATH/functions.html ] && DOXY_FUNCTIONS=$line || DOXY_FUNCTIONS=""
+}
+
+# Link to Class Hierarchy page
+function find_hierarchy() {
+	local line="<td><a href=\"hierarchy.html\">Class Hierarchy</a> </td><td>The class hierarchy based on inheritance. </td></tr>"
+	[ -f $API_PATH/hierarchy.html ] && DOXY_HIERARCHY=$line || DOXY_HIERARCHY=""
+}
+
+# Link to File List page
+function find_files() {
+	local line="<td><a href=\"files.html\">File List</a> </td><td>The list of all documented files. </td></tr>"
+	[ -f $API_PATH/files.html ] && DOXY_FILELIST=$line || DOXY_HIERARCHY=""
+}
+
+# Link to File List page
+function find_file_members() {
+	local line="<td><a href=\"globals.html\">File Members</a> </td><td>The list of all documented file members. </td></tr>"
+	[ -f $API_PATH/globals.html ] && DOXY_FILEMEMBERS=$line || DOXY_HIERARCHY=""
+}
+
+# Link to File List page
+function find_examples() {
+	local line="<td><a href=\"examples.html\">File Members</a> </td><td>The list of all documented examples. </td></tr>"
+	[ -f $API_PATH/examples.html ] && DOXY_EXAMPLES=$line || DOXY_HIERARCHY=""
+}
+
+function generate_toc () {
+	API_PATH="$1"
+	API_NAME="$2"	
+
+	SECTION="<h3>Sections</h3>\n<p>Refer to the following sections of the $API_NAME API Reference.</p>"
+	BEGIN_TABLE="<table class="doxtable">\n<tr>\n<th>Section </th><th>Description </th></tr>\n<tr>"
+	END_TABLE="</table>"
+
+	# To hold links to generated pages
+	DOXY_PAGES=""
+    DOXY_MODULES=""
+    DOXY_NAMESPACELIST=""
+    DOXY_NAMESPACEMEMBERS=""    
+    DOXY_ANNOTATED=""
+	DOXY_CLASSES=""
+    DOXY_FUNCTIONS=""
+    DOXY_HIERARCHY=""
+    DOXY_FILELIST=""
+    DOXY_FILEMEMBERS=""
+    DOXY_EXAMPLES=""
+    
+	# Set links to DOXY_ variables
+    find_pages
+    find_modules
+    find_namespace_list
+    find_namespace_members
+	find_annotated      		# Sets $DOXY_ANNOTATED
+	find_classes        		# Sets $DOXY_CLASSES
+    find_functions      		# Sets $DOXY_FUNCTIONS
+    find_hierarchy      		# Sets $DOXY_HIERARCHY
+    find_files
+    find_file_members
+    find_examples
+
+    # Create the table of contents string
+    # This is in one line due to issues using multi-line vars with sed
+	LINE="$SECTION$BEGIN_TABLE$DOXY_PAGES$DOXY_MODULES$DOXY_NAMESPACELIST$DOXY_NAMESPACEMEMBERS$DOXY_ANNOTATED$DOXY_CLASSES$DOXY_FUNCTIONS$DOXY_HIERARCHY$DOXY_FILELIST$DOXY_FILEMEMBERS$DOXY_EXAMPLES$END_TABLE"	
+
+    # Find $PATTERN in index.html and replace with $LINE
+	sed -i "/$TOC_PATTERN/ c\\$LINE" $API_PATH/index.html
+
+}

+ 31 - 128
tools/o3de-doxygen/o3de-framework-apis.sh

@@ -1,132 +1,35 @@
 #!/bin/bash
 
-# Link to Related Pages page
-function find_pages() {
-	local line="<td><a href=\"pages.html\">Related Pages</a> </td><td>The list related documentation pages. </td></tr>"
-	[ -f $API_PATH/pages.html ] && DOXY_PAGES=$line || DOXY_ANNOTATED=""
-}
-
-function find_modules() {
-	local line="<td><a href=\"modules.html\">Modules</a> </td><td>The list all modules. </td></tr>"
-	[ -f $API_PATH/modules.html ] && DOXY_MODULES=$line || DOXY_ANNOTATED=""
-}
-
-# Link to Namespaces List page
-function find_namespace_list() {
-	local line="<td><a href=\"namespaces.html\">Namespace List</a> </td><td>The list all documented namedspaces. </td></tr>"
-	[ -f $API_PATH/namespaces.html ] && DOXY_NAMESPACELIST=$line || DOXY_ANNOTATED=""
-}
-
-# Link to Namespaces Members page
-function find_namespace_members() {
-	local line="<td><a href=\"namespacemembers.html\">Namespace Members</a> </td><td>The list all documented namedspace members. </td></tr>"
-	[ -f $API_PATH/namespacemembers.html ] && DOXY_NAMESPACEMEMBERS=$line || DOXY_ANNOTATED=""
-}
-
-# Link to Class List page
-function find_annotated() {
-	local line="<td><a href=\"annotated.html\">Class List</a> </td><td>The list of classes, structs, unions, and interfaces. </td></tr>"
-	[ -f $API_PATH/classes.html ] && DOXY_ANNOTATED=$line || DOXY_ANNOTATED=""
-}
-
-# Link to Class Index page
-function find_classes() {
-	local line="<td><a href=\"classes.html\">Class Index</a> </td><td>The list of classes, structs, unions, and interfaces. </td></tr>"
-	[ -f $API_PATH/classes.html ] && DOXY_CLASSES=$line || DOXY_CLASSES=""
-}
-
-# Link to Class Members page
-function find_functions() {
-	local line="<td><a href=\"functions.html\">Class Members</a> </td><td>The list of class members. </td></tr>"
-	[ -f $API_PATH/functions.html ] && DOXY_FUNCTIONS=$line || DOXY_FUNCTIONS=""
-}
-
-# Link to Class Hierarchy page
-function find_hierarchy() {
-	local line="<td><a href=\"hierarchy.html\">Class Hierarchy</a> </td><td>The class hierarchy based on inheritance. </td></tr>"
-	[ -f $API_PATH/hierarchy.html ] && DOXY_HIERARCHY=$line || DOXY_HIERARCHY=""
-}
-
-# Link to File List page
-function find_files() {
-	local line="<td><a href=\"files.html\">File List</a> </td><td>The list of all documented files. </td></tr>"
-	[ -f $API_PATH/files.html ] && DOXY_FILELIST=$line || DOXY_HIERARCHY=""
-}
-
-# Link to File List page
-function find_file_members() {
-	local line="<td><a href=\"globals.html\">File Members</a> </td><td>The list of all documented file members. </td></tr>"
-	[ -f $API_PATH/globals.html ] && DOXY_FILEMEMBERS=$line || DOXY_HIERARCHY=""
-}
-
-# Link to File List page
-function find_examples() {
-	local line="<td><a href=\"examples.html\">File Members</a> </td><td>The list of all documented examples. </td></tr>"
-	[ -f $API_PATH/examples.html ] && DOXY_EXAMPLES=$line || DOXY_HIERARCHY=""
-}
-
-function generate_toc () {
-
-	SECTION="<h3>Sections</h3>\n<p>Refer to the following sections of the $API_NAME API Reference.</p>"
-	BEGIN_TABLE="<table class="doxtable">\n<tr>\n<th>Section </th><th>Description </th></tr>\n<tr>"
-	END_TABLE="</table>"
-	DOXY_PAGES=""
-    DOXY_MODULES=""
-    DOXY_NAMESPACELIST=""
-    DOXY_NAMESPACEMEMBERS=""    
-    DOXY_ANNOTATED=""
-	DOXY_CLASSES=""
-    DOXY_FUNCTIONS=""
-    DOXY_HIERARCHY=""
-    DOXY_FILELIST=""
-    DOXY_FILEMEMBERS=""
-    DOXY_EXAMPLES=""
-    
+source ./o3de-api-functions.sh
+source ./config.sh
+
+# Path to output generated files
+OUTPUT_DIRECTORY=${O3DEORG_PATH}/static/docs/api/frameworks  
+
+# Path to source code
+FRAMEWORKS=${O3DE_PATH}/Code/Framework
+
+# Frameworks API landing page template
+LANDING_TEMPLATE=framework_index.md
 
-    find_pages
-    find_modules
-    find_namespace_list
-    find_namespace_members
-	find_annotated      # Sets $DOXY_ANNOTATED
-	find_classes        # Sets $DOXY_CLASSES
-    find_functions      # Sets $DOXY_FUNCTIONS
-    find_hierarchy      # Sets $DOXY_HIERARCHY
-    find_files
-    find_file_members
-    find_examples
-
-    # Create the table of contents string
-    # Difficult readability due to issues with multi-line vars and sed
-	LINE="$SECTION$BEGIN_TABLE$DOXY_PAGES$DOXY_MODULES$DOXY_NAMESPACELIST$DOXY_NAMESPACEMEMBERS$DOXY_ANNOTATED$DOXY_CLASSES$DOXY_FUNCTIONS$DOXY_HIERARCHY$DOXY_FILELIST$DOXY_FILEMEMBERS$DOXY_EXAMPLES$END_TABLE"	
-
-    # Find pattern in index.html and replace the line with $LINE
-    # The pattern is first set in index.md, which doxygen uses to generate index.html files
-	sed -i "/INSERT_TABLE/ c\\$LINE" $API_PATH/index.html
-
-}
-
-function test_generate_toc () {
-
-	echo $API_PATH
-	generate_toc
-	echo "CLASSES=$CLASSES"
-	echo "ANNOTATED=$ANNOTATED"
-	echo "LINE=$LINE"
-}
-
-o3de_path=/workplace/chanmosq/o3de
-frameworks=${o3de_path}/Code/Framework
-toc=framework_index.md
-output_toc=build/${toc}
-if [ ! -e "${output_toc%%/*}" ]; then
-    mkdir -p ${output_toc%%/*}
+# File to output LANDING_TEMPLATE
+OUTPUT_TOC=${O3DEORG_PATH}/content/docs/api/frameworks/_index.md
+
+# Create Frameworks API landing page (https://www.o3de.org/docs/api/frameworks/)
+# If parent directories don't exist, create them
+if [ ! -e "${OUTPUT_TOC%%/*}" ]; then
+    mkdir -p "${OUTPUT_TOC%%/*}"
 fi
-cp ${toc} ${output_toc}
+cp ${LANDING_TEMPLATE} ${OUTPUT_TOC}
+
+# Generate a set of API docs for each framework
+for framework_path in `ls -1d ${FRAMEWORKS}/*/ `; do
+
+    # Configure and run Doxygen
 
-for framework_path in `ls -1d ${frameworks}/*/ `; do
     framework=`basename ${framework_path}`
 
-    echo "* [${framework}](/docs/api/frameworks/${framework})" >> ${output_toc}
+    echo "* [${framework}](/docs/api/frameworks/${framework})" >> ${OUTPUT_TOC}
 
     config_file=`mktemp`
     index="index.md"
@@ -135,7 +38,7 @@ for framework_path in `ls -1d ${frameworks}/*/ `; do
     "
     Welcome to the **Open 3D Engine (O3DE)** API Reference for the **${framework}** framework!
 
-    INSERT_TABLE
+    $TOC_PATTERN
 
     Return to the [Frameworks API Reference](/docs/api/frameworks) index page. 
 
@@ -148,16 +51,16 @@ for framework_path in `ls -1d ${frameworks}/*/ `; do
 
     cat $main_config >> $config_file
     echo PROJECT_NAME=\"Open 3D Engine ${framework} API Reference\" >> $config_file
-    echo OUTPUT_DIRECTORY=build/frameworks >> $config_file
+    echo OUTPUT_DIRECTORY=${OUTPUT_DIRECTORY} >> $config_file
     echo INPUT=${framework_path} ${index} >> $config_file
     echo HTML_OUTPUT=${framework} >> $config_file
-    echo STRIP_FROM_PATH=$o3de_path >> $config_file
+    echo STRIP_FROM_PATH=$O3DE_PATH >> $config_file
 
     echo "${framework}: Using config ${config_file}, landing page ${index}"
     doxygen $config_file
 
-    API_PATH=build/frameworks/${framework}
-    API_NAME=${framework}
-    generate_toc
+    # Post-process generated files
+    
+    generate_toc "${OUTPUT_DIRECTORY}/${framework}" "${framework}"
 
 done

+ 37 - 131
tools/o3de-doxygen/o3de-gem-apis.sh

@@ -1,144 +1,47 @@
 #!/bin/bash
 
-# Link to Related Pages page
-function find_pages() {
-	local line="<td><a href=\"pages.html\">Related Pages</a> </td><td>The list related documentation pages. </td></tr>"
-	[ -f $API_PATH/pages.html ] && DOXY_PAGES=$line || DOXY_ANNOTATED=""
-}
-
-function find_modules() {
-	local line="<td><a href=\"modules.html\">Modules</a> </td><td>The list all modules. </td></tr>"
-	[ -f $API_PATH/modules.html ] && DOXY_MODULES=$line || DOXY_ANNOTATED=""
-}
-
-# Link to Namespaces List page
-function find_namespace_list() {
-	local line="<td><a href=\"namespaces.html\">Namespace List</a> </td><td>The list all documented namedspaces. </td></tr>"
-	[ -f $API_PATH/namespaces.html ] && DOXY_NAMESPACELIST=$line || DOXY_ANNOTATED=""
-}
-
-# Link to Namespaces Members page
-function find_namespace_members() {
-	local line="<td><a href=\"namespacemembers.html\">Namespace Members</a> </td><td>The list all documented namedspace members. </td></tr>"
-	[ -f $API_PATH/namespacemembers.html ] && DOXY_NAMESPACEMEMBERS=$line || DOXY_ANNOTATED=""
-}
-
-# Link to Class List page
-function find_annotated() {
-	local line="<td><a href=\"annotated.html\">Class List</a> </td><td>The list of classes, structs, unions, and interfaces. </td></tr>"
-	[ -f $API_PATH/classes.html ] && DOXY_ANNOTATED=$line || DOXY_ANNOTATED=""
-}
-
-# Link to Class Index page
-function find_classes() {
-	local line="<td><a href=\"classes.html\">Class Index</a> </td><td>The list of classes, structs, unions, and interfaces. </td></tr>"
-	[ -f $API_PATH/classes.html ] && DOXY_CLASSES=$line || DOXY_CLASSES=""
-}
-
-# Link to Class Members page
-function find_functions() {
-	local line="<td><a href=\"functions.html\">Class Members</a> </td><td>The list of class members. </td></tr>"
-	[ -f $API_PATH/functions.html ] && DOXY_FUNCTIONS=$line || DOXY_FUNCTIONS=""
-}
-
-# Link to Class Hierarchy page
-function find_hierarchy() {
-	local line="<td><a href=\"hierarchy.html\">Class Hierarchy</a> </td><td>The class hierarchy based on inheritance. </td></tr>"
-	[ -f $API_PATH/hierarchy.html ] && DOXY_HIERARCHY=$line || DOXY_HIERARCHY=""
-}
-
-# Link to File List page
-function find_files() {
-	local line="<td><a href=\"files.html\">File List</a> </td><td>The list of all documented files. </td></tr>"
-	[ -f $API_PATH/files.html ] && DOXY_FILELIST=$line || DOXY_HIERARCHY=""
-}
-
-# Link to File List page
-function find_file_members() {
-	local line="<td><a href=\"globals.html\">File Members</a> </td><td>The list of all documented file members. </td></tr>"
-	[ -f $API_PATH/globals.html ] && DOXY_FILEMEMBERS=$line || DOXY_HIERARCHY=""
-}
-
-# Link to File List page
-function find_examples() {
-	local line="<td><a href=\"examples.html\">File Members</a> </td><td>The list of all documented examples. </td></tr>"
-	[ -f $API_PATH/examples.html ] && DOXY_EXAMPLES=$line || DOXY_HIERARCHY=""
-}
-
-function generate_toc () {
-
-	SECTION="<h3>Sections</h3>\n<p>Refer to the following sections of the $API_NAME API Reference.</p>"
-	BEGIN_TABLE="<table class="doxtable">\n<tr>\n<th>Section </th><th>Description </th></tr>\n<tr>"
-	END_TABLE="</table>"
-	DOXY_PAGES=""
-    DOXY_MODULES=""
-    DOXY_NAMESPACELIST=""
-    DOXY_NAMESPACEMEMBERS=""    
-    DOXY_ANNOTATED=""
-	DOXY_CLASSES=""
-    DOXY_FUNCTIONS=""
-    DOXY_HIERARCHY=""
-    DOXY_FILELIST=""
-    DOXY_FILEMEMBERS=""
-    DOXY_EXAMPLES=""
-    
-
-    find_pages
-    find_modules
-    find_namespace_list
-    find_namespace_members
-	find_annotated      # Sets $DOXY_ANNOTATED
-	find_classes        # Sets $DOXY_CLASSES
-    find_functions      # Sets $DOXY_FUNCTIONS
-    find_hierarchy      # Sets $DOXY_HIERARCHY
-    find_files
-    find_file_members
-    find_examples
-
-    # Create the table of contents string
-    # Difficult readability due to issues with multi-line vars and sed
-	LINE="$SECTION$BEGIN_TABLE$DOXY_PAGES$DOXY_MODULES$DOXY_NAMESPACELIST$DOXY_NAMESPACEMEMBERS$DOXY_ANNOTATED$DOXY_CLASSES$DOXY_FUNCTIONS$DOXY_HIERARCHY$DOXY_FILELIST$DOXY_FILEMEMBERS$DOXY_EXAMPLES$END_TABLE"	
-
-    # Find pattern in index.html and replace the line with $LINE
-    # The pattern is first set in index.md, which doxygen uses to generate index.html files
-	sed -i "/INSERT_TABLE/ c\\$LINE" $API_PATH/index.html
-
-}
-
-function test_generate_toc () {
-
-	echo $API_PATH
-	generate_toc
-	echo "CLASSES=$CLASSES"
-	echo "ANNOTATED=$ANNOTATED"
-	echo "LINE=$LINE"
-}
-
-o3de_path=/workplace/chanmosq/o3de
-gems=${o3de_path}/Gems
-toc=gems_index.md
-output_toc=build/${toc}
-if [ ! -e "${output_toc%%/*}" ]; then
-    mkdir -p ${output_toc%%/*}
+source ./o3de-api-functions.sh
+source ./config.sh
+
+# Path to output generated files
+OUTPUT_DIRECTORY=${O3DEORG_PATH}/static/docs/api/gems  
+
+# Path to source code
+GEMS=${O3DE_PATH}/Gems
+
+# Gems API landing page template
+LANDING_TEMPLATE=gems_index.md
+
+# File to output LANDING_TEMPLATE
+OUTPUT_TOC=${O3DEORG_PATH}/content/docs/api/gems/${toc}
+
+# Create Gems API landing page (https://www.o3de.org/docs/api/gems/)
+# If parent directories don't exist, create them
+if [ ! -e "${OUTPUT_TOC%%/*}" ]; then
+    mkdir -p ${OUTPUT_TOC%%/*}
 fi
-cp ${toc} ${output_toc}
+cp ${LANDING_TEMPLATE} ${OUTPUT_TOC}
+
+# Generate a set of API docs for each Gem
+for gem_path in `ls -1d ${GEMS}/*/`; do
+
+    # Configure and run Doxygen
 
-for gem_path in `ls -1d ${gems}/*/`; do
     gem=`basename ${gem_path}`
 
-    echo "* [${gem}](/docs/api/gems/${gem})" >> ${output_toc}
+    echo "* [${gem}](/docs/api/gems/${gem})" >> ${OUTPUT_TOC}
 
     config_file=`mktemp`
     index=index.md
 
     echo \
-"
-Welcome to the **Open 3D Engine (O3DE)** API Reference for the **${gem} Gem**!
+    "
+    Welcome to the **Open 3D Engine (O3DE)** API Reference for the **${gem} Gem**!
 
-INSERT_TABLE
+    $TOC_PATTERN
 
-Return to the [Gems API Reference](/docs/api/gems) index page. 
-" > $index
+    Return to the [Gems API Reference](/docs/api/gems) index page. 
+    " > $index
 
     main_config="core-api-doxygen.config"
     if [ -e "${gem}.doxygen" ]; then
@@ -147,15 +50,18 @@ Return to the [Gems API Reference](/docs/api/gems) index page.
 
     cat $main_config >> $config_file
     echo PROJECT_NAME=\"Open 3D Engine ${gem} Gem API Reference\" >> $config_file
-    echo OUTPUT_DIRECTORY=build/gems >> $config_file
+    echo OUTPUT_DIRECTORY=${OUTPUT_DIRECTORY} >> $config_file
     echo INPUT=$(fd -t d -X echo {} \; -- Include ${gem_path}) $index >> $config_file
     echo HTML_OUTPUT=${gem} >> $config_file
-    echo STRIP_FROM_PATH=$o3de_path >> $config_file
+    echo STRIP_FROM_PATH=$O3DE_PATH >> $config_file
 
     echo "${gem}: Using config ${config_file}, landing page ${index}"
+
     doxygen $config_file
 
+    # Post-process generated files
+
     API_PATH=build/gems/${gem}
     API_NAME=${gem}
-    generate_toc
+    generate_toc "${OUTPUT_DIRECTORY}/${gem}" "${gem}"
 done