Files
cs249r_book/tinytorch/site/_static/demos/scripts/vhs-to-terminalizer.sh
Vijay Janapa Reddi c602f97364 feat: integrate TinyTorch into MLSysBook repository
TinyTorch educational deep learning framework now lives at tinytorch/

Structure:
- tinytorch/src/         - Source modules (single source of truth)
- tinytorch/tito/        - CLI tool
- tinytorch/tests/       - Test suite
- tinytorch/site/        - Jupyter Book website
- tinytorch/milestones/  - Historical ML implementations
- tinytorch/datasets/    - Educational datasets (tinydigits, tinytalks)
- tinytorch/assignments/ - NBGrader assignments
- tinytorch/instructor/  - Teaching materials

Workflows (with tinytorch- prefix):
- tinytorch-ci.yml           - CI/CD pipeline
- tinytorch-publish-dev.yml  - Dev site deployment
- tinytorch-publish-live.yml - Live site deployment
- tinytorch-build-pdf.yml    - PDF generation
- tinytorch-release-check.yml - Release validation

Repository Variables added:
- TINYTORCH_ROOT  = tinytorch
- TINYTORCH_SRC   = tinytorch/src
- TINYTORCH_SITE  = tinytorch/site
- TINYTORCH_TESTS = tinytorch/tests

All workflows use \${{ vars.TINYTORCH_* }} for path configuration.

Note: tinytorch/site/_static/favicon.svg kept as SVG (valid for favicons)
2025-12-05 19:23:18 -08:00

233 lines
5.7 KiB
Bash
Executable File

#!/bin/bash
# VHS to Terminalizer Converter
# Converts VHS tape files to Terminalizer YAML configs for polished output
set -e
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
echo -e "${BLUE}🎬 VHS → Terminalizer Converter${NC}"
echo "======================================"
echo ""
# Check arguments
if [ $# -lt 1 ]; then
echo -e "${RED}Usage: $0 <tape-file> [output-yml]${NC}"
echo ""
echo "Examples:"
echo " $0 docs/_static/demos/tapes/01-zero-to-ready.tape"
echo " $0 docs/_static/demos/tapes/01-zero-to-ready.tape 01-custom.yml"
exit 1
fi
TAPE_FILE="$1"
OUTPUT_YML="${2:-$(basename "$TAPE_FILE" .tape).yml}"
# Check if tape file exists
if [ ! -f "$TAPE_FILE" ]; then
echo -e "${RED}❌ Tape file not found: $TAPE_FILE${NC}"
exit 1
fi
echo -e "${BLUE}📄 Input: $TAPE_FILE${NC}"
echo -e "${BLUE}📝 Output: $OUTPUT_YML${NC}"
echo ""
# Check if terminalizer is installed
if ! command -v terminalizer &> /dev/null; then
echo -e "${YELLOW}⚠️ Terminalizer not installed${NC}"
echo ""
echo "Install with: npm install -g terminalizer"
echo ""
echo -e "${BLUE}For now, creating a template config...${NC}"
fi
# Extract metadata from VHS tape
WIDTH=$(grep "^Set Width" "$TAPE_FILE" | awk '{print $3}')
HEIGHT=$(grep "^Set Height" "$TAPE_FILE" | awk '{print $3}')
THEME=$(grep "^Set Theme" "$TAPE_FILE" | sed -n 's/Set Theme "\(.*\)"/\1/p')
OUTPUT_GIF=$(grep "^Output" "$TAPE_FILE" | awk '{print $2}' | tr -d '"')
# Convert Catppuccin Mocha to Terminalizer theme
TERM_THEME="monokai" # Default fallback
case "$THEME" in
"Catppuccin Mocha")
TERM_THEME="monokai"
;;
"Dracula")
TERM_THEME="dracula"
;;
esac
echo -e "${GREEN}📊 Extracted Settings:${NC}"
echo " Dimensions: ${WIDTH}x${HEIGHT}"
echo " Theme: $THEME$TERM_THEME"
echo " Output: $OUTPUT_GIF"
echo ""
# Parse VHS commands and convert to Terminalizer format
echo -e "${BLUE}🔄 Converting commands...${NC}"
# Create Terminalizer config header
cat > "$OUTPUT_YML" << EOF
# Terminalizer Config
# Auto-generated from VHS tape: $TAPE_FILE
# Date: $(date +"%Y-%m-%d %H:%M:%S")
config:
# Recording settings
command: bash -l
cwd: /tmp
# Terminal dimensions
cols: $((WIDTH / 10))
rows: $((HEIGHT / 20))
# Rendering
repeat: 0
quality: 100
frameDelay: auto
maxIdleTime: 2000
# Style
theme:
background: "transparent"
foreground: "#abb2bf"
cursor: "#c678dd"
# Watermark
watermark:
imagePath: null
style:
position: absolute
right: 15px
bottom: 15px
width: 100px
opacity: 0.9
# Cursor style
cursorStyle: block
# Font
fontFamily: "JetBrains Mono, Monaco, Menlo, monospace"
fontSize: 18
lineHeight: 1.2
letterSpacing: 0
# Recording frames
records:
EOF
# Parse VHS tape and convert commands
# This is a simplified converter - it extracts Type and Enter commands
# and converts Sleep to delays
FRAME_COUNT=0
DELAY_MS=0
while IFS= read -r line; do
# Skip comments and empty lines
[[ "$line" =~ ^[[:space:]]*# ]] && continue
[[ -z "$line" ]] && continue
# Parse Type commands
if [[ "$line" =~ ^Type[[:space:]]+"(.+)"$ ]]; then
TEXT="${BASH_REMATCH[1]}"
if [ $FRAME_COUNT -gt 0 ]; then
# Add accumulated delay to previous frame
sed -i '' "s/delay: 0$/delay: $DELAY_MS/" "$OUTPUT_YML"
DELAY_MS=0
fi
# Add typing frame
cat >> "$OUTPUT_YML" << FRAME
- delay: 0
content: "$TEXT"
FRAME
((FRAME_COUNT++))
# Parse Enter commands
elif [[ "$line" =~ ^Enter ]]; then
if [ $FRAME_COUNT -gt 0 ]; then
sed -i '' "s/delay: 0$/delay: $DELAY_MS/" "$OUTPUT_YML"
DELAY_MS=0
fi
cat >> "$OUTPUT_YML" << FRAME
- delay: 0
content: "\\r"
FRAME
((FRAME_COUNT++))
# Parse Sleep commands and accumulate
elif [[ "$line" =~ ^Sleep[[:space:]]+([0-9]+)(ms|s) ]]; then
SLEEP_VAL="${BASH_REMATCH[1]}"
SLEEP_UNIT="${BASH_REMATCH[2]}"
if [ "$SLEEP_UNIT" = "s" ]; then
DELAY_MS=$((DELAY_MS + SLEEP_VAL * 1000))
else
DELAY_MS=$((DELAY_MS + SLEEP_VAL))
fi
# Parse Wait commands and convert to reasonable delay
elif [[ "$line" =~ ^Wait[[:space:]]+([0-9]+)?s?[[:space:]]*Line ]]; then
WAIT_TIMEOUT="${BASH_REMATCH[1]:-5}"
# Convert Wait to a reasonable delay (half the timeout)
DELAY_MS=$((DELAY_MS + (WAIT_TIMEOUT * 1000 / 2)))
fi
done < "$TAPE_FILE"
# Apply final delay if any
if [ $DELAY_MS -gt 0 ] && [ $FRAME_COUNT -gt 0 ]; then
sed -i '' "s/delay: 0$/delay: $DELAY_MS/" "$OUTPUT_YML"
fi
echo -e "${GREEN}✅ Converted $FRAME_COUNT frames${NC}"
echo ""
# Add usage instructions
cat << USAGE
${BLUE}📋 Next Steps:${NC}
1. ${YELLOW}Review the generated config:${NC}
cat $OUTPUT_YML
2. ${YELLOW}Record with Terminalizer:${NC}
terminalizer record $OUTPUT_YML -c $OUTPUT_YML
${BLUE}Or manually replay commands:${NC}
The config contains the command sequence.
You may need to run commands manually in the terminal.
3. ${YELLOW}Render to GIF:${NC}
terminalizer render $OUTPUT_YML -o ${OUTPUT_GIF}
4. ${YELLOW}Preview:${NC}
terminalizer play $OUTPUT_YML
${BLUE}💡 Tips:${NC}
- Terminalizer configs may need manual adjustment
- The converter provides a starting point
- Check timing and add missing pauses
- Terminalizer creates smoother, more polished GIFs
${YELLOW}⚠️ Note:${NC}
Terminalizer requires manual execution, unlike VHS.
The converted config shows the command sequence,
but you'll need to type them during recording.
For fully automated workflow, stick with VHS.
Use Terminalizer only for final polish.
USAGE
echo -e "${GREEN}✅ Conversion complete!${NC}"