Skip to main content

D2L Document Generation

D2L Document Generation#

Python-based system to generate professional, WCAG AAA-compliant PDFs and DOCX files from course content for Brightspace (D2L) upload.

Features#

  • πŸ“„ Dual-path generation β€” PDFs via Typst (beautiful), DOCXs via Pandoc (editable)
  • 🎯 Flexible modes β€” Combined or individual files per content item
  • βœ… WCAG AAA compliant β€” Both formats meet accessibility standards
  • 🎨 Professional styling β€” MSU green branding template
  • πŸ“Š Multiple content types β€” Readings, assignments, resources, docs
  • πŸ”„ Batch processing β€” Generate all at once or by type

Quick Start#

Generate readings as PDF + DOCX#

cd /path/to/repo
source venv/bin/activate.fish
python scripts/generate-d2l-docs.py --type readings --format both

Output:

  • output/d2l/readings.pdf β€” Beautiful, paginated (346 KB)
  • output/d2l/readings.docx β€” Editable in Word (21 KB)

Generate individual files#

python scripts/generate-d2l-docs.py --type assignments --individual --format both

Output:

  • output/d2l/assignment-01.pdf + .docx
  • output/d2l/assignment-02.pdf + .docx
  • … (one pair per file)

Setup#

Prerequisites#

  1. Virtual environment (one-time setup):

    python3 -m venv venv
    source venv/bin/activate.fish
    pip install python-frontmatter markdown pyyaml pypandoc
    
  2. Typst (for PDF generation):

    brew install typst
    
  3. Pandoc (for DOCX generation):

    brew install pandoc
    

Verify Installation#

typst --version
pandoc --version
python --version

Usage#

Command Syntax#

python scripts/generate-d2l-docs.py [OPTIONS]

Options#

OptionValuesDefaultDescription
--typereadings, assignments, resources, docs, allallContent type
--formatpdf, docx, bothpdfOutput format
--individual(flag)combinedSeparate files per item

Common Examples#

Combined documents#

# All readings as one PDF
python scripts/generate-d2l-docs.py --type readings

# All content in both formats
python scripts/generate-d2l-docs.py --format both

# Assignments as combined PDF + DOCX
python scripts/generate-d2l-docs.py --type assignments --format both

Individual documents#

# Each reading separate
python scripts/generate-d2l-docs.py --type readings --individual

# Each resource in both formats
python scripts/generate-d2l-docs.py --type resources --individual --format both

# All content as individual files
python scripts/generate-d2l-docs.py --individual --format both

Specific types#

# Syllabus and docs only
python scripts/generate-d2l-docs.py --type docs --format both

# Resources only
python scripts/generate-d2l-docs.py --type resources --individual

Accessibility & Compliance#

PDF (Typst-generated)#

βœ… WCAG AAA Compliant:

  • Color contrast: 7:1+ minimum
  • Body text: 17.4:1 βœ“
  • Headings: 10.75:1 βœ“
  • Footer: 8.06:1 βœ“
  • Proper heading hierarchy (h1 β†’ h2 β†’ h3)
  • Readable fonts (11pt Roboto)
  • Optimized spacing (0.7em leading)

DOCX (Pandoc-generated)#

βœ… Native Accessibility:

  • Semantic structure preserved
  • Heading tags for screen readers
  • Editable in Microsoft Word
  • Supports annotations
  • Cross-platform compatible

Output Structure#

Files are saved to: output/d2l/

Combined mode#

output/d2l/
β”œβ”€β”€ readings.pdf        # All readings
β”œβ”€β”€ readings.docx
β”œβ”€β”€ assignments.pdf
β”œβ”€β”€ assignments.docx
β”œβ”€β”€ resources.pdf
β”œβ”€β”€ resources.docx
└── docs.pdf

Individual mode#

output/d2l/
β”œβ”€β”€ week-01.pdf         # One per item
β”œβ”€β”€ week-01.docx
β”œβ”€β”€ week-02.pdf
β”œβ”€β”€ week-02.docx
β”œβ”€β”€ assignment-01.pdf
β”œβ”€β”€ assignment-01.docx
└── ...

Content Requirements#

Files need frontmatter:

---
title: "Week 1: Introduction"
weight: 1
---

# Main heading

Your markdown content...
  • title β€” Used as document heading
  • weight β€” Sort order (lower = earlier)
  • Content β€” Standard markdown

File Structure#

content/
β”œβ”€β”€ readings/           # Weekly readings
β”‚   β”œβ”€β”€ week-01.md
β”‚   β”œβ”€β”€ week-02.md
β”‚   └── ...
β”œβ”€β”€ assignments/        # Assignments
β”‚   β”œβ”€β”€ assignment-01.md
β”‚   └── ...
β”œβ”€β”€ resources/          # Additional resources
β”‚   └── ...
└── docs/              # Syllabus, guides, etc.
    └── ...

D2L Upload Guide#

  1. In D2L, go to Content > Learning Materials
  2. Upload readings.pdf, assignments.pdf, etc.
  3. Students download and view in PDF reader
  4. βœ… Maintains formatting
  5. βœ… Accessible on all devices
  6. βœ… Offline readable

DOCX Method (For Editing)#

  1. Upload .docx file to Brightspace
  2. Students download and edit in Word
  3. βœ… Can add annotations
  4. βœ… Can customize formatting
  5. βœ… Offline access

Hybrid Approach (Best)#

  1. Post PDF for reading
  2. Include DOCX link for students who prefer Word
  3. βœ… Covers all accessibility needs
  4. βœ… Covers all device preferences

File Naming#

Script uses Hugo filename as output name:

SourceOutput (Combined)Output (Individual)
content/readings/week-01.mdreadings.pdfweek-01.pdf
content/assignments/project-a.mdassignments.pdfproject-a.pdf

Troubleshooting#

typst: command not found#

Install Typst:

brew install typst
typst --version

pandoc: command not found#

Install Pandoc:

brew install pandoc
pandoc --version

Empty output directory#

  1. Check content exists:

    ls -la content/readings/
    ls -la content/assignments/
    
  2. Ensure files have title: in frontmatter

  3. Check script can find template:

    ls -la templates/typst/clean/template.typ
    

DOCX looks plain#

This is intentional β€” minimal styling ensures cross-platform compatibility. You can:

  1. Use PDF version for rich formatting
  2. Edit DOCX in Word to add styles
  3. Create custom reference document

PDF font rendering issues#

# Clear cache
rm -rf output/d2l/*.typ

# Regenerate
python scripts/generate-d2l-docs.py --type readings --format pdf

Performance#

Approximate generation times:

TaskTime
Single reading PDF2-3 seconds
Combined readings (12 files)3-5 seconds
Single DOCX1-2 seconds
Full regenerate (all types, both)30-60 seconds

Automation#

Shell Script#

# Create scripts/regenerate-d2l.sh
cat > scripts/regenerate-d2l.sh << 'EOF'
#!/bin/bash
cd "$(dirname "$0")/.."
source venv/bin/activate.fish
python scripts/generate-d2l-docs.py --format both
echo "βœ… D2L documents regenerated"
EOF

chmod +x scripts/regenerate-d2l.sh
./scripts/regenerate-d2l.sh

CI/CD Pipeline#

Add to your GitHub Actions workflow:

- name: Generate D2L Documents
  run: |
    source venv/bin/activate
    python scripts/generate-d2l-docs.py --format both

Advanced: Custom DOCX Template#

Create a reference document for custom styling:

# Generate default reference
pandoc -o output/d2l/reference.docx --print-default-data-file reference.docx

# Edit reference.docx with Word styles
# Save as output/d2l/reference.docx
# Script automatically uses it

Template Customization#

Edit templates/typst/clean/template.typ to customize PDFs:

  • Font: Change from Roboto to any system font
  • Colors: Modify MSU green or text colors
  • Margins: Adjust page margins
  • Heading sizes: Increase/decrease heading sizes

See Template Guide for details.

Maintenance#

Update Template#

# Edit template
nano templates/typst/clean/template.typ

# Regenerate documents
python scripts/generate-d2l-docs.py --format both

# Commit changes
git add templates/
git commit -m "Update PDF template styling"

Add New Content Type#

Edit scripts/generate-d2l-docs.py:

types_to_process = ['readings', 'assignments', 'resources', 'docs', 'new-type']

Then run script with --type new-type.

Key Features Explained#

Dual-Path Generation#

Why two different tools?

  • Typst β†’ Beautiful PDFs with professional typography
  • Pandoc β†’ Direct markdownβ†’DOCX with native Word compatibility

This gives you:

  • βœ… Professional PDFs for distribution
  • βœ… Editable DOCXs for student work

Combined vs Individual#

Combined: All readings in one PDF

  • βœ… Single file to manage
  • ❌ Harder to organize updates

Individual: One PDF per reading

  • βœ… Easy to update one section
  • βœ… Student downloads only what needed
  • ❌ More files to manage

Use case: Combined for printing, individual for online.

Format Options#

PDF only:

  • Fast generation
  • Beautiful output
  • Read-only

DOCX only:

  • Fast generation
  • Editable
  • Native Word format

Both:

  • Complete flexibility
  • Students choose format
  • Slightly longer generation

Support#

Common Questions#

Q: Can I customize the PDF styling?
A: Yes! Edit templates/typst/clean/template.typ

Q: Can students edit the PDF?
A: No, use DOCX format for editing. Or use bothβ€”let students choose.

Q: How do I update one assignment?
A: Edit the markdown file, regenerate with --type assignments --individual

Q: Can I automate regeneration?
A: Yes, use the shell script or CI/CD pipeline approach

Q: How big are the files?
A: PDFs: 150-350 KB, DOCXs: 10-50 KB per document


Last Updated: May 2026
Status: Production ready
Accessibility: WCAG AAA compliant