Skip to content
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
160 changes: 160 additions & 0 deletions Build/COVER_PAGE_FEATURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# Custom Cover Page Feature

## Overview
The PDF build process now automatically replaces the first page (auto-generated title page) with a custom cover image.

## Cover Image
- **Location**: `chapters/media/TS_SysmonCommunityGuide_Cover.png`
- **Format**: PNG
- **Size**: ~3 MB (high resolution)
- **Page Size**: Scaled to fit A4 with aspect ratio maintained

## Implementation

### Components
1. **`Build/replace_cover.py`** - Python script that handles cover replacement
- Uses `pypdf` (or PyPDF2) to manipulate PDF pages
- Uses `Pillow` to process cover image
- Uses `reportlab` to convert image to PDF page
- Maintains A4 page size and centers image

2. **`Build/md2pdf.sh`** - Updated to call cover replacement after PDF generation
- Generates PDF with XeLaTeX (2 passes for TOC)
- Checks for cover image existence
- Replaces first page automatically
- Handles errors gracefully (falls back to original if replacement fails)

3. **Dependencies** - Added Python packages:
- `pypdf` - PDF manipulation
- `Pillow` - Image processing
- `reportlab` - PDF generation

### Build Process Flow
```
1. Pandoc converts Markdown → LaTeX
2. XeLaTeX generates PDF (2 passes)
3. Custom cover replacement:
a. Check if TS_SysmonCommunityGuide_Cover.png exists
b. Convert cover image to PDF page (A4, centered, scaled)
c. Replace first page of generated PDF with cover
d. Save final PDF
4. Clean up temporary files
```

## Usage

### Normal Build
```bash
# Just build as usual - cover replacement happens automatically
make pdf

# Or using build.sh
./build.sh pdf
```

### Installing Dependencies

**macOS:**
```bash
make install-deps-mac
# Or manually:
pip3 install --user --break-system-packages pypdf Pillow reportlab
```

**Ubuntu/Debian:**
```bash
make install-deps
# Or manually:
pip3 install pypdf Pillow reportlab
```

**Docker:**
```bash
# Dependencies already included in Docker image
make docker-pdf
```

## Customization

### Using a Different Cover Image
1. Replace `chapters/media/TS_SysmonCommunityGuide_Cover.png` with your image
2. Image can be any size - will be automatically scaled to fit A4
3. Maintains aspect ratio - will not distort
4. Centered on page

### Disabling Cover Replacement
If you want to use the default Pandoc-generated title page:
1. Remove or rename the cover image file, OR
2. Comment out the cover replacement section in `Build/md2pdf.sh` (lines 64-80)

## Technical Details

### Image Processing
- Cover image is converted to a temporary PDF (`/tmp/cover_page.pdf`)
- Image is scaled to fit A4 (210mm × 297mm) while maintaining aspect ratio
- Image is centered on the page
- Uses high-quality rendering from Pillow

### PDF Manipulation
- Original PDF is temporarily renamed
- Cover page PDF is created with exact A4 dimensions
- First page of original PDF is replaced with cover
- All other pages (2-N) are copied unchanged
- Temporary files are cleaned up

### Error Handling
- Checks if cover image exists before attempting replacement
- Validates PDF was generated successfully
- Falls back to original PDF if replacement fails
- Provides clear error messages in build output

## Verification

After building, verify the cover replacement worked:

```bash
# Check PDF exists and has correct size
ls -lh Build/SysmonGuide.pdf

# Check number of pages
file Build/SysmonGuide.pdf

# Open PDF and visually inspect first page
open Build/SysmonGuide.pdf # macOS
xdg-open Build/SysmonGuide.pdf # Linux
```

## Troubleshooting

### "Module not found" errors
Install Python dependencies:
```bash
pip3 install --user --break-system-packages pypdf Pillow reportlab
```

### Cover replacement fails
Check build log for errors:
```bash
cat Build/pdfgen.log
```

### Cover image not found
Verify the image exists:
```bash
ls -lh chapters/media/TS_SysmonCommunityGuide_Cover.png
```

### PDF is too large
The cover image adds ~3MB to the PDF. To reduce size:
1. Optimize the cover image before building
2. Convert to lower DPI (e.g., 150 DPI instead of 300 DPI)
3. Use JPEG instead of PNG (with quality setting)

## Future Enhancements

Potential improvements:
- [ ] Support for back cover page
- [ ] Configurable cover image path in chapters.json
- [ ] Multiple cover formats (PDF, SVG, etc.)
- [ ] Automatic image optimization
- [ ] Cover template system
5,736 changes: 4,770 additions & 966 deletions Build/Sysmon.md

Large diffs are not rendered by default.

Binary file added Build/SysmonGuide.pdf
Binary file not shown.
22 changes: 15 additions & 7 deletions Build/chapter_break.tex
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
%% Adds pagebreak between chapters
% from comments of accepted answer
% https://superuser.com/questions/601469/getting-chapters-to-start-on-a-new-page-in-a-pandoc-generated-pdf
%% Chapter/Section Styling
%% Customize appearance of level 1 headings (sections in Pandoc = # in markdown)

\usepackage{sectsty}
\sectionfont{\clearpage}

% accepted answer gave error
%\usepackage{titlesec}
%\newcommand{\sectionbreak}{\clearpage}
% Level 1 headings: centered, larger, bold, with spacing but NO page break
\sectionfont{\centering\LARGE\bfseries}

% Add some vertical space before and after level 1 headings
\usepackage{titlesec}
\titlespacing*{\section}
{0pt} % left margin
{3ex plus 1ex minus .2ex} % space before (vertical)
{2ex plus .2ex} % space after (vertical)

% Optional: Keep subsections and subsubsections left-aligned
\subsectionfont{\large\bfseries}
\subsubsectionfont{\normalsize\bfseries}
26 changes: 24 additions & 2 deletions Build/md2pdf.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,20 @@ SCRIPT=$(readlink -f "$0")
SCRIPTPATH=$(dirname "$SCRIPT")
echo "Running Pandoc to generate the LaTeX file..."
pandoc "$1" \
-f gfm \
-f markdown \
--toc \
--toc-depth=3 \
--listings \
--include-in-header ${SCRIPTPATH}/chapter_break.tex \
--include-in-header ${SCRIPTPATH}/inline_code.tex \
--include-in-header ${SCRIPTPATH}/bullet_style.tex \
--include-in-header ${SCRIPTPATH}/pdf_properties.tex \
--include-in-header ${SCRIPTPATH}/listings-setup.tex \
--include-in-header ${SCRIPTPATH}/toc-styling.tex \
--include-in-header ${SCRIPTPATH}/title_page.tex \
--include-in-header ${SCRIPTPATH}/toc_pagebreak.tex \
--highlight-style ${SCRIPTPATH}/pygments.theme \
-V toc-title='Table of contents' \
-V toc-title='Sysmon Guide Contents' \
-V linkcolor:blue \
-V geometry:a4paper \
-V geometry:margin=2cm \
Expand All @@ -59,6 +63,24 @@ xelatex -interaction=nonstopmode ${fn}.tex > pdfgen.log 2>&1
echo "Generating PDF (second pass for TOC)..."
xelatex -interaction=nonstopmode ${fn}.tex >> pdfgen.log 2>&1

# Replace first page with custom cover if cover image exists
COVER_IMAGE="${SCRIPTPATH}/../chapters/media/TS_SysmonCommunityGuide_Cover.png"
if [ -f "$COVER_IMAGE" ]; then
echo "Replacing first page with custom cover..."
TEMP_PDF="${fn}_temp.pdf"
mv "${fn}.pdf" "$TEMP_PDF"

if python3 "${SCRIPTPATH}/replace_cover.py" "$TEMP_PDF" "$COVER_IMAGE" "${fn}.pdf"; then
echo "Cover page replaced successfully"
rm "$TEMP_PDF"
else
echo "Warning: Failed to replace cover page, using original PDF"
mv "$TEMP_PDF" "${fn}.pdf"
fi
else
echo "Warning: Cover image not found at $COVER_IMAGE, skipping cover replacement"
fi

echo "Cleaning temp files..."
rm /tmp/temp.tex "$fn".{tex,toc,aux,log}

Binary file added Build/media/TS_SysmonCommunityGuide_Cover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Build/media/image1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Build/media/image10.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Build/media/image11.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Build/media/image12.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Build/media/image13.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Build/media/image14.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Build/media/image15.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Build/media/image16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Build/media/image17.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Build/media/image18.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Build/media/image19.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Build/media/image2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Build/media/image20.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Build/media/image21.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Build/media/image22.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Build/media/image23.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Build/media/image24.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Build/media/image25.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Build/media/image26.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Build/media/image27.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Build/media/image28.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Build/media/image29.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Build/media/image3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Build/media/image30.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Build/media/image31.png
Binary file added Build/media/image32.png
Binary file added Build/media/image33.png
Binary file added Build/media/image34.png
Binary file added Build/media/image35.png
Binary file added Build/media/image36.png
Binary file added Build/media/image37.png
Binary file added Build/media/image38.png
Binary file added Build/media/image39.png
Binary file added Build/media/image4.png
Binary file added Build/media/image40.png
Binary file added Build/media/image41.png
Binary file added Build/media/image42.png
Binary file added Build/media/image43.png
Binary file added Build/media/image44.png
Binary file added Build/media/image45.png
Binary file added Build/media/image46.png
Binary file added Build/media/image47.png
Binary file added Build/media/image48.png
Binary file added Build/media/image49.png
Binary file added Build/media/image5.png
Binary file added Build/media/image50.png
Binary file added Build/media/image51.png
Binary file added Build/media/image52.png
Binary file added Build/media/image53.png
Binary file added Build/media/image54.png
Binary file added Build/media/image55.png
Binary file added Build/media/image56.png
Binary file added Build/media/image57.png
Binary file added Build/media/image58.png
Binary file added Build/media/image59.png
Binary file added Build/media/image6.png
Binary file added Build/media/image60.png
Binary file added Build/media/image61.png
Binary file added Build/media/image62.png
Binary file added Build/media/image63.png
Binary file added Build/media/image64.png
Binary file added Build/media/image65.png
Binary file added Build/media/image66.png
Binary file added Build/media/image67.png
Binary file added Build/media/image68.png
Binary file added Build/media/image7.png
Binary file added Build/media/image8.png
Binary file added Build/media/image9.png
Binary file added Build/media/tslogo.png
Binary file added Build/media/tslogo_old.png
Loading
Loading