Skip to content

GH Actions/publish-wiki: auto-generate table of contents #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions .github/workflows/publish-wiki.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,31 @@ jobs:
permissions:
# Needed for the commit to the wiki.
contents: write
# Needed for the PR comment.
pull-requests: write

steps:
- name: Checkout code
uses: actions/checkout@v4


# ################################################################################
# Update Wiki files.
# ################################################################################

- name: Install DocToc table of contents generator
run: npm install -g doctoc

- name: Copy wiki files to temporary location
shell: bash
run: cp -v -a wiki _wiki

- name: Update tables of contents
run: doctoc ./_wiki/ --github --maxlevel 4 --update-only

- name: Re-run tables of contents with different settings for specific file
run: doctoc ./_wiki/Version-4.0-User-Upgrade-Guide.md --github --maxlevel 3 --update-only

- name: Preface markdown files with warning not to edit in place
shell: bash
# yamllint disable rule:line-length
Expand All @@ -50,6 +66,43 @@ jobs:
'1i\<!--\nWARNING: DO NOT EDIT THIS FILE IN THE WIKI.\nThis wiki is updated from the https://github.com/PHPCSStandards/PHP_CodeSniffer-documentation repository.\nSubmit a PR to that repository updating the relevant file in the /wiki/ subdirectory instead.\n-->\n' {} \;
# yamllint enable rule:line-length


# ################################################################################
# Dry-run/PRs: upload artifact with pre-processed files and post comment in PR.
# ################################################################################

# Retention is normally 90 days, but this artifact is only to help with reviewing PRs,
# especially when new output blocks are added or the (workflow) code for existing ones
# is updated. All in all, no need to keep the artifact for more than a few days.
- name: "[PR only] Upload the preprocessed wiki files as an artifact"
if: ${{ github.event_name == 'pull_request' }}
id: artifact
uses: actions/upload-artifact@v4
with:
name: wiki-files
path: ./_wiki
if-no-files-found: error
retention-days: 10

- name: "[PR only] Post comment to review artifact"
if: ${{ github.event_name == 'pull_request' }}
uses: mshick/add-pr-comment@v2
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
message: |
Thank you for your PR.
A dry-run has been executed on your PR, executing all markdown pre-processing for the wiki files.

Please review the resulting final markdown files via the [created artifact](${{ steps.artifact.outputs.artifact-url }}).
This is especially important when adding new pages.

_N.B.: the above link will automatically be updated when this PR is updated._


# ################################################################################
# Deploy to the wiki in the PHPCS repo.
# ################################################################################

- name: Check GitHub Git Operations status
uses: crazy-max/ghaction-github-status@v4
with:
Expand Down
12 changes: 2 additions & 10 deletions wiki/About-Standards-for-PHP_CodeSniffer.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
## Table of contents

* [A Project ruleset or a standard ?](#a-project-ruleset-or-a-standard-)
* [How does PHP_CodeSniffer determine which standard or ruleset to apply ?](#how-does-php_codesniffer-determine-which-standard-or-ruleset-to-apply-)
* [About standards](#about-standards)
* [Creating an external standard for PHP_CodeSniffer](#creating-an-external-standard-for-php_codesniffer)
* [Creating new rules](#creating-new-rules)
* [Naming conventions](#naming-conventions)
* [1. Directory structure](#1-directory-structure)
* [2. Sniff file name](#2-sniff-file-name)
* [3. Namespace and class name](#3-namespace-and-class-name)
* [Examples](#examples)
<!-- START doctoc -->
<!-- END doctoc -->

***

Expand Down
21 changes: 2 additions & 19 deletions wiki/Advanced-Usage.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,7 @@
## Table of contents

* [Specifying Valid File Extensions](#specifying-valid-file-extensions)
* [Ignoring Files and Folders](#ignoring-files-and-folders)
* [Ignoring Parts of a File](#ignoring-parts-of-a-file)
* [Limiting Results to Specific Sniffs](#limiting-results-to-specific-sniffs)
* [Filtering Errors and Warnings Based on Severity](#filtering-errors-and-warnings-based-on-severity)
* [Replacing Tabs with Spaces](#replacing-tabs-with-spaces)
* [Specifying an Encoding](#specifying-an-encoding)
* [Using a Bootstrap File](#using-a-bootstrap-file)
* [Using a Default Configuration File](#using-a-default-configuration-file)
* [Specifying php.ini Settings](#specifying-phpini-settings)
* [Setting Configuration Options](#setting-configuration-options)
* [Deleting Configuration Options](#deleting-configuration-options)
* [Viewing Configuration Options](#viewing-configuration-options)
* [Printing Verbose Tokeniser Output](#printing-verbose-tokeniser-output)
* [The Scope Map](#the-scope-map)
* [The Level Map](#the-level-map)
* [Printing Verbose Token Processing Output](#printing-verbose-token-processing-output)
* [Quieting Output](#quieting-output)
* [Understanding the Exit Codes](#understanding-the-exit-codes)
<!-- START doctoc -->
<!-- END doctoc -->

***

Expand Down
26 changes: 26 additions & 0 deletions wiki/Coding-Standard-Tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@ In this tutorial, we will create a new coding standard with a single sniff. Our

Sniffs need to follow [strict directory layout and naming conventions](https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki/About-Standards-for-PHP_CodeSniffer#naming-conventions).

## Table of contents

<!-- START doctoc -->
<!-- END doctoc -->

***

## Creating the Coding Standard Directory

All sniffs in PHP_CodeSniffer must belong to a coding standard. A coding standard is a directory with a specific sub-directory structure and a `ruleset.xml` file, so creating a standard is straight-forward.
Expand Down Expand Up @@ -39,6 +46,9 @@ The content of the `ruleset.xml` file should, at a minimum, be the following:
> [!NOTE]
> The ruleset.xml can be left quite small, as it is in this example coding standard. For information about the other features that the `ruleset.xml` provides, see the [[Annotated ruleset]].

<p align="right"><a href="#table-of-contents">back to top</a></p>


## Creating the Sniff

A sniff requires a single PHP file that must be placed into a sub-directory to categorise the type of check it performs. Its name should clearly describe the standard that we are enforcing and must end with `Sniff.php`. For our sniff, we will name the PHP file `DisallowHashCommentsSniff.php` and place it into a `Commenting` sub-directory to categorise this sniff as relating to commenting. Run the following commands to create the category and the sniff:
Expand All @@ -54,24 +64,36 @@ $ touch Commenting/DisallowHashCommentsSniff.php

Each sniff must implement the `PHP_CodeSniffer\Sniffs\Sniff` interface so that PHP_CodeSniffer knows that it should instantiate the sniff once it's invoked. The interface defines two methods that must be implemented; `register` and `process`.

<p align="right"><a href="#table-of-contents">back to top</a></p>


## The `register` and `process` Methods

The `register` method allows a sniff to subscribe to one or more token types that it wants to process. Once PHP_CodeSniffer encounters one of those tokens, it calls the `process` method with the `PHP_CodeSniffer\Files\File` object (a representation of the current file being checked) and the position in the stack where the token was found.

For our sniff, we are interested in single line comments. The `token_get_all` method that PHP_CodeSniffer uses to acquire the tokens within a file distinguishes doc comments and normal comments as two separate token types. Therefore, we don't have to worry about doc comments interfering with our test. The `register` method only needs to return one token type, `T_COMMENT`.

<p align="right"><a href="#table-of-contents">back to top</a></p>


## The Token Stack

A sniff can gather more information about a token by acquiring the token stack with a call to the `getTokens` method on the `PHP_CodeSniffer\Files\File` object. This method returns an array and is indexed by the position where the token occurs in the token stack. Each element in the array represents a token. All tokens have a `code`, `type` and a `content` index in their array. The `code` value is a unique integer for the type of token. The `type` value is a string representation of the token (e.g., `'T_COMMENT'` for comment tokens). The `type` has a corresponding globally defined integer with the same name. Finally, the `content` value contains the content of the token as it appears in the code.

> [!NOTE]
> Depending on the token, the token array may contain various additional indexes with further information on a token.

<p align="right"><a href="#table-of-contents">back to top</a></p>


## Reporting Errors

Once an error is detected, a sniff should indicate that an error has occurred by calling the `addError` method on the `PHP_CodeSniffer\Files\File` object, passing in an appropriate error message as the first argument, the position in the stack where the error was detected as the second, a code to uniquely identify the error within this sniff and an array of data used inside the error message.
Alternatively, if the violation is considered not as critical as an error, the `addWarning` method can be used.

<p align="right"><a href="#table-of-contents">back to top</a></p>


## DisallowHashCommentsSniff.php

We now have to write the content of our sniff. The content of the `DisallowHashCommentsSniff.php` file should be the following:
Expand Down Expand Up @@ -135,6 +157,8 @@ public $supportedTokenizers = [
];
```

<p align="right"><a href="#table-of-contents">back to top</a></p>


## Results

Expand Down Expand Up @@ -173,3 +197,5 @@ FOUND 3 ERROR(S) AFFECTING 3 LINE(S)
13 | ERROR | Hash comments are prohibited; found # Error.
--------------------------------------------------------------------------------
```

<p align="right"><a href="#table-of-contents">back to top</a></p>
24 changes: 2 additions & 22 deletions wiki/Configuration-Options.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,7 @@
## Table of contents

* [Setting the default coding standard](#setting-the-default-coding-standard)
* [Setting the default report format](#setting-the-default-report-format)
* [Hiding warnings by default](#hiding-warnings-by-default)
* [Showing progress by default](#showing-progress-by-default)
* [Using colors in output by default](#using-colors-in-output-by-default)
* [Changing the default severity levels](#changing-the-default-severity-levels)
* [Setting the default report width](#setting-the-default-report-width)
* [Setting the default encoding](#setting-the-default-encoding)
* [Setting the default tab width](#setting-the-default-tab-width)
* [Setting the installed standard paths](#setting-the-installed-standard-paths)
* [Setting the PHP version](#setting-the-php-version)
* [Ignoring errors when generating the exit code](#ignoring-errors-when-generating-the-exit-code)
* [Ignoring warnings when generating the exit code](#ignoring-warnings-when-generating-the-exit-code)
* [Ignoring non-auto-fixable issues when generating the exit code (PHP_CodeSniffer >= 4.0.0)](#ignoring-non-auto-fixable-issues-when-generating-the-exit-code-php_codesniffer--400)
* Setting tool paths
* [CSSLint](#setting-the-path-to-csslint)
* [Google Closure Linter](#setting-the-path-to-the-google-closure-linter)
* [PHP](#setting-the-path-to-php)
* [JSHint](#setting-the-path-to-jshint)
* [JSLint](#setting-the-path-to-jslint)
* [JavaScript Lint](#setting-the-path-to-javascript-lint)
* [Zend Code Analyzer](#setting-the-path-to-the-zend-code-analyzer)
<!-- START doctoc -->
<!-- END doctoc -->

***

Expand Down
66 changes: 2 additions & 64 deletions wiki/Customisable-Sniff-Properties.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,70 +4,8 @@ For more information about changing sniff behaviour by customising your ruleset,

## Table of contents

* [Generic Sniffs](#generic-sniffs)
* [Generic.Arrays.ArrayIndent](#genericarraysarrayindent)
* [Generic.CodeAnalysis.UnusedFunctionParameter](#genericcodeanalysisunusedfunctionparameter)
* [Generic.ControlStructures.InlineControlStructure](#genericcontrolstructuresinlinecontrolstructure)
* [Generic.Debug.ClosureLinter](#genericdebugclosurelinter)
* [Generic.Debug.ESLint](#genericdebugeslint)
* [Generic.Files.LineEndings](#genericfileslineendings)
* [Generic.Files.LineLength](#genericfileslinelength)
* [Generic.Formatting.MultipleStatementAlignment](#genericformattingmultiplestatementalignment)
* [Generic.Formatting.SpaceAfterCast](#genericformattingspaceaftercast)
* [Generic.Formatting.SpaceAfterNot](#genericformattingspaceafternot)
* [Generic.Functions.OpeningFunctionBraceBsdAllman](#genericfunctionsopeningfunctionbracebsdallman)
* [Generic.Functions.OpeningFunctionBraceKernighanRitchie](#genericfunctionsopeningfunctionbracekernighanritchie)
* [Generic.Metrics.CyclomaticComplexity](#genericmetricscyclomaticcomplexity)
* [Generic.Metrics.NestingLevel](#genericmetricsnestinglevel)
* [Generic.NamingConventions.CamelCapsFunctionName](#genericnamingconventionscamelcapsfunctionname)
* [Generic.PHP.ForbiddenFunctions](#genericphpforbiddenfunctions)
* [Generic.PHP.NoSilencedErrors](#genericphpnosilencederrors)
* [Generic.Strings.UnnecessaryStringConcat](#genericstringsunnecessarystringconcat)
* [Generic.WhiteSpace.ArbitraryParenthesesSpacing](#genericwhitespacearbitraryparenthesesspacing)
* [Generic.WhiteSpace.ScopeIndent](#genericwhitespacescopeindent)
* [Generic.WhiteSpace.SpreadOperatorSpacingAfter](#genericwhitespacespreadoperatorspacingafter)
* [PEAR Sniffs](#pear-sniffs)
* [PEAR.Commenting.FunctionComment](#pearcommentingfunctioncomment)
* [PEAR.ControlStructures.ControlSignature](#pearcontrolstructurescontrolsignature)
* [PEAR.ControlStructures.MultiLineCondition](#pearcontrolstructuresmultilinecondition)
* [PEAR.Formatting.MultiLineAssignment](#pearformattingmultilineassignment)
* [PEAR.Functions.FunctionCallSignature](#pearfunctionsfunctioncallsignature)
* [PEAR.Functions.FunctionDeclaration](#pearfunctionsfunctiondeclaration)
* [PEAR.WhiteSpace.ObjectOperatorIndent](#pearwhitespaceobjectoperatorindent)
* [PEAR.WhiteSpace.ScopeClosingBrace](#pearwhitespacescopeclosingbrace)
* [PEAR.WhiteSpace.ScopeIndent](#pearwhitespacescopeindent)
* [PSR2 Sniffs](#psr2-sniffs)
* [PSR2.Classes.ClassDeclaration](#psr2classesclassdeclaration)
* [PSR2.ControlStructures.ControlStructureSpacing](#psr2controlstructurescontrolstructurespacing)
* [PSR2.ControlStructures.SwitchDeclaration](#psr2controlstructuresswitchdeclaration)
* [PSR2.Methods.FunctionCallSignature](#psr2methodsfunctioncallsignature)
* [PSR12 Sniffs](#psr12-sniffs)
* [PSR12.Classes.AnonClassDeclaration](#psr12classesanonclassdeclaration)
* [PSR12.ControlStructures.BooleanOperatorPlacement](#psr12controlstructuresbooleanoperatorplacement)
* [PSR12.ControlStructures.ControlStructureSpacing](#psr12controlstructurescontrolstructurespacing)
* [PSR12.Namespaces.CompoundNamespaceDepth](#psr12namespacescompoundnamespacedepth)
* [PSR12.Operators.OperatorSpacing](#psr12operatorsoperatorspacing)
* [Squiz Sniffs](#squiz-sniffs)
* [Squiz.Classes.ClassDeclaration](#squizclassesclassdeclaration)
* [Squiz.Commenting.FunctionComment](#squizcommentingfunctioncomment)
* [Squiz.Commenting.LongConditionClosingComment](#squizcommentinglongconditionclosingcomment)
* [Squiz.ControlStructures.ControlSignature](#squizcontrolstructurescontrolsignature)
* [Squiz.ControlStructures.ForEachLoopDeclaration](#squizcontrolstructuresforeachloopdeclaration)
* [Squiz.ControlStructures.ForLoopDeclaration](#squizcontrolstructuresforloopdeclaration)
* [Squiz.ControlStructures.SwitchDeclaration](#squizcontrolstructuresswitchdeclaration)
* [Squiz.CSS.ForbiddenStyles](#squizcssforbiddenstyles)
* [Squiz.CSS.Indentation](#squizcssindentation)
* [Squiz.Functions.FunctionDeclaration](#squizfunctionsfunctiondeclaration)
* [Squiz.Functions.FunctionDeclarationArgumentSpacing](#squizfunctionsfunctiondeclarationargumentspacing)
* [Squiz.PHP.CommentedOutCode](#squizphpcommentedoutcode)
* [Squiz.PHP.DiscouragedFunctions](#squizphpdiscouragedfunctions)
* [Squiz.PHP.ForbiddenFunctions](#squizphpforbiddenfunctions)
* [Squiz.Strings.ConcatenationSpacing](#squizstringsconcatenationspacing)
* [Squiz.WhiteSpace.FunctionSpacing](#squizwhitespacefunctionspacing)
* [Squiz.WhiteSpace.MemberVarSpacing](#squizwhitespacemembervarspacing)
* [Squiz.WhiteSpace.ObjectOperatorSpacing](#squizwhitespaceobjectoperatorspacing)
* [Squiz.WhiteSpace.OperatorSpacing](#squizwhitespaceoperatorspacing)
* [Squiz.WhiteSpace.SuperfluousWhitespace](#squizwhitespacesuperfluouswhitespace)
<!-- START doctoc -->
<!-- END doctoc -->

***

Expand Down
8 changes: 2 additions & 6 deletions wiki/FAQ.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
## Table of contents

* [Does PHP_CodeSniffer perform any code coverage or unit testing?](#does-php_codesniffer-perform-any-code-coverage-or-unit-testing)
* [My code is fine! Why do I need PHP_CodeSniffer?](#my-code-is-fine-why-do-i-need-php_codesniffer)
* [Does PHP_CodeSniffer parse my code to ensure it will execute?](#does-php_codesniffer-parse-my-code-to-ensure-it-will-execute)
* [I don't agree with your coding standards! Can I make PHP_CodeSniffer enforce my own?](#i-dont-agree-with-your-coding-standards-can-i-make-php_codesniffer-enforce-my-own)
* [How come PHP_CodeSniffer reported errors, I fixed them, now I get even more?](#how-come-php_codesniffer-reported-errors-i-fixed-them-now-i-get-even-more)
* [What does PHP_CodeSniffer use to tokenize my code?](#what-does-php_codesniffer-use-to-tokenize-my-code)
<!-- START doctoc -->
<!-- END doctoc -->

***

Expand Down
5 changes: 2 additions & 3 deletions wiki/Fixing-Errors-Automatically.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
## Table of contents

* [About Automatic Fixing](#about-automatic-fixing)
* [Using the PHP Code Beautifier and Fixer](#using-the-php-code-beautifier-and-fixer)
* [Viewing Debug Information](#viewing-debug-information)
<!-- START doctoc -->
<!-- END doctoc -->

***

Expand Down
9 changes: 2 additions & 7 deletions wiki/Usage.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
## Table of contents

* [Getting Help from the Command Line](#getting-help-from-the-command-line)
* [Checking Files and Folders](#checking-files-and-folders)
* [Printing a Summary Report](#printing-a-summary-report)
* [Printing Progress Information](#printing-progress-information)
* [Specifying a Coding Standard](#specifying-a-coding-standard)
* [Printing a List of Installed Coding Standards](#printing-a-list-of-installed-coding-standards)
* [Listing Sniffs Inside a Coding Standard](#listing-sniffs-inside-a-coding-standard)
<!-- START doctoc -->
<!-- END doctoc -->

***

Expand Down
16 changes: 2 additions & 14 deletions wiki/Version-3.0-Upgrade-Guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,8 @@ PHP_CodeSniffer version 3 contains a large number of core changes and breaks bac

## Table of contents

* [Upgrading Custom Sniffs](#upgrading-custom-sniffs)
* [Extending Other Sniffs](#extending-other-sniffs)
* [Extending the Included Abstract Sniffs](#extending-the-included-abstract-sniffs)
* [AbstractVariableSniff](#abstractvariablesniff)
* [AbstractPatternSniff](#abstractpatternsniff)
* [AbstractScopeSniff](#abstractscopesniff)
* [New Class Names](#new-class-names)
* [PHP_CodeSniffer_File](#php_codesniffer_file)
* [PHP_CodeSniffer_Tokens](#php_codesniffer_tokens)
* [PHP_CodeSniffer](#php_codesniffer)
* [Upgrading Unit Tests](#upgrading-unit-tests)
* [Setting CLI Values](#setting-cli-values)
* [Upgrading Custom Reports](#upgrading-custom-reports)
* [Supporting Concurrency](#supporting-concurrency)
<!-- START doctoc -->
<!-- END doctoc -->

***

Expand Down
Loading