Files
new-marp-project/new-marp-project.sh

452 lines
12 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
# ============================================================
# new-marp-project.sh — crée un nouveau projet Marp prêt à l'emploi.
#
# Usage :
# ./new-marp-project.sh slides <dossier> # diaporama 16:9 (thème custom)
# ./new-marp-project.sh a4 <dossier> # document A4 (thème custom-a4)
# ./new-marp-project.sh # mode interactif
# ./new-marp-project.sh --help
# ============================================================
usage() {
sed -n 's/^# \+//p' "$0" | sed -n '2,8p'
exit "${1:-0}"
}
# --- Arguments ----------------------------------------------------
if [ "${1:-}" = "--help" ] || [ "${1:-}" = "-h" ]; then
usage 0
fi
if [ $# -eq 2 ]; then
TYPE="$1"
DIR="$2"
elif [ $# -eq 0 ]; then
read -rp "Type de projet (slides/a4) : " TYPE
read -rp "Nom du dossier : " DIR
else
usage 1
fi
case "$TYPE" in
slides|a4) ;;
*) echo "Type invalide : attendu 'slides' ou 'a4'."; usage 1 ;;
esac
# --- Sécurités ----------------------------------------------------
if [ -z "$DIR" ]; then
echo "Nom du dossier manquant."; exit 1
fi
if [ -e "$DIR" ] && [ -n "$(ls -A "$DIR" 2>/dev/null)" ]; then
echo "ERREUR : le dossier '$DIR' existe déjà et n'est pas vide."; exit 1
fi
mkdir -p "$DIR/.vscode"
echo "Création du projet '$TYPE' dans '$DIR'..."
# ============================================================
# 1. Configuration commune (Marp CLI + extension VS Code)
# ============================================================
if [ "$TYPE" = "slides" ]; then
cat > "$DIR/.marprc.json" <<'EOF'
{
"themeSet": [".vscode/custom.css"]
}
EOF
cat > "$DIR/.vscode/settings.json" <<'EOF'
{
"markdown.marp.themes": [".vscode/custom.css"]
}
EOF
else
cat > "$DIR/.marprc.json" <<'EOF'
{
"themeSet": [".vscode/custom.css", ".vscode/custom-a4.css"]
}
EOF
cat > "$DIR/.vscode/settings.json" <<'EOF'
{
"markdown.marp.themes": [".vscode/custom.css", ".vscode/custom-a4.css"]
}
EOF
fi
# ============================================================
# 2. Thème commun custom.css
# ============================================================
cat > "$DIR/.vscode/custom.css" <<'EOF'
/* @theme custom
*
* Surcharge du thème "default" de Marp.
* Le thème par défaut est importé puis adapté.
*
* Toutes les couleurs / valeurs sont centralisées dans les variables
* :root pour faciliter les modifications.
*
* Sommaire
* ---------
* 1. Design tokens (:root) — couleurs, typo, bordures
* 2. Base — section, titres, liens, strong, blockquote
* 3. Layout de section — variante .nolead
* 4. Header / Footer / Pages — en-tête, pied de page, pagination
* 5. Tableaux — table, th, td, zebra, cas .two-cols
* 6. Colonnes (grid) — .columns / .cols-N
* 7. Impression — @media print
*/
@import "default";
/* ==================================================================
* 1. Design tokens — toutes les valeurs modifiables du thème
* ================================================================== */
:root {
/* --- Couleurs principales --- */
--color-bg: #ffffff; /* fond des diapos */
--color-text: #1f2328; /* texte principal */
--color-primary: #0969da; /* titres, liens, tableaux */
--color-accent: #cf222e; /* strong, code */
--color-muted: #6e7781; /* header, footer, numérotation */
--color-border: #d0d7de; /* bordures */
--color-bg-soft: #f6f8fa; /* fonds secondaires (blockquote, pre, zebra) */
--color-code-bg: #eeeeee; /* fond du code inline */
/* --- Typographie --- */
--font-family: "Segoe UI", Arial, sans-serif;
--font-size-small: 0.8em;
--font-size-medium: 0.9em;
/* --- Bordures & arrondis --- */
--radius: 6px;
--border-width-thick: 4px;
--border-width-thin: 1px;
}
/* ==================================================================
* 2. Base — styles globaux de la diapo
* ================================================================== */
section {
background: var(--color-bg);
color: var(--color-text);
font-family: var(--font-family);
}
h1 {
color: var(--color-primary);
padding-bottom: 0.2em;
}
h2,
h3 {
color: var(--color-text);
}
strong {
color: var(--color-accent);
}
a {
color: var(--color-primary);
}
blockquote {
border-left: var(--border-width-thick) solid var(--color-primary);
background: var(--color-bg-soft);
padding: 0.5em 1em;
border-radius: var(--radius);
}
/* ==================================================================
* 3. Layout de section — variante .nolead
* (contenu aligné en haut à gauche, sans la mise en page centrée
* par défaut de Marp)
* ================================================================== */
section.nolead {
display: flex;
flex-direction: column;
justify-content: flex-start;
text-align: left;
}
/* ==================================================================
* 4. Header / Footer / Pagination
* ================================================================== */
/* En-tête / pied de page définis dans le front-matter */
header {
color: var(--color-muted);
font-size: var(--font-size-small);
border-bottom: var(--border-width-thin) solid var(--color-border);
}
footer {
color: var(--color-muted);
font-size: var(--font-size-medium);
}
/* Numérotation de page */
section::after {
color: var(--color-muted);
}
/* ==================================================================
* 5. Tableaux
* ================================================================== */
table {
display: table; /* la base GFM impose display:block, ce qui ignore les largeurs de colonnes */
border-collapse: collapse;
width: 100%;
}
th,
td {
border: var(--border-width-thin) solid var(--color-border);
padding: 0.4em 0.8em;
}
th {
background: var(--color-primary);
color: var(--color-bg);
}
/* Lignes impaires sur fond neutre (effet "zebra") */
tr:nth-child(even) td {
background: var(--color-bg-soft);
}
/* --- Variante .two-cols : tableau 2 colonnes verticales (gauche / droite) --- */
section.two-cols table {
display: table; /* la base GFM impose display:block, ce qui ignore les largeurs de colonnes */
width: 100%;
table-layout: fixed; /* 2 colonnes égales (50/50) au lieu de l'auto */
border-collapse: collapse;
}
section.two-cols th,
section.two-cols td {
vertical-align: top; /* contenu aligné en haut, façon listes */
text-align: left;
padding: 0.6em 1em;
}
/* Séparateur vertical entre les 2 colonnes */
section.two-cols th:first-child,
section.two-cols td:first-child {
border-right: var(--border-width-thin) solid var(--color-border);
}
/* ==================================================================
* 6. Colonnes verticales — .columns + .cols-N (display: grid)
* ================================================================== */
section .columns {
display: grid;
gap: 0 2em;
}
section .columns.cols-2 {
grid-template-columns: repeat(2, 1fr);
}
section .columns.cols-3 {
grid-template-columns: repeat(3, 1fr);
}
section .columns.cols-4 {
grid-template-columns: repeat(4, 1fr);
}
section .columns > div {
min-width: 0; /* permet au contenu (pre, code, tableaux) de rester dans sa colonne */
padding: 0.6em 1em;
}
/* Séparateur vertical entre les colonnes */
section .columns > div + div {
border-left: var(--border-width-thin) solid var(--color-border);
}
/* ==================================================================
* 7. Impression / export PDF — conserver les couleurs
* ================================================================== */
@media print {
section {
background: var(--color-bg);
}
}
EOF
# ============================================================
# 3. Fichiers spécifiques au type A4
# ============================================================
if [ "$TYPE" = "a4" ]; then
cat > "$DIR/.vscode/custom-a4.css" <<'EOF'
/* @theme custom-a4
*
* Variante du thème "custom" adaptée au format A4 (portrait).
* Destinée aux exports PDF / DOCX, elle reprend intégralement les
* règles du thème "custom" et n'adapte que la taille de page et
* les marges.
*
* Le thème de base est importé via @import, puis surchargé : inutile
* de dupliquer les styles, toute modification de "custom" se
* répercute automatiquement ici.
*
* Sommaire
* --------
* 1. Page A4 — taille, marges et corps de texte de la diapo
* 2. Typographie — tailles des titres pour un document
* 3. Impression / export PDF — réglages @page
*/
@import "custom";
/* ==================================================================
* 1. Page A4 — taille de la diapo en unités absolues
*
* Marpit utilise la taille des <section> (ou :root) comme taille de
* page pour le PDF exporté. Le format A4 standard fait 210 x 297 mm.
* La taille de diapo est fixée dans le thème : il n'est pas possible
* de la modifier via une classe ou une directive locale.
* ================================================================== */
section {
width: 210mm; /* ~794 px */
height: 297mm; /* ~1123 px */
/* Marges "papier" plus généreuses que le défaut du thème "default"
* (~78px), pour un rendu proche d'un document imprimé. */
padding: 20mm 22mm;
/* Corps de texte type document imprimé.
* Le thème "default" (conçu pour des diapos 1280x720) impose 29px,
* beaucoup trop grand une fois la page passée au format A4. */
font-size: 11pt; /* ~14.7 px — texte courant */
line-height: 1.4;
}
/* ==================================================================
* 2. Typographie — tailles des titres pour un document A4
* (valeurs exprimées en em, relatives au corps de texte ci-dessus)
* ================================================================== */
h1 {
font-size: 1.45em; /* ~16 pt */
}
h2 {
font-size: 1.25em; /* ~13.8 pt */
}
h3 {
font-size: 1.1em; /* ~12 pt */
}
h4 {
font-size: 1em; /* ~11 pt */
}
/* ==================================================================
* 3. Impression / export PDF — réglages @page
*
* Assure une page A4 exacte (sans marges navigateur supplémentaires)
* lors de l'export PDF via Marp CLI. La largeur/hauteur des sections
* définie ci-dessus reste la source de vérité du format.
* ================================================================== */
@page {
size: A4 portrait;
margin: 0;
}
EOF
cat > "$DIR/pandoc-strip-hr.lua" <<'EOF'
-- ==================================================================
-- pandoc-strip-hr.lua
--
-- Filtre pandoc : supprime les filets horizontaux (---, ***) lors de
-- la conversion vers DOCX.
--
-- Dans un projet Marp, les "---" servent à séparer les diapos : en
-- les convertissant avec pandoc, ils apparaissent comme des traits
-- horizontaux inutiles dans le document Word. Ce filtre les retire.
--
-- Usage :
-- pandoc document.md --lua-filter=pandoc-strip-hr.lua -o document.docx
-- ==================================================================
function HorizontalRule()
return {}
end
EOF
fi
# ============================================================
# 4. Fichier de départ (le front-matter choisit déjà le thème)
# ============================================================
if [ "$TYPE" = "slides" ]; then
cat > "$DIR/slides.md" <<'EOF'
---
marp: true
theme: custom
paginate: true
header: "Mon header"
footer: "Mon footer"
class: nolead
---
# Bienvenue
## Nouveau diaporama
Ceci est la première diapo de votre nouveau projet.
---
# Une nouvelle diapo
- Item 1
- Item 2
EOF
else
cat > "$DIR/document.md" <<'EOF'
---
marp: true
theme: custom-a4
paginate: true
header: "Mon header"
footer: "Mon footer"
class: nolead
---
# Titre du document A4
## Sous-titre
Corps de texte du document. Chaque bloc `---` devient une nouvelle page A4.
---
# Deuxième page
Contenu de la deuxième page.
EOF
fi
chmod -R u+rw "$DIR"
# ============================================================
# 5. Récapitulatif et commandes d'export
# ============================================================
echo
echo "Projet '$TYPE' créé dans '$DIR' :"
find "$DIR" -type f | sort | sed 's/^/ /'
echo
if [ "$TYPE" = "slides" ]; then
echo "Exports :"
echo " npx @marp-team/marp-cli $DIR/slides.md --pdf"
echo " npx @marp-team/marp-cli $DIR/slides.md --pptx"
else
echo "Exports :"
echo " npx @marp-team/marp-cli $DIR/document.md --pdf"
echo " pandoc $DIR/document.md --lua-filter=$DIR/pandoc-strip-hr.lua -o $DIR/document.docx"
fi
echo
echo "Préview VS Code : ouvrir $DIR/slides.md et lancer le preview Marp."