Implement automated spell checking and content validation workflows to maintain professional content standards across all public-facing materials while supporting financial and investment terminology.
# dictionaries/investment-vocabulary.txt
equities
fixed-income
alternatives
commodities
REITs
MLPs
ETFs
ETPs
mutual
funds
index
active
passive
factor
smart-beta
momentum
value
growth
quality
profitability
investment
low-volatility
minimum
variance
equal
weight
market
cap
small
mid
large
mega
micro
developed
emerging
frontier
markets
domestic
international
global
regional
sector
industry
thematic
dividend
yield
growth
aristocrats
kings
champions
sustainable
responsible
impact
ESG
environmental
social
governance
exclusionary
screening
positive
negative
best-in-class
integration
shareholder
engagement
proxy
voting
2.2GitHub Actions Workflow
2.2.1Comprehensive Spell Check Action
# .github/workflows/spell-check.ymlname: Spell Check and Content Validationon:push:branches:[main, develop, staging]paths:['content/**','blog/**','strategies/**','**/*.md','**/*.qmd']pull_request:branches:[main]paths:['content/**','blog/**','strategies/**','**/*.md','**/*.qmd']schedule:-cron:'0 6 * * *' # Daily at 6 AM UTCjobs:spell-check:name: Spell Check Contentruns-on: ubuntu-lateststeps:-name: Checkout Repositoryuses: actions/checkout@v4with:fetch-depth:0-name: Setup Node.jsuses: actions/setup-node@v4with:node-version:'18'cache:'npm'-name: Install Dependencies run: | npm install -g cspell@latest npm install --save-dev @cspell/cspell-bundled-dicts-name: Validate CSpell Configuration run: | echo "š Validating CSpell configuration..." cspell --config .cspell.json --validate-directives echo "ā Configuration is valid"-name: Run Spell Check on All Contentid: spell-check run: | echo "š¤ Running spell check on content files..." # Create results directory mkdir -p spell-check-results # Run spell check and capture results if cspell --config .cspell.json "content/**/*.{md,qmd}" \ --reporter @cspell/reporter-json \ > spell-check-results/results.json 2>&1; then echo "ā No spelling errors found" echo "spell_errors=false" >> $GITHUB_OUTPUT else echo "ā Spelling errors detected" echo "spell_errors=true" >> $GITHUB_OUTPUT # Generate human-readable report cspell --config .cspell.json "content/**/*.{md,qmd}" \ --reporter default > spell-check-results/report.txt 2>&1 || true fi-name: Generate Spell Check Summaryif: steps.spell-check.outputs.spell_errors == 'true' run: | echo "š Generating spell check summary..." # Extract unique misspelled words cat spell-check-results/report.txt | \ grep -o 'Unknown word.*' | \ sed 's/Unknown word (\([^)]*\)).*/\1/' | \ sort -u > spell-check-results/misspelled-words.txt echo "š¤ Unique misspelled words:" cat spell-check-results/misspelled-words.txt # Create GitHub issue comment body echo "## Spell Check Results" > spell-check-results/comment.md echo "" >> spell-check-results/comment.md echo "ā **Spelling errors detected in the following files:**" >> spell-check-results/comment.md echo "" >> spell-check-results/comment.md echo '```' >> spell-check-results/comment.md cat spell-check-results/report.txt >> spell-check-results/comment.md echo '```' >> spell-check-results/comment.md-name: Upload Spell Check Resultsif: steps.spell-check.outputs.spell_errors == 'true'uses: actions/upload-artifact@v4with:name: spell-check-resultspath: spell-check-results/retention-days:7-name: Comment on Pull Requestif: github.event_name == 'pull_request' && steps.spell-check.outputs.spell_errors == 'true'uses: actions/github-script@v7with: script: | const fs = require('fs'); const comment = fs.readFileSync('spell-check-results/comment.md', 'utf8'); github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: comment });-name: Fail on Spelling Errorsif: steps.spell-check.outputs.spell_errors == 'true' && github.ref == 'refs/heads/main' run: | echo "ā Spelling errors found in main branch content" echo "Please fix spelling errors before merging to main" exit 1content-validation:name: Content Structure Validationruns-on: ubuntu-latestneeds: spell-checksteps:-name: Checkout Repositoryuses: actions/checkout@v4-name: Setup Pythonuses: actions/setup-python@v4with:python-version:'3.11'-name: Install Python Dependencies run: | pip install pyyaml python-frontmatter textstat-name: Validate Content Structure run: | python - << 'EOF' import os import frontmatter import yaml from pathlib import Path import textstat def validate_frontmatter(file_path): """Validate required front matter fields""" try: with open(file_path, 'r', encoding='utf-8') as f: post = frontmatter.load(f) required_fields = ['title'] recommended_fields = ['description', 'date', 'author'] errors = [] warnings = [] # Check required fields for field in required_fields: if field not in post.metadata: errors.append(f"Missing required field: {field}") # Check recommended fields for field in recommended_fields: if field not in post.metadata: warnings.append(f"Missing recommended field: {field}") # Validate title length if 'title' in post.metadata: title_len = len(post.metadata['title']) if title_len > 60: warnings.append(f"Title too long: {title_len} chars (recommended: <60)") # Validate description length if 'description' in post.metadata: desc_len = len(post.metadata['description']) if desc_len > 160: warnings.append(f"Description too long: {desc_len} chars (recommended: <160)") # Check readability content = post.content if content.strip(): reading_level = textstat.flesch_kincaid().flesch_reading_ease(content) if reading_level < 60: # Below "Standard" level warnings.append(f"Content may be too complex (Flesch score: {reading_level:.1f})") return errors, warnings except Exception as e: return [f"Error parsing file: {str(e)}"], [] # Process all content files content_files = [] for pattern in ['content/**/*.md', 'content/**/*.qmd', 'blog/**/*.md', 'strategies/**/*.md']: content_files.extend(Path('.').glob(pattern)) total_errors = 0 total_warnings = 0 print("š Content Structure Validation Report") print("=" * 50) for file_path in content_files: errors, warnings = validate_frontmatter(file_path) if errors or warnings: print(f"\nš {file_path}") for error in errors: print(f" ā {error}") total_errors += 1 for warning in warnings: print(f" ā ļø {warning}") total_warnings += 1 print(f"\nš Summary:") print(f" Files processed: {len(content_files)}") print(f" Total errors: {total_errors}") print(f" Total warnings: {total_warnings}") if total_errors > 0: print(f"\nā Content validation failed with {total_errors} errors") exit(1) else: print(f"\nā Content validation passed") EOF
2.3Pre-commit Hook Integration
2.3.1Pre-commit Configuration
# .pre-commit-config.yamlrepos:-repo: localhooks:-id: cspellname: Spell Checkentry: cspelllanguage: nodefiles: \.(md|qmd|txt)$args:['--config','.cspell.json']additional_dependencies:['cspell@latest']-id: content-validationname: Content Structure Validationentry: pythonlanguage: pythonfiles: \.(md|qmd)$args:['-c','import frontmatter; import sys; [frontmatter.load(open(f)) for f in sys.argv[1:]]']additional_dependencies:['python-frontmatter']
2.4Local Development Tools
2.4.1Spell Check Script
#!/bin/bash# scripts/spell-check.shset-eecho"š¤ Running spell check on content..."# Check if cspell is installedif! command-v cspell &> /dev/null;thenecho"Installing cspell..."npm install -g cspell@latestfi# Create results directorymkdir-p .spell-check-results# Run spell checkifcspell--config .cspell.json "content/**/*.{md,qmd}"--reporter default;thenecho"ā No spelling errors found"rm-rf .spell-check-resultsexit 0elseecho"ā Spelling errors detected"# Generate suggestions for misspelled wordscspell--config .cspell.json "content/**/*.{md,qmd}"\--reporter @cspell/reporter-json > .spell-check-results/errors.json 2>&1||trueecho""echo"š” To add words to dictionary:"echo"echo 'newword' >> dictionaries/financial-terms.txt"echo""echo"š” To ignore a word in this file only:"echo"Add '<!-- cspell:ignore word -->' comment"echo""echo"š” To disable spell check for a section:"echo"<!-- cspell:disable -->"echo"content with technical terms"echo"<!-- cspell:enable -->"exit 1fi
2.4.2Dictionary Management Script
#!/bin/bash# scripts/manage-dictionary.shDICT_FILE="dictionaries/financial-terms.txt"case"$1"in"add")if[-z"$2"];thenecho"Usage: $0 add <word>"exit 1fiecho"$2">>"$DICT_FILE"sort-u"$DICT_FILE"-o"$DICT_FILE"echo"ā Added '$2' to financial terms dictionary";;"remove")if[-z"$2"];thenecho"Usage: $0 remove <word>"exit 1fised-i''"/^$2$/d""$DICT_FILE"echo"ā Removed '$2' from financial terms dictionary";;"list")echo"š Financial terms dictionary contents:"cat"$DICT_FILE"|sort;;"check")if[-z"$2"];thenecho"Usage: $0 check <word>"exit 1fiifgrep-q"^$2$""$DICT_FILE";thenecho"ā '$2' is in the dictionary"elseecho"ā '$2' is not in the dictionary"fi;;*)echo"Usage: $0 {add|remove|list|check} [word]"exit 1;;esac
2.5Content Quality Metrics
2.5.1Quality Dashboard Script
# scripts/content-quality-dashboard.pyimport jsonimport subprocessimport osfrom pathlib import Pathfrom datetime import datetimedef run_spell_check():"""Run spell check and return results"""try: result = subprocess.run(['cspell', '--config', '.cspell.json','content/**/*.md', 'content/**/*.qmd','--reporter', '@cspell/reporter-json' ], capture_output=True, text=True)if result.returncode ==0:return {"error_count": 0, "errors": []}else:# Parse JSON output for error details errors = []for line in result.stdout.split('\n'):if line.strip():try: error_data = json.loads(line) errors.extend(error_data.get('issues', []))except json.JSONDecodeError:passreturn {"error_count": len(errors), "errors": errors}except subprocess.CalledProcessError as e:return {"error_count": -1, "errors": [f"Spell check failed: {e}"]}def count_content_files():"""Count total content files""" patterns = ['content/**/*.md', 'content/**/*.qmd'] files = []for pattern in patterns: files.extend(Path('.').glob(pattern))returnlen(files)def generate_quality_report():"""Generate comprehensive quality report"""print("š Content Quality Dashboard")print("="*40)print(f"Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")print()# File count file_count = count_content_files()print(f"š Total content files: {file_count}")# Spell check results spell_results = run_spell_check()if spell_results["error_count"] ==0:print("ā Spell check: PASSED (0 errors)")elif spell_results["error_count"] >0:print(f"ā Spell check: FAILED ({spell_results['error_count']} errors)")# Show top misspelled words words = {}for error in spell_results["errors"]: word = error.get("text", "")if word: words[word] = words.get(word, 0) +1if words:print(" Top misspelled words:")for word, count insorted(words.items(), key=lambda x: x[1], reverse=True)[:10]:print(f" - {word} ({count} times)")else:print("ā Spell check: ERROR")print()print("š” To fix spelling errors:")print(" - Add words to dictionaries/financial-terms.txt")print(" - Use inline comments: <!-- cspell:ignore word -->")print(" - Run: ./scripts/spell-check.sh")if__name__=="__main__": generate_quality_report()
This comprehensive spell check and content validation system ensures high-quality, professional content standards while supporting the specialized vocabulary of financial services and investment management.