diff --git a/.github/actions/Build-PSModule/action.yml b/.github/actions/Build-PSModule/action.yml index 8143f3bd..ba3459da 100644 --- a/.github/actions/Build-PSModule/action.yml +++ b/.github/actions/Build-PSModule/action.yml @@ -40,9 +40,7 @@ runs: PSMODULE_BUILD_PSMODULE_INPUT_OutputFolder: ${{ inputs.OutputFolder }} PSMODULE_BUILD_PSMODULE_INPUT_Version: ${{ inputs.Version }} PSMODULE_BUILD_PSMODULE_INPUT_Prerelease: ${{ inputs.Prerelease }} - run: | - # Build-PSModule - ${{ github.action_path }}/src/main.ps1 + run: ${{ github.action_path }}/src/main.ps1 - name: Upload module artifact uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 diff --git a/.github/actions/Build-ZensicalSite/README.md b/.github/actions/Build-ZensicalSite/README.md new file mode 100644 index 00000000..f4eb2bb9 --- /dev/null +++ b/.github/actions/Build-ZensicalSite/README.md @@ -0,0 +1,16 @@ +# Build-ZensicalSite + +Builds Zensical documentation site output and normalizes it to `/_site`. + +## Inputs + +- `WorkingDirectory` (required): Build working directory. + +## Usage + +```yaml +- name: Build documentation site with Zensical + uses: ./_wf/.github/actions/Build-ZensicalSite + with: + WorkingDirectory: . +``` diff --git a/.github/actions/Build-ZensicalSite/action.yml b/.github/actions/Build-ZensicalSite/action.yml new file mode 100644 index 00000000..5031f0a9 --- /dev/null +++ b/.github/actions/Build-ZensicalSite/action.yml @@ -0,0 +1,16 @@ +name: Build-ZensicalSite +description: Build Zensical site output and normalize output folder. + +inputs: + WorkingDirectory: + description: Working directory for the repository build. + required: true + +runs: + using: composite + steps: + - name: Build documentation site + shell: pwsh + env: + INPUT_WORKING_DIRECTORY: ${{ inputs.WorkingDirectory }} + run: '& "${{ github.action_path }}/src/main.ps1" -WorkingDirectory "$env:INPUT_WORKING_DIRECTORY"' diff --git a/.github/actions/Build-ZensicalSite/src/build-zensical-site.ps1 b/.github/actions/Build-ZensicalSite/src/build-zensical-site.ps1 new file mode 100644 index 00000000..090f1a09 --- /dev/null +++ b/.github/actions/Build-ZensicalSite/src/build-zensical-site.ps1 @@ -0,0 +1,29 @@ +param( + [Parameter(Mandatory)] + [string]$WorkingDirectory +) + +$ErrorActionPreference = 'Stop' + +$resolvedWorkingDirectory = Resolve-Path -Path $WorkingDirectory | Select-Object -ExpandProperty Path +$siteWorkingDirectory = Join-Path -Path $resolvedWorkingDirectory -ChildPath 'outputs/site' +$outputSitePath = Join-Path -Path $resolvedWorkingDirectory -ChildPath '_site' + +Set-Location -Path $siteWorkingDirectory + +if (-not (Test-Path -Path 'zensical.toml')) { + throw "No documentation config file found in outputs/site. Expected zensical.toml." +} + +zensical build --config-file 'zensical.toml' + +if (Test-Path -Path '_site') { + if (Test-Path -Path $outputSitePath) { + Remove-Item -Path $outputSitePath -Recurse -Force + } + Move-Item -Path '_site' -Destination $outputSitePath -Force +} + +if (-not (Test-Path -Path $outputSitePath)) { + throw "Expected Zensical output at $outputSitePath but it was not created." +} diff --git a/.github/actions/Build-ZensicalSite/src/main.ps1 b/.github/actions/Build-ZensicalSite/src/main.ps1 new file mode 100644 index 00000000..080a8dea --- /dev/null +++ b/.github/actions/Build-ZensicalSite/src/main.ps1 @@ -0,0 +1,50 @@ +#Requires -Version 7.0 + +<# + .SYNOPSIS + Builds the Zensical site and normalizes output to the expected _site path. + + .DESCRIPTION + Runs zensical build from outputs/site and moves the generated _site directory + to /_site for downstream workflow steps. + + .EXAMPLE + ./main.ps1 -WorkingDirectory '.' + + .INPUTS + None. + + .OUTPUTS + None. +#> +[CmdletBinding()] +param( + # Build working directory containing outputs/site and destination _site. + [Parameter(Mandatory)] + [string]$WorkingDirectory +) + +$ErrorActionPreference = 'Stop' + +$resolvedWorkingDirectory = Resolve-Path -Path $WorkingDirectory | Select-Object -ExpandProperty Path +$siteWorkingDirectory = Join-Path -Path $resolvedWorkingDirectory -ChildPath 'outputs/site' +$outputSitePath = Join-Path -Path $resolvedWorkingDirectory -ChildPath '_site' + +Set-Location -Path $siteWorkingDirectory + +if (-not (Test-Path -Path 'zensical.toml')) { + throw "No documentation config file found in outputs/site. Expected zensical.toml." +} + +zensical build --config-file 'zensical.toml' + +if (Test-Path -Path '_site') { + if (Test-Path -Path $outputSitePath) { + Remove-Item -Path $outputSitePath -Recurse -Force + } + Move-Item -Path '_site' -Destination $outputSitePath -Force +} + +if (-not (Test-Path -Path $outputSitePath)) { + throw "Expected Zensical output at $outputSitePath but it was not created." +} diff --git a/.github/actions/Cleanup-PSModulePrereleases/action.yml b/.github/actions/Cleanup-PSModulePrereleases/action.yml index af728ffd..3c076b45 100644 --- a/.github/actions/Cleanup-PSModulePrereleases/action.yml +++ b/.github/actions/Cleanup-PSModulePrereleases/action.yml @@ -29,6 +29,4 @@ runs: env: PSMODULE_CLEANUP_PSMODULEPRERELEASES_INPUT_WhatIf: ${{ inputs.WhatIf }} PSMODULE_CLEANUP_PSMODULEPRERELEASES_CONTEXT_ReleaseTag: ${{ env.PSMODULE_PUBLISH_PSMODULE_CONTEXT_ReleaseTag }} - run: | - # Cleanup prerelease tags - ${{ github.action_path }}/src/cleanup.ps1 + run: ${{ github.action_path }}/src/cleanup.ps1 diff --git a/.github/actions/Cleanup-PSModulePrereleases/src/cleanup.ps1 b/.github/actions/Cleanup-PSModulePrereleases/src/cleanup.ps1 index 546593a8..a10bdf1d 100644 --- a/.github/actions/Cleanup-PSModulePrereleases/src/cleanup.ps1 +++ b/.github/actions/Cleanup-PSModulePrereleases/src/cleanup.ps1 @@ -3,7 +3,7 @@ param() $PSStyle.OutputRendering = 'Ansi' -Import-Module -Name 'Helpers' -Force +Import-Module -Name 'PSModule' -Force #region Load inputs LogGroup 'Load inputs' { diff --git a/.github/actions/Document-PSModule/action.yml b/.github/actions/Document-PSModule/action.yml index f9d01a54..d82f83ab 100644 --- a/.github/actions/Document-PSModule/action.yml +++ b/.github/actions/Document-PSModule/action.yml @@ -27,6 +27,4 @@ runs: DOCUMENT_PSMODULE_INPUT_Name: ${{ inputs.Name }} DOCUMENT_PSMODULE_INPUT_ShowSummaryOnSuccess: ${{ inputs.ShowSummaryOnSuccess }} working-directory: ${{ inputs.WorkingDirectory }} - run: | - # Build-PSModuleDocumentation - ${{ github.action_path }}/src/main.ps1 + run: ${{ github.action_path }}/src/main.ps1 diff --git a/.github/actions/Expose-TestData/action.yml b/.github/actions/Expose-TestData/action.yml index 67d9e936..38acc14d 100644 --- a/.github/actions/Expose-TestData/action.yml +++ b/.github/actions/Expose-TestData/action.yml @@ -20,5 +20,4 @@ runs: shell: pwsh env: PSMODULE_TEST_DATA: ${{ inputs.TestData }} - run: | - Import-TestData + run: Import-TestData diff --git a/.github/actions/Inject-SiteScripts/README.md b/.github/actions/Inject-SiteScripts/README.md new file mode 100644 index 00000000..9c75bdb1 --- /dev/null +++ b/.github/actions/Inject-SiteScripts/README.md @@ -0,0 +1,18 @@ +# Inject-SiteScripts + +Injects JavaScript snippets from `.github/scripts/site-injectors/*.js` into generated HTML files. + +## Inputs + +- `SitePath` (required): Path to generated site output. +- `WorkflowPath` (optional, default `_wf`): Path where workflow repository is checked out. + +## Usage + +```yaml +- name: Inject shared site scripts + uses: ./_wf/.github/actions/Inject-SiteScripts + with: + SitePath: ./_site + WorkflowPath: _wf +``` diff --git a/.github/actions/Inject-SiteScripts/action.yml b/.github/actions/Inject-SiteScripts/action.yml new file mode 100644 index 00000000..0a280e76 --- /dev/null +++ b/.github/actions/Inject-SiteScripts/action.yml @@ -0,0 +1,21 @@ +name: Inject-SiteScripts +description: Inject shared JavaScript snippets into generated site HTML files. + +inputs: + SitePath: + description: Path to the generated site output directory. + required: true + WorkflowPath: + description: Path to the checked out workflow repository root. + required: false + default: _wf + +runs: + using: composite + steps: + - name: Inject site scripts + shell: pwsh + env: + INPUT_SITE_PATH: ${{ inputs.SitePath }} + INPUT_WORKFLOW_PATH: ${{ inputs.WorkflowPath }} + run: '& "${{ github.action_path }}/src/main.ps1" -SitePath "$env:INPUT_SITE_PATH" -WorkflowPath "$env:INPUT_WORKFLOW_PATH"' diff --git a/.github/actions/Inject-SiteScripts/src/inject-site-scripts.ps1 b/.github/actions/Inject-SiteScripts/src/inject-site-scripts.ps1 new file mode 100644 index 00000000..3c10d48a --- /dev/null +++ b/.github/actions/Inject-SiteScripts/src/inject-site-scripts.ps1 @@ -0,0 +1,41 @@ +param( + [Parameter(Mandatory)] + [string]$SitePath, + + [Parameter(Mandatory)] + [string]$WorkflowPath +) + +$resolvedSitePath = Resolve-Path -Path $SitePath -ErrorAction Stop | Select-Object -ExpandProperty Path +$injectorsPath = Join-Path -Path $env:GITHUB_WORKSPACE -ChildPath "$WorkflowPath/.github/scripts/site-injectors" + +if (-not (Test-Path -Path $injectorsPath)) { + throw "Expected site injector folder at $injectorsPath but it was not found." +} + +$injectorScripts = Get-ChildItem -Path $injectorsPath -File -Filter '*.js' | Sort-Object -Property Name +if (-not $injectorScripts) { + Write-Host "No site injector scripts found under $injectorsPath." + exit 0 +} + +Get-ChildItem -Path $resolvedSitePath -Filter '*.html' -Recurse | ForEach-Object { + $html = Get-Content -Path $_.FullName -Raw + $modified = $false + + foreach ($injectorScript in $injectorScripts) { + $marker = "data-psmodule-site-injector=""$($injectorScript.Name)""" + if ($html -match [Regex]::Escape($marker)) { + continue + } + + $scriptContent = Get-Content -Path $injectorScript.FullName -Raw + $injectedScript = "" + $html = $html -replace '', "$injectedScript`n" + $modified = $true + } + + if ($modified) { + Set-Content -Path $_.FullName -Value $html -NoNewline + } +} diff --git a/.github/actions/Inject-SiteScripts/src/main.ps1 b/.github/actions/Inject-SiteScripts/src/main.ps1 new file mode 100644 index 00000000..6fcdad0d --- /dev/null +++ b/.github/actions/Inject-SiteScripts/src/main.ps1 @@ -0,0 +1,63 @@ +#Requires -Version 7.0 + +<# + .SYNOPSIS + Injects shared JavaScript snippets into generated site HTML files. + + .DESCRIPTION + Reads scripts from .github/scripts/site-injectors in the checked out workflow + repository and injects each script into every HTML file under SitePath, once per file. + + .EXAMPLE + ./main.ps1 -SitePath './_site' -WorkflowPath '_wf' + + .INPUTS + None. + + .OUTPUTS + None. +#> +[CmdletBinding()] +param( + # Path to generated site output directory containing HTML files. + [Parameter(Mandatory)] + [string]$SitePath, + + # Relative path to the checked out workflow repository root. + [Parameter(Mandatory)] + [string]$WorkflowPath +) + +$resolvedSitePath = Resolve-Path -Path $SitePath -ErrorAction Stop | Select-Object -ExpandProperty Path +$injectorsPath = Join-Path -Path $env:GITHUB_WORKSPACE -ChildPath "$WorkflowPath/.github/scripts/site-injectors" + +if (-not (Test-Path -Path $injectorsPath)) { + throw "Expected site injector folder at $injectorsPath but it was not found." +} + +$injectorScripts = Get-ChildItem -Path $injectorsPath -File -Filter '*.js' | Sort-Object -Property Name +if (-not $injectorScripts) { + Write-Host "No site injector scripts found under $injectorsPath." + exit 0 +} + +Get-ChildItem -Path $resolvedSitePath -Filter '*.html' -Recurse | ForEach-Object { + $html = Get-Content -Path $_.FullName -Raw + $modified = $false + + foreach ($injectorScript in $injectorScripts) { + $marker = "data-psmodule-site-injector=""$($injectorScript.Name)""" + if ($html -match [Regex]::Escape($marker)) { + continue + } + + $scriptContent = Get-Content -Path $injectorScript.FullName -Raw + $injectedScript = "" + $html = $html -replace '', "$injectedScript`n" + $modified = $true + } + + if ($modified) { + Set-Content -Path $_.FullName -Value $html -NoNewline + } +} diff --git a/.github/actions/Install-PSModule/action.yml b/.github/actions/Install-PSModule/action.yml index 2f749694..0b3f3440 100644 --- a/.github/actions/Install-PSModule/action.yml +++ b/.github/actions/Install-PSModule/action.yml @@ -6,6 +6,4 @@ runs: steps: - name: Install-PSModule shell: pwsh - run: | - # Install-PSModule - ${{ github.action_path }}/src/main.ps1 + run: ${{ github.action_path }}/src/main.ps1 diff --git a/.github/actions/Install-Zensical/README.md b/.github/actions/Install-Zensical/README.md new file mode 100644 index 00000000..1939aba2 --- /dev/null +++ b/.github/actions/Install-Zensical/README.md @@ -0,0 +1,14 @@ +# Install-Zensical + +Installs the Zensical CLI used by site build workflows. + +## Inputs + +None. + +## Usage + +```yaml +- name: Install Zensical + uses: ./_wf/.github/actions/Install-Zensical +``` diff --git a/.github/actions/Install-Zensical/action.yml b/.github/actions/Install-Zensical/action.yml new file mode 100644 index 00000000..18a16b4b --- /dev/null +++ b/.github/actions/Install-Zensical/action.yml @@ -0,0 +1,9 @@ +name: Install-Zensical +description: Install Zensical CLI used for documentation site generation. + +runs: + using: composite + steps: + - name: Install Zensical CLI + shell: pwsh + run: '& "${{ github.action_path }}/src/main.ps1"' diff --git a/.github/actions/Install-Zensical/src/install-zensical.ps1 b/.github/actions/Install-Zensical/src/install-zensical.ps1 new file mode 100644 index 00000000..a42e7982 --- /dev/null +++ b/.github/actions/Install-Zensical/src/install-zensical.ps1 @@ -0,0 +1,3 @@ +$ErrorActionPreference = 'Stop' + +pip install zensical diff --git a/.github/actions/Install-Zensical/src/main.ps1 b/.github/actions/Install-Zensical/src/main.ps1 new file mode 100644 index 00000000..936e4886 --- /dev/null +++ b/.github/actions/Install-Zensical/src/main.ps1 @@ -0,0 +1,24 @@ +#Requires -Version 7.0 + +<# + .SYNOPSIS + Installs the Zensical CLI used by site build workflows. + + .DESCRIPTION + Installs the zensical Python package in the current runner environment. + + .EXAMPLE + ./main.ps1 + + .INPUTS + None. + + .OUTPUTS + None. +#> +[CmdletBinding()] +param() + +$ErrorActionPreference = 'Stop' + +pip install zensical diff --git a/.github/actions/Publish-PSModule/action.yml b/.github/actions/Publish-PSModule/action.yml index c855fe20..0ff0a534 100644 --- a/.github/actions/Publish-PSModule/action.yml +++ b/.github/actions/Publish-PSModule/action.yml @@ -46,8 +46,7 @@ runs: - name: Update Microsoft.PowerShell.PSResourceGet shell: pwsh - run: | - Install-PSResource -Name Microsoft.PowerShell.PSResourceGet -Repository PSGallery -TrustRepository + run: Install-PSResource -Name Microsoft.PowerShell.PSResourceGet -Repository PSGallery -TrustRepository - name: Download module artifact uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 diff --git a/.github/actions/Publish-PSModule/src/publish.ps1 b/.github/actions/Publish-PSModule/src/publish.ps1 index d99b31be..b9f76254 100644 --- a/.github/actions/Publish-PSModule/src/publish.ps1 +++ b/.github/actions/Publish-PSModule/src/publish.ps1 @@ -27,7 +27,7 @@ param() $PSStyle.OutputRendering = 'Ansi' -Import-Module -Name 'Helpers' -Force +Import-Module -Name 'PSModule' -Force #region Load inputs LogGroup 'Load inputs' { diff --git a/.github/actions/Resolve-PSModuleVersion/action.yml b/.github/actions/Resolve-PSModuleVersion/action.yml index e9f8981e..20b41883 100644 --- a/.github/actions/Resolve-PSModuleVersion/action.yml +++ b/.github/actions/Resolve-PSModuleVersion/action.yml @@ -58,8 +58,7 @@ runs: - name: Install PSSemVer shell: pwsh - run: | - Install-PSResource -Name PSSemVer -Repository PSGallery -TrustRepository + run: Install-PSResource -Name PSSemVer -Repository PSGallery -TrustRepository - name: Resolve module version id: resolve @@ -71,6 +70,4 @@ runs: PSMODULE_RESOLVE_PSMODULEVERSION_INPUT_Name: ${{ inputs.Name }} PSMODULE_RESOLVE_PSMODULEVERSION_INPUT_EventJson: ${{ inputs.EventJson }} GITHUB_EVENT_PATH: ${{ inputs.EventPath || github.event_path }} - run: | - # Resolve module version - ${{ github.action_path }}/src/main.ps1 + run: ${{ github.action_path }}/src/main.ps1 diff --git a/.github/actions/Structure-Site/README.md b/.github/actions/Structure-Site/README.md new file mode 100644 index 00000000..203f9564 --- /dev/null +++ b/.github/actions/Structure-Site/README.md @@ -0,0 +1,18 @@ +# Structure-Site + +Prepares site content and writes a resolved Zensical config file under `outputs/site`. + +## Inputs + +- `WorkingDirectory` (required): Build working directory. +- `Name` (optional): Module name override. + +## Usage + +```yaml +- name: Structure site + uses: ./_wf/.github/actions/Structure-Site + with: + WorkingDirectory: . + Name: MyModule +``` diff --git a/.github/actions/Structure-Site/action.yml b/.github/actions/Structure-Site/action.yml new file mode 100644 index 00000000..cb6d5cd2 --- /dev/null +++ b/.github/actions/Structure-Site/action.yml @@ -0,0 +1,21 @@ +name: Structure-Site +description: Structure generated docs and create site config for Zensical. + +inputs: + WorkingDirectory: + description: Working directory for the repository build. + required: true + Name: + description: Optional module name override. + required: false + default: '' + +runs: + using: composite + steps: + - name: Structure site content and config + shell: pwsh + env: + INPUT_WORKING_DIRECTORY: ${{ inputs.WorkingDirectory }} + INPUT_NAME: ${{ inputs.Name }} + run: '& "${{ github.action_path }}/src/main.ps1" -WorkingDirectory "$env:INPUT_WORKING_DIRECTORY" -Name "$env:INPUT_NAME"' diff --git a/.github/actions/Structure-Site/src/main.ps1 b/.github/actions/Structure-Site/src/main.ps1 new file mode 100644 index 00000000..44c8d20c --- /dev/null +++ b/.github/actions/Structure-Site/src/main.ps1 @@ -0,0 +1,99 @@ +#Requires -Version 7.0 + +<# + .SYNOPSIS + Structures generated documentation content and writes a resolved site config. + + .DESCRIPTION + Copies generated docs, README, and assets into outputs/site and resolves zensical.toml + placeholders and site_dir for build execution. + + .EXAMPLE + ./main.ps1 -WorkingDirectory '.' -Name 'MyModule' + + .INPUTS + None. + + .OUTPUTS + None. +#> +[CmdletBinding()] +param( + # Build working directory where src/, README.md, and outputs/ exist. + [Parameter(Mandatory)] + [string]$WorkingDirectory, + + # Optional module name override used for placeholder replacement. + [Parameter()] + [string]$Name +) + +$ErrorActionPreference = 'Stop' + +$resolvedWorkingDirectory = Resolve-Path -Path $WorkingDirectory | Select-Object -ExpandProperty Path +$siteOutputPath = Join-Path -Path $resolvedWorkingDirectory -ChildPath 'outputs/site' +$docsOutputPath = Join-Path -Path $resolvedWorkingDirectory -ChildPath 'outputs/docs' +$moduleSourcePath = Join-Path -Path $resolvedWorkingDirectory -ChildPath 'src' +$moduleName = if ([string]::IsNullOrEmpty($Name)) { $env:GITHUB_REPOSITORY_NAME } else { $Name } + +$functionDocsFolder = New-Item -Path (Join-Path -Path $siteOutputPath -ChildPath 'docs/Functions') -ItemType Directory -Force +Copy-Item -Path (Join-Path -Path $docsOutputPath -ChildPath '*') -Destination $functionDocsFolder.FullName -Recurse -Force + +Write-Host "Function Docs Folder: $($functionDocsFolder.FullName)" +Write-Host "Module Name: $moduleName" +Write-Host "Module Source Path: $moduleSourcePath" +Write-Host "Site Output Path: $siteOutputPath" + +$aboutDocsFolder = New-Item -Path (Join-Path -Path $siteOutputPath -ChildPath 'docs/About') -ItemType Directory -Force +$aboutSourceFolder = Join-Path -Path $moduleSourcePath -ChildPath 'en-US' +if (Test-Path -Path $aboutSourceFolder) { + Get-ChildItem -Path $aboutSourceFolder -Filter '*.txt' | Copy-Item -Destination $aboutDocsFolder.FullName -Force -PassThru | + Rename-Item -NewName { $_.Name -replace '\.txt$', '.md' } +} + +$assetsFolder = New-Item -Path (Join-Path -Path $siteOutputPath -ChildPath 'docs/Assets') -ItemType Directory -Force +$iconPath = Join-Path -Path $resolvedWorkingDirectory -ChildPath 'icon/icon.png' +if (Test-Path -Path $iconPath) { + Copy-Item -Path $iconPath -Destination $assetsFolder.FullName -Force +} + +$readmePath = Join-Path -Path $resolvedWorkingDirectory -ChildPath 'README.md' +$readmeTargetPath = Join-Path -Path $siteOutputPath -ChildPath 'docs/README.md' +Copy-Item -Path $readmePath -Destination $readmeTargetPath -Force + +$possiblePaths = @( + '.github/zensical.toml', + 'docs/zensical.toml', + 'zensical.toml' +) + +$docsConfigSourcePath = $null +foreach ($relativePath in $possiblePaths) { + $candidatePath = Join-Path -Path $resolvedWorkingDirectory -ChildPath $relativePath + if (Test-Path -Path $candidatePath) { + $docsConfigSourcePath = $candidatePath + break + } +} + +if (-not $docsConfigSourcePath) { + throw "Documentation config file not found. Expected one of: $($possiblePaths -join ', ')" +} + +$docsConfigFileName = [System.IO.Path]::GetFileName($docsConfigSourcePath) +$docsConfigTargetPath = Join-Path -Path $siteOutputPath -ChildPath $docsConfigFileName + +$docsConfigContent = Get-Content -Path $docsConfigSourcePath -Raw +$docsConfigContent = $docsConfigContent.Replace('-{{ REPO_NAME }}-', $moduleName) +$docsConfigContent = $docsConfigContent.Replace('-{{ REPO_OWNER }}-', $env:GITHUB_REPOSITORY_OWNER) + +if ($docsConfigFileName -eq 'zensical.toml') { + if ($docsConfigContent -match '(?m)^\s*site_dir\s*=') { + $docsConfigContent = $docsConfigContent -replace '(?m)^\s*site_dir\s*=.*$', 'site_dir = "_site"' + } else { + $docsConfigContent = $docsConfigContent -replace '(?m)^\[project\]\s*$', "[project]`nsite_dir = ""_site""" + } +} + +Set-Content -Path $docsConfigTargetPath -Value $docsConfigContent -Force +Write-Host "Build Config Type: $docsConfigFileName" diff --git a/.github/actions/Structure-Site/src/structure-site.ps1 b/.github/actions/Structure-Site/src/structure-site.ps1 new file mode 100644 index 00000000..68ece30b --- /dev/null +++ b/.github/actions/Structure-Site/src/structure-site.ps1 @@ -0,0 +1,77 @@ +param( + [Parameter(Mandatory)] + [string]$WorkingDirectory, + + [Parameter()] + [string]$Name +) + +$ErrorActionPreference = 'Stop' + +$resolvedWorkingDirectory = Resolve-Path -Path $WorkingDirectory | Select-Object -ExpandProperty Path +$siteOutputPath = Join-Path -Path $resolvedWorkingDirectory -ChildPath 'outputs/site' +$docsOutputPath = Join-Path -Path $resolvedWorkingDirectory -ChildPath 'outputs/docs' +$moduleSourcePath = Join-Path -Path $resolvedWorkingDirectory -ChildPath 'src' +$moduleName = if ([string]::IsNullOrEmpty($Name)) { $env:GITHUB_REPOSITORY_NAME } else { $Name } + +$functionDocsFolder = New-Item -Path (Join-Path -Path $siteOutputPath -ChildPath 'docs/Functions') -ItemType Directory -Force +Copy-Item -Path (Join-Path -Path $docsOutputPath -ChildPath '*') -Destination $functionDocsFolder.FullName -Recurse -Force + +Write-Host "Function Docs Folder: $($functionDocsFolder.FullName)" +Write-Host "Module Name: $moduleName" +Write-Host "Module Source Path: $moduleSourcePath" +Write-Host "Site Output Path: $siteOutputPath" + +$aboutDocsFolder = New-Item -Path (Join-Path -Path $siteOutputPath -ChildPath 'docs/About') -ItemType Directory -Force +$aboutSourceFolder = Join-Path -Path $moduleSourcePath -ChildPath 'en-US' +if (Test-Path -Path $aboutSourceFolder) { + Get-ChildItem -Path $aboutSourceFolder -Filter '*.txt' | Copy-Item -Destination $aboutDocsFolder.FullName -Force -PassThru | + Rename-Item -NewName { $_.Name -replace '\.txt$', '.md' } +} + +$assetsFolder = New-Item -Path (Join-Path -Path $siteOutputPath -ChildPath 'docs/Assets') -ItemType Directory -Force +$iconPath = Join-Path -Path $resolvedWorkingDirectory -ChildPath 'icon/icon.png' +if (Test-Path -Path $iconPath) { + Copy-Item -Path $iconPath -Destination $assetsFolder.FullName -Force +} + +$readmePath = Join-Path -Path $resolvedWorkingDirectory -ChildPath 'README.md' +$readmeTargetPath = Join-Path -Path $siteOutputPath -ChildPath 'docs/README.md' +Copy-Item -Path $readmePath -Destination $readmeTargetPath -Force + +$possiblePaths = @( + '.github/zensical.toml', + 'docs/zensical.toml', + 'zensical.toml' +) + +$docsConfigSourcePath = $null +foreach ($relativePath in $possiblePaths) { + $candidatePath = Join-Path -Path $resolvedWorkingDirectory -ChildPath $relativePath + if (Test-Path -Path $candidatePath) { + $docsConfigSourcePath = $candidatePath + break + } +} + +if (-not $docsConfigSourcePath) { + throw "Documentation config file not found. Expected one of: $($possiblePaths -join ', ')" +} + +$docsConfigFileName = [System.IO.Path]::GetFileName($docsConfigSourcePath) +$docsConfigTargetPath = Join-Path -Path $siteOutputPath -ChildPath $docsConfigFileName + +$docsConfigContent = Get-Content -Path $docsConfigSourcePath -Raw +$docsConfigContent = $docsConfigContent.Replace('-{{ REPO_NAME }}-', $moduleName) +$docsConfigContent = $docsConfigContent.Replace('-{{ REPO_OWNER }}-', $env:GITHUB_REPOSITORY_OWNER) + +if ($docsConfigFileName -eq 'zensical.toml') { + if ($docsConfigContent -match '(?m)^\s*site_dir\s*=') { + $docsConfigContent = $docsConfigContent -replace '(?m)^\s*site_dir\s*=.*$', 'site_dir = "_site"' + } else { + $docsConfigContent = $docsConfigContent -replace '(?m)^\[project\]\s*$', "[project]`nsite_dir = ""_site""" + } +} + +Set-Content -Path $docsConfigTargetPath -Value $docsConfigContent -Force +Write-Host "Build Config Type: $docsConfigFileName" diff --git a/.github/actions/Test-PSModule/action.yml b/.github/actions/Test-PSModule/action.yml index 4f7030d1..621c9032 100644 --- a/.github/actions/Test-PSModule/action.yml +++ b/.github/actions/Test-PSModule/action.yml @@ -276,9 +276,7 @@ runs: env: PSMODULE_TEST_PSMODULE_INPUT_Name: ${{ inputs.Name }} PSMODULE_TEST_PSMODULE_INPUT_Settings: ${{ inputs.Settings }} - run: | - # Get test paths - ${{ github.action_path }}/src/main.ps1 + run: ${{ github.action_path }}/src/main.ps1 - name: Invoke-Pester uses: PSModule/Invoke-Pester@4ff33199141fdf22568990b6107fe3148ae93a1c # v5.1.0 diff --git a/.github/scripts/site-injectors/nav-state.js b/.github/scripts/site-injectors/nav-state.js new file mode 100644 index 00000000..1150a1da --- /dev/null +++ b/.github/scripts/site-injectors/nav-state.js @@ -0,0 +1,86 @@ +(() => { + const storageKey = "zensical-nav-state-v1"; + let lastSignature = ""; + + const getToggles = () => + Array.from(document.querySelectorAll("input.md-nav__toggle.md-toggle[id]")); + + const getPrimaryList = () => + document.querySelector("nav.md-nav--primary > ul.md-nav__list"); + + const applyDefaultTopLevelState = (toggles) => { + const primaryList = getPrimaryList(); + if (!primaryList) { + return; + } + + const topLevelToggles = Array.from( + primaryList.querySelectorAll( + ":scope > li > input.md-nav__toggle.md-toggle[id]", + ), + ); + const topLevelIds = new Set(topLevelToggles.map((toggle) => toggle.id)); + + for (const toggle of toggles) { + toggle.checked = topLevelIds.has(toggle.id); + } + }; + + const restoreState = (toggles) => { + const raw = localStorage.getItem(storageKey); + if (!raw) { + applyDefaultTopLevelState(toggles); + return; + } + + try { + const state = JSON.parse(raw); + for (const toggle of toggles) { + if (Object.hasOwn(state, toggle.id)) { + toggle.checked = !!state[toggle.id]; + } + } + } catch { + applyDefaultTopLevelState(toggles); + } + }; + + const persistState = (toggles) => { + const state = {}; + for (const toggle of toggles) { + state[toggle.id] = !!toggle.checked; + } + localStorage.setItem(storageKey, JSON.stringify(state)); + }; + + const initialize = () => { + const toggles = getToggles(); + if (toggles.length === 0) { + return; + } + + const signature = toggles.map((toggle) => toggle.id).join("|"); + if (signature === lastSignature) { + return; + } + + lastSignature = signature; + restoreState(toggles); + for (const toggle of toggles) { + if (toggle.dataset.navStateBound === "true") { + continue; + } + + toggle.dataset.navStateBound = "true"; + toggle.addEventListener("change", () => persistState(getToggles())); + } + }; + + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", initialize, { once: true }); + } else { + initialize(); + } + + setInterval(initialize, 500); +})(); diff --git a/.github/workflows/Build-Site.yml b/.github/workflows/Build-Site.yml index d128642e..cbf3b69f 100644 --- a/.github/workflows/Build-Site.yml +++ b/.github/workflows/Build-Site.yml @@ -39,122 +39,25 @@ jobs: name: docs path: ${{ fromJson(inputs.Settings).WorkingDirectory }}/outputs/docs - - name: Install mkdocs-material - shell: pwsh - run: | - pip install mkdocs-material - pip install mkdocs-git-authors-plugin - pip install mkdocs-git-revision-date-localized-plugin - pip install mkdocs-git-committers-plugin-2 + - name: Install Zensical + uses: ./_wf/.github/actions/Install-Zensical - name: Structure site - uses: PSModule/GitHub-Script@8083ec1f733f00357ee4d0db0c6056686e483bc0 # v1.9.0 + uses: ./_wf/.github/actions/Structure-Site with: - Debug: ${{ fromJson(inputs.Settings).Debug }} - Prerelease: ${{ fromJson(inputs.Settings).Prerelease }} - Verbose: ${{ fromJson(inputs.Settings).Verbose }} - Version: ${{ fromJson(inputs.Settings).Version }} WorkingDirectory: ${{ fromJson(inputs.Settings).WorkingDirectory }} - Script: | - LogGroup "Get folder structure" { - $functionDocsFolder = New-Item -Path "outputs/site/docs/Functions" -ItemType Directory -Force - Copy-Item -Path "outputs/docs/*" -Destination "outputs/site/docs/Functions" -Recurse -Force - $moduleName = [string]::IsNullOrEmpty('${{ fromJson(inputs.Settings).Name }}') ? $env:GITHUB_REPOSITORY_NAME : '${{ fromJson(inputs.Settings).Name }}' - $ModuleSourcePath = Resolve-Path 'src' | Select-Object -ExpandProperty Path - $SiteOutputPath = Resolve-Path 'outputs/site' | Select-Object -ExpandProperty Path + Name: ${{ fromJson(inputs.Settings).Name }} - Write-Host "Function Docs Folder: $functionDocsFolder" - Write-Host "Module Name: $moduleName" - Write-Host "Module Source Path: $ModuleSourcePath" - Write-Host "Site Output Path: $SiteOutputPath" - } - - LogGroup "Get folder structure" { - Get-ChildItem -Recurse | Select-Object -ExpandProperty FullName | Sort-Object | Format-List - } - - Get-ChildItem -Path $functionDocsFolder -Recurse -Force -Include '*.md' | ForEach-Object { - $fileName = $_.Name - LogGroup " - $fileName" { - Show-FileContent -Path $_ - } - } - - LogGroup 'Build docs - Process about topics' { - $aboutDocsFolderPath = Join-Path -Path $SiteOutputPath -ChildPath 'docs/About' - $aboutDocsFolder = New-Item -Path $aboutDocsFolderPath -ItemType Directory -Force - $aboutSourceFolder = Get-ChildItem -Path $ModuleSourcePath -Directory | Where-Object { $_.Name -eq 'en-US' } - Get-ChildItem -Path $aboutSourceFolder -Filter *.txt | Copy-Item -Destination $aboutDocsFolder -Force -Verbose -PassThru | - Rename-Item -NewName { $_.Name -replace '.txt', '.md' } - - Write-Host "About Docs Folder: $aboutDocsFolder" - Write-Host "About Source Folder: $aboutSourceFolder" - } - - LogGroup 'Build docs - Copy icon to assets' { - $assetsFolderPath = Join-Path -Path $SiteOutputPath -ChildPath 'docs/Assets' - $assetsFolder = New-Item -Path $assetsFolderPath -ItemType Directory -Force - $rootPath = Split-Path -Path $ModuleSourcePath -Parent - $iconPath = Resolve-Path 'icon\icon.png' | Select-Object -ExpandProperty Path - Copy-Item -Path $iconPath -Destination $assetsFolder -Force -Verbose - - Write-Host "Assets Folder: $assetsFolder" - Write-Host "Icon Path: $iconPath" - } - - LogGroup 'Build docs - Copy readme.md' { - $readmePath = Resolve-Path 'README.md' | Select-Object -ExpandProperty Path - $readmeTargetPath = Join-Path -Path $SiteOutputPath -ChildPath 'docs/README.md' - Copy-Item -Path $readmePath -Destination $readmeTargetPath -Force -Verbose - - Write-Host "Readme Path: $readmePath" - Write-Host "Readme Target Path: $readmeTargetPath" - } - - LogGroup 'Build docs - Create mkdocs.yml' { - $rootPath = Split-Path -Path $ModuleSourcePath -Parent - $possiblePaths = @( - '.github/mkdocs.yml', - 'docs/mkdocs.yml', - 'mkdocs.yml' - ) - - $mkdocsSourcePath = $null - foreach ($path in $possiblePaths) { - $candidatePath = Join-Path -Path $rootPath -ChildPath $path - if (Test-Path -Path $candidatePath) { - $mkdocsSourcePath = $candidatePath - break - } - } - - if (-not $mkdocsSourcePath) { - throw "Mkdocs source file not found in any of the expected locations: $($possiblePaths -join ', ')" - } - - $mkdocsTargetPath = Join-Path -Path $SiteOutputPath -ChildPath 'mkdocs.yml' - - Write-Host "Mkdocs Source Path: $mkdocsSourcePath" - Write-Host "Mkdocs Target Path: $mkdocsTargetPath" - - $mkdocsContent = Get-Content -Path $mkdocsSourcePath -Raw - $mkdocsContent = $mkdocsContent.Replace('-{{ REPO_NAME }}-', $ModuleName) - $mkdocsContent = $mkdocsContent.Replace('-{{ REPO_OWNER }}-', $env:GITHUB_REPOSITORY_OWNER) - $mkdocsContent | Set-Content -Path $mkdocsTargetPath -Force - Show-FileContent -Path $mkdocsTargetPath - } - - - name: Build mkdocs-material project - working-directory: ${{ fromJson(inputs.Settings).WorkingDirectory }}/outputs/site - shell: pwsh - run: | - LogGroup 'Build docs - mkdocs build - content' { - Show-FileContent -Path mkdocs.yml - } + - name: Build documentation site with Zensical + uses: ./_wf/.github/actions/Build-ZensicalSite + with: + WorkingDirectory: ${{ fromJson(inputs.Settings).WorkingDirectory }} - LogGroup 'Build docs - mkdocs build' { - mkdocs build --config-file mkdocs.yml --site-dir ../../_site - } + - name: Inject shared site scripts + uses: ./_wf/.github/actions/Inject-SiteScripts + with: + SitePath: ${{ fromJson(inputs.Settings).WorkingDirectory }}/_site + WorkflowPath: _wf - uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 with: diff --git a/.github/zensical.toml b/.github/zensical.toml new file mode 100644 index 00000000..650af9f7 --- /dev/null +++ b/.github/zensical.toml @@ -0,0 +1,69 @@ +[project] +site_name = "-{{ REPO_NAME }}-" +repo_name = "-{{ REPO_OWNER }}-/-{{ REPO_NAME }}-" +repo_url = "https://github.com/-{{ REPO_OWNER }}-/-{{ REPO_NAME }}-" + +[project.theme] +variant = "classic" +language = "en" +logo = "Assets/icon.png" +favicon = "Assets/icon.png" +features = [ + "navigation.instant", + "navigation.instant.progress", + "navigation.indexes", + "navigation.top", + "navigation.tracking", + "navigation.expand", + "search.suggest", + "search.highlight", + "content.code.copy" +] + +[[project.theme.palette]] +media = "(prefers-color-scheme)" +toggle.icon = "lucide/sun-moon" +toggle.name = "Switch to dark mode" + +[[project.theme.palette]] +media = "(prefers-color-scheme: dark)" +scheme = "slate" +primary = "black" +accent = "green" +toggle.icon = "lucide/moon" +toggle.name = "Switch to light mode" + +[[project.theme.palette]] +media = "(prefers-color-scheme: light)" +scheme = "default" +primary = "indigo" +accent = "green" +toggle.icon = "lucide/sun" +toggle.name = "Switch to system preference" + +[project.theme.icon] +repo = "fontawesome/brands/github" + +[project.markdown_extensions.toc] +permalink = true + +[project.markdown_extensions.attr_list] +[project.markdown_extensions.admonition] +[project.markdown_extensions.md_in_html] +[project.markdown_extensions.pymdownx.details] +[project.markdown_extensions.pymdownx.superfences] + +[[project.extra.social]] +icon = "fontawesome/brands/discord" +link = "https://discord.gg/jedJWCPAhD" +name = "-{{ REPO_OWNER }}- on Discord" + +[[project.extra.social]] +icon = "fontawesome/brands/github" +link = "https://github.com/-{{ REPO_OWNER }}-/" +name = "-{{ REPO_OWNER }}- on GitHub" + +[project.extra.consent] +title = "Cookie consent" +description = "We use cookies to recognize your repeated visits and preferences, as well as to measure the effectiveness of our documentation and whether users find what they're searching for. With your consent, you're helping us to make our documentation better." +actions = ["accept", "reject"] diff --git a/README.md b/README.md index 5e295557..db35db76 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ Process-PSModule is the corner-stone of the PSModule framework — an end-to-end GitHub Actions workflow that builds, tests, versions, documents, and publishes PowerShell modules to the PowerShell Gallery. +Documentation site generation is powered by Zensical. Repositories define site configuration in `zensical.toml`. + ## Documentation The full documentation lives on the MSX / Docs site: diff --git a/tests/srcTestRepo/mkdocs.yml b/tests/srcTestRepo/mkdocs.yml deleted file mode 100644 index df5e17ad..00000000 --- a/tests/srcTestRepo/mkdocs.yml +++ /dev/null @@ -1,75 +0,0 @@ -site_name: -{{ REPO_NAME }}- -theme: - name: material - language: en - font: - text: Roboto - code: Sono - logo: Assets/icon.png - favicon: Assets/icon.png - palette: - # Palette toggle for automatic mode - - media: "(prefers-color-scheme)" - toggle: - icon: material/link - name: Switch to dark mode - # Palette toggle for dark mode - - media: '(prefers-color-scheme: dark)' - scheme: slate - toggle: - primary: black - accent: green - icon: material/toggle-switch-off-outline - name: Switch to light mode - # Palette toggle for light mode - - media: '(prefers-color-scheme: light)' - scheme: default - toggle: - primary: indigo - accent: green - icon: material/toggle-switch - name: Switch to system preference - icon: - repo: material/github - features: - - navigation.instant - - navigation.instant.progress - - navigation.indexes - - navigation.top - - navigation.tracking - - navigation.expand - - search.suggest - - search.highlight - -repo_name: -{{ REPO_OWNER }}-/-{{ REPO_NAME }}- -repo_url: https://github.com/-{{ REPO_OWNER }}-/-{{ REPO_NAME }}- - -plugins: - - search - -markdown_extensions: - - toc: - permalink: true # Adds a link icon to headings - - attr_list - - admonition - - md_in_html - - pymdownx.details # Enables collapsible admonitions - -extra: - social: - - icon: fontawesome/brands/discord - link: https://discord.gg/jedJWCPAhD - name: -{{ REPO_OWNER }}- on Discord - - icon: fontawesome/brands/github - link: https://github.com/-{{ REPO_OWNER }}-/ - name: -{{ REPO_OWNER }}- on GitHub - consent: - title: Cookie consent - description: >- - We use cookies to recognize your repeated visits and preferences, as well - as to measure the effectiveness of our documentation and whether users - find what they're searching for. With your consent, you're helping us to - make our documentation better. - actions: - - accept - - reject diff --git a/tests/srcTestRepo/zensical.toml b/tests/srcTestRepo/zensical.toml new file mode 100644 index 00000000..650af9f7 --- /dev/null +++ b/tests/srcTestRepo/zensical.toml @@ -0,0 +1,69 @@ +[project] +site_name = "-{{ REPO_NAME }}-" +repo_name = "-{{ REPO_OWNER }}-/-{{ REPO_NAME }}-" +repo_url = "https://github.com/-{{ REPO_OWNER }}-/-{{ REPO_NAME }}-" + +[project.theme] +variant = "classic" +language = "en" +logo = "Assets/icon.png" +favicon = "Assets/icon.png" +features = [ + "navigation.instant", + "navigation.instant.progress", + "navigation.indexes", + "navigation.top", + "navigation.tracking", + "navigation.expand", + "search.suggest", + "search.highlight", + "content.code.copy" +] + +[[project.theme.palette]] +media = "(prefers-color-scheme)" +toggle.icon = "lucide/sun-moon" +toggle.name = "Switch to dark mode" + +[[project.theme.palette]] +media = "(prefers-color-scheme: dark)" +scheme = "slate" +primary = "black" +accent = "green" +toggle.icon = "lucide/moon" +toggle.name = "Switch to light mode" + +[[project.theme.palette]] +media = "(prefers-color-scheme: light)" +scheme = "default" +primary = "indigo" +accent = "green" +toggle.icon = "lucide/sun" +toggle.name = "Switch to system preference" + +[project.theme.icon] +repo = "fontawesome/brands/github" + +[project.markdown_extensions.toc] +permalink = true + +[project.markdown_extensions.attr_list] +[project.markdown_extensions.admonition] +[project.markdown_extensions.md_in_html] +[project.markdown_extensions.pymdownx.details] +[project.markdown_extensions.pymdownx.superfences] + +[[project.extra.social]] +icon = "fontawesome/brands/discord" +link = "https://discord.gg/jedJWCPAhD" +name = "-{{ REPO_OWNER }}- on Discord" + +[[project.extra.social]] +icon = "fontawesome/brands/github" +link = "https://github.com/-{{ REPO_OWNER }}-/" +name = "-{{ REPO_OWNER }}- on GitHub" + +[project.extra.consent] +title = "Cookie consent" +description = "We use cookies to recognize your repeated visits and preferences, as well as to measure the effectiveness of our documentation and whether users find what they're searching for. With your consent, you're helping us to make our documentation better." +actions = ["accept", "reject"] diff --git a/tests/srcWithManifestTestRepo/mkdocs.yml b/tests/srcWithManifestTestRepo/mkdocs.yml deleted file mode 100644 index df5e17ad..00000000 --- a/tests/srcWithManifestTestRepo/mkdocs.yml +++ /dev/null @@ -1,75 +0,0 @@ -site_name: -{{ REPO_NAME }}- -theme: - name: material - language: en - font: - text: Roboto - code: Sono - logo: Assets/icon.png - favicon: Assets/icon.png - palette: - # Palette toggle for automatic mode - - media: "(prefers-color-scheme)" - toggle: - icon: material/link - name: Switch to dark mode - # Palette toggle for dark mode - - media: '(prefers-color-scheme: dark)' - scheme: slate - toggle: - primary: black - accent: green - icon: material/toggle-switch-off-outline - name: Switch to light mode - # Palette toggle for light mode - - media: '(prefers-color-scheme: light)' - scheme: default - toggle: - primary: indigo - accent: green - icon: material/toggle-switch - name: Switch to system preference - icon: - repo: material/github - features: - - navigation.instant - - navigation.instant.progress - - navigation.indexes - - navigation.top - - navigation.tracking - - navigation.expand - - search.suggest - - search.highlight - -repo_name: -{{ REPO_OWNER }}-/-{{ REPO_NAME }}- -repo_url: https://github.com/-{{ REPO_OWNER }}-/-{{ REPO_NAME }}- - -plugins: - - search - -markdown_extensions: - - toc: - permalink: true # Adds a link icon to headings - - attr_list - - admonition - - md_in_html - - pymdownx.details # Enables collapsible admonitions - -extra: - social: - - icon: fontawesome/brands/discord - link: https://discord.gg/jedJWCPAhD - name: -{{ REPO_OWNER }}- on Discord - - icon: fontawesome/brands/github - link: https://github.com/-{{ REPO_OWNER }}-/ - name: -{{ REPO_OWNER }}- on GitHub - consent: - title: Cookie consent - description: >- - We use cookies to recognize your repeated visits and preferences, as well - as to measure the effectiveness of our documentation and whether users - find what they're searching for. With your consent, you're helping us to - make our documentation better. - actions: - - accept - - reject diff --git a/tests/srcWithManifestTestRepo/zensical.toml b/tests/srcWithManifestTestRepo/zensical.toml new file mode 100644 index 00000000..650af9f7 --- /dev/null +++ b/tests/srcWithManifestTestRepo/zensical.toml @@ -0,0 +1,69 @@ +[project] +site_name = "-{{ REPO_NAME }}-" +repo_name = "-{{ REPO_OWNER }}-/-{{ REPO_NAME }}-" +repo_url = "https://github.com/-{{ REPO_OWNER }}-/-{{ REPO_NAME }}-" + +[project.theme] +variant = "classic" +language = "en" +logo = "Assets/icon.png" +favicon = "Assets/icon.png" +features = [ + "navigation.instant", + "navigation.instant.progress", + "navigation.indexes", + "navigation.top", + "navigation.tracking", + "navigation.expand", + "search.suggest", + "search.highlight", + "content.code.copy" +] + +[[project.theme.palette]] +media = "(prefers-color-scheme)" +toggle.icon = "lucide/sun-moon" +toggle.name = "Switch to dark mode" + +[[project.theme.palette]] +media = "(prefers-color-scheme: dark)" +scheme = "slate" +primary = "black" +accent = "green" +toggle.icon = "lucide/moon" +toggle.name = "Switch to light mode" + +[[project.theme.palette]] +media = "(prefers-color-scheme: light)" +scheme = "default" +primary = "indigo" +accent = "green" +toggle.icon = "lucide/sun" +toggle.name = "Switch to system preference" + +[project.theme.icon] +repo = "fontawesome/brands/github" + +[project.markdown_extensions.toc] +permalink = true + +[project.markdown_extensions.attr_list] +[project.markdown_extensions.admonition] +[project.markdown_extensions.md_in_html] +[project.markdown_extensions.pymdownx.details] +[project.markdown_extensions.pymdownx.superfences] + +[[project.extra.social]] +icon = "fontawesome/brands/discord" +link = "https://discord.gg/jedJWCPAhD" +name = "-{{ REPO_OWNER }}- on Discord" + +[[project.extra.social]] +icon = "fontawesome/brands/github" +link = "https://github.com/-{{ REPO_OWNER }}-/" +name = "-{{ REPO_OWNER }}- on GitHub" + +[project.extra.consent] +title = "Cookie consent" +description = "We use cookies to recognize your repeated visits and preferences, as well as to measure the effectiveness of our documentation and whether users find what they're searching for. With your consent, you're helping us to make our documentation better." +actions = ["accept", "reject"]