Skip to content

Commit de3691d

Browse files
authored
Fix markdown indentation issues and add detection scripts (#16429)
* Fix indentation issues in markdown files and add scripts for detection and correction * Add guidelines for checking indentation and clarify style guide scope
1 parent 8d20218 commit de3691d

File tree

10 files changed

+442
-21
lines changed

10 files changed

+442
-21
lines changed

.claude/commands/docs-review.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ Always provide relevant line numbers for any issues you identify.
9090
- Confirm that **all links resolve** and point to the correct targets (no 404s, no mislinked paths).
9191
- Validate that **content is accurate and current** (commands, APIs, terminology).
9292
- Ensure **all new files end with a newline**.
93+
- Double-check indented lines to ensure they are not incorrectly indented as code blocks.
9394
- **Code examples** must run correctly and follow best practices:
9495
- Do not suggest untested code.
9596
- Examples should show realistic use cases, not contrived demos.

STYLE-GUIDE.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,17 @@ For topics not addressed here, refer to the [Google Developer Documentation Styl
55

66
---
77

8+
## Scope
9+
10+
This style guide applies to all Hugo content files in this repository.
11+
12+
The following exceptions are specifically excluded from this style guide:
13+
14+
- Non-content files (scripts, configuration, etc.) should follow general best practices for that file type.
15+
- Meta Markdown files (e.g., `README.md`, `AGENTS.md`) may use different conventions as appropriate.
16+
17+
---
18+
819
## Inclusive Language
920

1021
Pulumi strives to use language that is clear, inclusive, and respectful.

content/docs/iac/get-started/aws/next-steps.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ aliases:
1919

2020
Congratulations! You've successfully provisioned some cloud resources using Pulumi. By completing this guide you have successfully:
2121

22-
- Created a Pulumi new project.
23-
- Provisioned a new S3 bucket.
24-
- Turned it into a static website.
25-
- Created a website component for easy reuse.
26-
- Destroyed all of the resources you've provisioned.
22+
- Created a Pulumi new project.
23+
- Provisioned a new S3 bucket.
24+
- Turned it into a static website.
25+
- Created a website component for easy reuse.
26+
- Destroyed all of the resources you've provisioned.
2727

2828
Below are some recommended next steps, including examples and tutorials that you can explore or use them as a foundation for your own applications and infrastructure projects. Also be sure to [join the Community Slack](https://slack.pulumi.com/) to meet fellow IaC practitioners.
2929

content/docs/iac/get-started/azure/destroy-stack.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,11 @@ entirely from Pulumi Cloud, along with all of its update history.
6767

6868
Congratulations! You've successfully provisioned some cloud resources using Pulumi. By completing this guide you have successfully:
6969

70-
- Created a Pulumi new project.
71-
- Provisioned a new Azure storage account and container.
72-
- Added an `index.html` file to your container.
73-
- Served the `index.html` as a static website.
74-
- Destroyed the resources you've provisioned.
70+
- Created a Pulumi new project.
71+
- Provisioned a new Azure storage account and container.
72+
- Added an `index.html` file to your container.
73+
- Served the `index.html` as a static website.
74+
- Destroyed the resources you've provisioned.
7575

7676
On the next page, we have a collection of examples and tutorials that you can deploy as they are or use them as a foundation for your own applications and infrastructure projects.
7777

content/docs/iac/get-started/azure/next-steps.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ Congrats! You've deployed your first project on Microsoft Azure with Pulumi. Her
2424

2525
With Pulumi ESC you can:
2626

27-
- **Stop secret sprawl.** Pull and sync configuration and secrets with any secrets store – including HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, GCP Secret Manager, 1Password, and more – and consume in any application, tool, or CI/CD platform.
28-
- **Trust (and prove) your secrets are secure.** Every environment can be locked down with role-based access controls (RBAC) and versioned with all changes fully logged for auditing.
29-
- **Ditch `.env` files.** No more storing secrets in plaintext on dev computers. Developers can easily access secrets via CLI, API, Kubernetes operator, the Pulumi Cloud UI, and in-code with Typescript/Javascript, Python, and Go SDKs.
27+
- **Stop secret sprawl.** Pull and sync configuration and secrets with any secrets store – including HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, GCP Secret Manager, 1Password, and more – and consume in any application, tool, or CI/CD platform.
28+
- **Trust (and prove) your secrets are secure.** Every environment can be locked down with role-based access controls (RBAC) and versioned with all changes fully logged for auditing.
29+
- **Ditch `.env` files.** No more storing secrets in plaintext on dev computers. Developers can easily access secrets via CLI, API, Kubernetes operator, the Pulumi Cloud UI, and in-code with Typescript/Javascript, Python, and Go SDKs.
3030

3131
{{< get-started-next-step path="/docs/esc/get-started/" label="Learn more about Pulumi ESC" ref="gs-azure-esc" >}}
3232

content/docs/iac/get-started/gcp/destroy-stack.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,11 @@ Optionally, to delete the stack itself, you can also run [`pulumi stack rm`](/do
6565

6666
Congratulations! You've successfully provisioned some cloud resources using Pulumi. By completing this guide you have successfully:
6767

68-
- Created a Pulumi new project.
69-
- Provisioned a new storage bucket.
70-
- Added an `index.html` file to your bucket.
71-
- Served the file as a static website.
72-
- Destroyed the resources you've provisioned.
68+
- Created a Pulumi new project.
69+
- Provisioned a new storage bucket.
70+
- Added an `index.html` file to your bucket.
71+
- Served the file as a static website.
72+
- Destroyed the resources you've provisioned.
7373

7474
On the next page, we have a collection of examples and tutorials that you can deploy as they are or use them as a foundation for your own applications and infrastructure projects.
7575

content/docs/iac/get-started/gcp/next-steps.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ Congrats! You've deployed your first project on Google Cloud with Pulumi. Here a
2525

2626
With Pulumi ESC you can:
2727

28-
- **Stop secret sprawl.** Pull and sync configuration and secrets with any secrets store – including HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, GCP Secret Manager, 1Password, and more – and consume in any application, tool, or CI/CD platform.
29-
- **Trust (and prove) your secrets are secure.** Every environment can be locked down with role-based access controls (RBAC) and versioned with all changes fully logged for auditing.
30-
- **Ditch `.env` files.** No more storing secrets in plaintext on dev computers. Developers can easily access secrets via CLI, API, Kubernetes operator, the Pulumi Cloud UI, and in-code with Typescript/Javascript, Python, and Go SDKs.
28+
- **Stop secret sprawl.** Pull and sync configuration and secrets with any secrets store – including HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, GCP Secret Manager, 1Password, and more – and consume in any application, tool, or CI/CD platform.
29+
- **Trust (and prove) your secrets are secure.** Every environment can be locked down with role-based access controls (RBAC) and versioned with all changes fully logged for auditing.
30+
- **Ditch `.env` files.** No more storing secrets in plaintext on dev computers. Developers can easily access secrets via CLI, API, Kubernetes operator, the Pulumi Cloud UI, and in-code with Typescript/Javascript, Python, and Go SDKs.
3131

3232
{{< get-started-next-step path="/docs/esc/get-started" label="Learn more about Pulumi ESC" ref="gs-gcp-esc" >}}
3333

scripts/indent-fixes/README.md

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
# Indent Fixes Scripts
2+
3+
These scripts detect and fix incorrectly indented bullet lists in markdown files. This issue occurred during the content reorganization (PRs #16119, #16303) where bullet lists were inadvertently indented with 4 spaces, causing Hugo to render them as code blocks instead of proper lists.
4+
5+
## The Problem
6+
7+
In markdown, 4 spaces of indentation before a bullet point creates a code block instead of a list item:
8+
9+
```markdown
10+
<!-- WRONG: Renders as code block -->
11+
- This is a bullet point
12+
- Another bullet point
13+
14+
<!-- CORRECT: Renders as list -->
15+
- This is a bullet point
16+
- Another bullet point
17+
```
18+
19+
During the content reorganization, some bullet lists were accidentally indented with 4 spaces, breaking their rendering on the website.
20+
21+
## Usage
22+
23+
### Quick Start
24+
25+
From the repository root:
26+
27+
```bash
28+
cd scripts/indent-fixes
29+
30+
# Step 1: Detect issues
31+
python3 detect_indent_issues.py
32+
33+
# Step 2: Review the report, then fix all issues
34+
python3 fix_indent_issues.py
35+
36+
# Step 3: Verify the changes
37+
git diff content/docs/
38+
```
39+
40+
### Step 1: Detection
41+
42+
Run the detection script to find all problematic indentations:
43+
44+
```bash
45+
python3 detect_indent_issues.py
46+
```
47+
48+
This will output:
49+
- Summary count of files with issues
50+
- Line-by-line listing of each problematic indentation
51+
- Total count of issues found
52+
53+
**Example output:**
54+
```
55+
Found 14 files with potential indentation issues:
56+
57+
content/docs/iac/get-started/aws/next-steps.md: 5 issue(s)
58+
Line 22: - Created a Pulumi new project.
59+
Line 23: - Provisioned a new S3 bucket.
60+
Line 24: - Turned it into a static website.
61+
Line 25: - Created a website component for easy reuse.
62+
Line 26: - Destroyed all of the resources you've provisioned.
63+
64+
Total: 66 potential issues across 14 files
65+
```
66+
67+
### Step 2: Fix Issues
68+
69+
After reviewing the detection report, run the fix script:
70+
71+
```bash
72+
python3 fix_indent_issues.py
73+
```
74+
75+
This will:
76+
- Process all markdown files in `content/docs/`
77+
- Remove 4-space indentation from incorrectly indented bullet points
78+
- Report the number of lines fixed per file
79+
80+
**Example output:**
81+
```
82+
Fixed 66 lines across 14 files:
83+
84+
content/docs/iac/get-started/aws/next-steps.md: 5 line(s) fixed
85+
content/docs/iac/get-started/azure/destroy-stack.md: 5 line(s) fixed
86+
content/docs/iac/get-started/azure/next-steps.md: 3 line(s) fixed
87+
...
88+
```
89+
90+
### Step 3: Verify Changes
91+
92+
Review the changes made by the script:
93+
94+
```bash
95+
# View summary of changes
96+
git diff --stat content/docs/
97+
98+
# View detailed changes
99+
git diff content/docs/
100+
101+
# Test the build
102+
make build
103+
```
104+
105+
## How It Works
106+
107+
### Detection Logic
108+
109+
The `detect_indent_issues.py` script intelligently identifies problematic indentations while avoiding false positives:
110+
111+
**What it detects:**
112+
- Lines matching the pattern `^ - ` (4 spaces + dash + space)
113+
- In markdown content sections (not frontmatter or code blocks)
114+
115+
**What it excludes:**
116+
- **YAML frontmatter**: Indentation between `---` markers is correct YAML syntax
117+
- **Code blocks**: Content within ` ``` ` fences is left untouched
118+
- **Nested lists**: Legitimate 2nd-level list items (preceded by 2-space indented parent)
119+
- **YAML-like structures**: Content that looks like YAML configuration blocks
120+
121+
### Fix Logic
122+
123+
The `fix_indent_issues.py` script:
124+
125+
1. Uses the same detection logic to identify problematic lines
126+
2. Removes exactly 4 spaces from the beginning of each line
127+
3. Writes the corrected content back to the file
128+
4. Reports the number of changes made
129+
130+
**Safety features:**
131+
- Only modifies lines that match the detection criteria
132+
- Preserves all other formatting (newlines, trailing spaces, etc.)
133+
- Non-destructive: Can be reviewed with `git diff` before committing
134+
135+
## When to Use These Scripts
136+
137+
- **After content reorganizations**: When files are moved/renamed, indentation issues may be introduced
138+
- **When rendering issues occur**: If bullet lists appear as code blocks on the site
139+
- **Periodic audits**: Run detection periodically to catch any new issues
140+
141+
## Workflow
142+
143+
1. Make content changes or complete a reorganization
144+
2. Run `python3 detect_indent_issues.py` to check for issues
145+
3. Review the detection report
146+
4. Run `python3 fix_indent_issues.py` to apply fixes
147+
5. **IMPORTANT** -- Review changes with `git diff`! There *will* be false positives!
148+
6. Run `make build` to verify the site builds correctly
149+
7. Commit the fixes
150+
151+
## Exit Codes
152+
153+
Both scripts return:
154+
- **0** - Success (issues found and reported, or no issues found)
155+
- **Non-zero** - Unexpected error occurred
156+
157+
## Related
158+
159+
- See `scripts/alias-verification/` for tools to verify file move aliases
160+
- See `STYLE-GUIDE.md` for markdown formatting guidelines
161+
162+
## History
163+
164+
These scripts were created to fix issues introduced during:
165+
- PR #16119: Major documentation reorganization
166+
- PR #16303: Insights & Governance docs reorganization
167+
168+
The fixes were partially addressed in:
169+
- PR #16427: Fixed get-started guides
170+
- PR #16428: Fixed next-steps pages
171+
172+
This toolset completes the remediation and provides ongoing verification.
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Detect incorrectly indented bullet points in markdown files.
4+
This script finds bullet lists with 4-space indentation that should be unindented.
5+
It distinguishes between YAML frontmatter (where indentation is correct) and
6+
markdown content (where 4-space indentation creates code blocks).
7+
"""
8+
9+
import re
10+
from pathlib import Path
11+
from typing import List, Tuple
12+
13+
def detect_indent_issues(file_path: str) -> List[Tuple[int, str]]:
14+
"""
15+
Detect lines with problematic 4-space indentation before bullet points.
16+
Returns a list of (line_number, line_content) tuples.
17+
"""
18+
issues = []
19+
20+
with open(file_path, 'r', encoding='utf-8') as f:
21+
lines = f.readlines()
22+
23+
in_frontmatter = False
24+
frontmatter_count = 0
25+
in_code_block = False
26+
27+
for i, line in enumerate(lines, 1):
28+
# Track frontmatter boundaries (YAML between --- markers)
29+
if line.strip() == '---':
30+
frontmatter_count += 1
31+
if frontmatter_count == 1:
32+
in_frontmatter = True
33+
elif frontmatter_count == 2:
34+
in_frontmatter = False
35+
continue
36+
37+
# Track code blocks (```)
38+
if line.strip().startswith('```'):
39+
in_code_block = not in_code_block
40+
continue
41+
42+
# Skip if we're in frontmatter or code block
43+
if in_frontmatter or in_code_block:
44+
continue
45+
46+
# Check for 4-space indented bullet points
47+
# Pattern: exactly 4 spaces, then dash, then space or content
48+
if re.match(r'^ - ', line):
49+
# Check if this might be a legitimate nested list item
50+
# Look at previous lines to see if there's a parent list item
51+
is_nested = False
52+
if i > 1:
53+
# Check previous non-empty lines
54+
for j in range(i-2, max(0, i-10), -1):
55+
prev_line = lines[j].rstrip()
56+
if not prev_line:
57+
continue
58+
# If previous line is a list item without indent, this might be nested
59+
if re.match(r'^ - ', prev_line):
60+
is_nested = True
61+
break
62+
# If we hit another non-list line, assume not nested
63+
if prev_line and not prev_line.startswith(' '):
64+
break
65+
66+
# Also check for YAML-like context (key: value patterns nearby)
67+
is_yaml_context = False
68+
if i > 1 and i < len(lines):
69+
# Check surrounding lines for YAML patterns
70+
for j in range(max(0, i-5), min(len(lines), i+5)):
71+
if re.search(r'^\w+:', lines[j]):
72+
# Could be YAML or markdown heading
73+
# If it's followed by indented content, likely YAML
74+
if j < len(lines) - 1 and lines[j+1].startswith(' '):
75+
is_yaml_context = True
76+
break
77+
78+
if not is_nested and not is_yaml_context:
79+
issues.append((i, line.rstrip()))
80+
81+
return issues
82+
83+
def main():
84+
# Search in content/docs directory (relative to repo root)
85+
# Script can be run from repo root or from scripts/indent-fixes/
86+
repo_root = Path(__file__).parent.parent.parent
87+
content_dir = repo_root / 'content' / 'docs'
88+
89+
all_issues = {}
90+
91+
for md_file in content_dir.rglob('*.md'):
92+
issues = detect_indent_issues(str(md_file))
93+
if issues:
94+
all_issues[str(md_file)] = issues
95+
96+
# Print results
97+
if all_issues:
98+
print(f"Found {len(all_issues)} files with potential indentation issues:\n")
99+
total_issues = 0
100+
for file_path in sorted(all_issues.keys()):
101+
issues = all_issues[file_path]
102+
total_issues += len(issues)
103+
print(f"\n{file_path}: {len(issues)} issue(s)")
104+
for line_num, line_content in issues:
105+
print(f" Line {line_num}: {line_content}")
106+
107+
print(f"\n\nTotal: {total_issues} potential issues across {len(all_issues)} files")
108+
else:
109+
print("No indentation issues found.")
110+
111+
if __name__ == '__main__':
112+
main()

0 commit comments

Comments
 (0)