Partage : Totalité des audios des pinyins et tons (fichiers mp3 et deck anki)

Merci beaucoup pour ton partage de compètence qui va grandement nous aider dans l’apprentissage :folded_hands:t3::innocent:

Un grand merci pour ces explications. Pas certain que j’ai le niveau informatique et IA pour y arriver mais je vais me pencher dessus.

Bonjour à tous,

Il ne manquerait pas le 5e ton pour tous ces fichiers par hasard ?

1 « J'aime »

Bonjour
J’ai créé un deck basé sur la liste HSK1 150 d’Alex et les pinyin tones de Keskidees.
Avec 3 cartes basiques (Hanzi > Pinyin+ audio; audio >Hanzi + Pinyin ; Traduction > audio +Hanzi + Pinyin) avec les liens vers Pleco et une carte Hanzi Writer :melting_face: .
le hanzi writer marche sur Ankidesktop , Anki mobile sur iphone et Ipad (mais pas testé sur Anki android). Si certains veulent tester je peux partager le deck.
Si le test est concluant j’envisage de créer les decks HSK2 150 … HSK 6 2500 (j’ai déjà préparé les bases)
voilà un screenshot de la carte Hanzi writer

2 « J'aime »

C’est super! Merci beaucoup. Je suis preneur

Voilà le lien vers le .apkg
(pour l’instant que les 150 premiers caractères/mots HSK1)

Bonjour à tous !
Je viens d’améliorer légèrement le deck en utilisant les explications de prononciation proposées par Alex dans son document gratuit « BONUS Table des sons ».

Voici de nouveau le lien pour télécharger le deck avec tout le code à jour :

Pour ceux qui ont déjà commencés à étudier ce deck, voici le code à copier-coller dans l’encart du style de la carte :
Verso - Back template

<link href="https://fonts.googleapis.com/css2?family=Reggae+One&family=Lexend:wght@300;500;700&display=swap" rel="stylesheet">

<div class="zh-pinyin-container">
    <div class="zh-pinyin-title">Correction</div>

    <div class="zh-pinyin-text-main" id="zh-colored-pinyin">{{pinyin}}</div>
    <div class="zh-pinyin-audio-wrap">{{audio_name}}</div>

    <div class="zh-pinyin-section-title">Prononciation</div>
    <div id="zh-pronunciation-container" class="zh-pronunciation-box"></div>

    <div class="zh-pinyin-section-title">Fréquence d'apparition</div>
    <div id="zh-freq-container"></div>
</div>

<script>
(function() {
    const useTraditional = false; 
    const rawSimp = "{{example_characters_simplified}}".replace(/[\[\]]/g, '').split(',');
    const rawTrad = "{{example_characters_traditional}}".replace(/[\[\]]/g, '').split(',');
    const rawFreq = "{{cumulative_frequency}}".replace(/[\[\]]/g, '').split(',');
    const rawHSK  = "{{hsk}}".replace(/[\[\]]/g, '').split(',');
    const toneNum = "{{tone_number}}".trim();
    const rawPinyin = "{{pinyin}}".trim();

    // 1. GESTION DE LA COULEUR DU PINYIN
    const pinyinEl = document.getElementById('zh-colored-pinyin');
    if(pinyinEl) {
        const style = getComputedStyle(document.documentElement);
        pinyinEl.style.color = style.getPropertyValue('--tone-' + (toneNum || '5')).trim();
    }

    // 2. GESTION DE LA PRONONCIATION (DICTIONNAIRES & LOGIQUE)
    const pinyinPrefixes = {
        "b": "Comme le 'b' français mais moins expiré",
        "p": "Comme le 'p' français mais plus expiré",
        "m": "Comme le 'm' français",
        "n": "Comme le 'n' français",
        "f": "Comme le 'f' français",
        "d": "Comme le 'd' français mais moins expiré",
        "t": "Comme le 't' français mais plus expiré",
        "h": "Comme le 'h' anglais, proche du 'r' français",
        "g": "Comme le 'g' français mais moins expiré",
        "k": "Comme le 'k' français mais plus expiré",
        "j": "Entre les sons 'dj' et 'ti' en français, proche du 'jeep' en anglais",
        "q": "Entre 'ts' et 'tch' en français, proche de 'chin chin' en français",
        "x": "Proche du 'ch' français en tirant la langue en arrière",
        "z": "Se prononce un peu comme le son 'dze' en français",
        "c": "Se prononce un peu comme le son 'tse' en français",
        "s": "Se prononce un peu comme le 's' de cela en français",
        "zh": "Se prononce un peu comme le 'j' de jean en anglais",
        "ch": "Se prononce un peu comme 'tcheu' en français",
        "sh": "Se prononce comme 'ch' de chaud en français",
        "r": "Se prononce comme le 'j' de jeux en français"
    };

    const pinyinSuffixes = {
        "a": "Comme le 'a' français",
        "e": "Comme le 'e' de 'euuuuh' en français (son guttural)",
        "i": "1) Comme le 'i' de 'papie' 2) comme le 'e' de 'yeux' en français (uniquement après consonne z, c, s, zh, ch, sh, r)",
        "o": "Comme le 'o' français",
        "u": "Comme le 'ou' de 'loup' en français",
        "ü": "Comme le 'u' de 'lune' en français",
        "ai": "Comme le 'aï' de 'aille' en français",
        "ei": "Comme le 'ei' de 'la tienne' en français",
        "ao": "Comme le 'ow' de 'now' en anglais",
        "ou": "Comme le 'o' de 'so ?' en anglais",
        "ia": "Comme le 'ya' de 'kayak' en français",
        "ie": "Comme le 'ye' de 'yéyé' en français",
        "iao": "Comme un 'i' + le 'ao' de 'now' en anglais",
        "iou": "Comme le 'yo' de 'yoyo' en français",
        "ua": "Comme le 'ou' de 'loup' + un 'a'",
        "uo": "Comme le 'ou' de 'loup' + un 'o'",
        "uai": "Comme 'why' en anglais",
        "uei": "Comme le 'ouais' en français",
        "üe": "Comme le 'ue' de 'huée' en français",
        "an": "Comme le 'an' de 'Âne' en français sans trop insister sur le 'n'",
        "en": "Comme le 'en' de 'Gène' en français sans trop insister sur le 'n'",
        "eng": "Comme le 'en' de 'taken' en anglais en rajoutant un 'g'",
        "ang": "Comme dans 'langue' sans trop insister sur le 'g'",
        "ong": "Comme le 'ongue' de 'tongue' en français sans trop insister sur le 'g'",
        "ian": "Comme le 'ien' de 'la tienne' en français sans trop insister sur le 'n'",
        "iang": "Comme dans 'langue' en français sans trop insister sur le 'g'",
        "in": "Comme le 'in' de 'mine' en français sans trop insister sur le 'n'",
        "ing": "Comme le 'ing' de 'camping' avec moins d'insistance sur le 'g'",
        "iong": "Comme le 'ongue' de 'tongue' sans trop insister sur le 'g'",
        "uan": "Comme le 'ouan' de 'Douane' en français sans trop insister sur le 'n'",
        "uang": "Combinaison du son 'ou' français et de 'ang' de 'langue' sans trop insister sur le 'g'",
        "uen": "Combinaison du 'ou' français et de 'ène' de 'Gène'",
        "üan": "Combinaison du 'u' français et de 'Âne'",
        "üen": "Comme dans 'une' en français sans trop insister sur le 'n'"
    };

    const suffixEquivalences = {
        "ya": "ia", "ye": "ie", "yao": "iao", "you": "iou",
        "yan": "ian", "yang": "iang", "yin": "in", "ying": "ing", "yong": "iong",
        "wa": "ua", "wo": "uo", "wai": "uai", "wei": "uei",
        "wan": "uan", "wang": "uang", "wen": "uen", "weng": "ong",
        "yue": "üe", "yuan": "üan", "yun": "üen",
        "iu": "iou", "ui": "uei", "un": "uen"
    };

    // Fonction pour retirer les tons et garder le pinyin pur (préserve le ü)
    function stripTones(pinyinStr) {
        const toneMap = {
            'ā':'a', 'á':'a', 'ǎ':'a', 'à':'a',
            'ē':'e', 'é':'e', 'ě':'e', 'è':'e',
            'ī':'i', 'í':'i', 'ǐ':'i', 'ì':'i',
            'ō':'o', 'ó':'o', 'ǒ':'o', 'ò':'o',
            'ū':'u', 'ú':'u', 'ǔ':'u', 'ù':'u',
            'ǖ':'ü', 'ǘ':'ü', 'ǚ':'ü', 'ǜ':'ü',
            'v':'ü' // Support basique si tapé avec v
        };
        return pinyinStr.replace(/[āáǎàēéěèīíǐìōóǒòūúǔùǖǘǚǜv]/gi, match => toneMap[match.toLowerCase()] || match)
                        .replace(/[0-9]/g, "")
                        .toLowerCase().trim();
    }

    function getPinyinPronunciation(pinyinInput) {
        let pinyin = stripTones(pinyinInput);
        let prefix = "";
        let suffix = "";

        if (pinyin.length >= 2 && pinyinPrefixes[pinyin.substring(0, 2)]) {
            prefix = pinyin.substring(0, 2);
            suffix = pinyin.substring(2);
        } else if (pinyinPrefixes[pinyin.substring(0, 1)]) {
            prefix = pinyin.substring(0, 1);
            suffix = pinyin.substring(1);
        } else {
            suffix = pinyin;
        }

        const normalizedSuffix = suffixEquivalences[suffix] || suffix;
        const prefixExplanation = prefix ? pinyinPrefixes[prefix] : "Syllabe autonome";
        const suffixExplanation = pinyinSuffixes[normalizedSuffix] || "Introuvable";

        return { prefix, suffix, normalizedSuffix, prefixExplanation, suffixExplanation };
    }

    // Injection de la prononciation dans le HTML
    const pronContainer = document.getElementById('zh-pronunciation-container');
    if (pronContainer && rawPinyin) {
        const pronData = getPinyinPronunciation(rawPinyin);
        let pronHTML = '';
        
        if (pronData.prefix) {
            pronHTML += `
                <div class="zh-pron-part">
                    <span class="zh-pron-badge">${pronData.prefix}</span>
                    <span class="zh-pron-text">${pronData.prefixExplanation}</span>
                </div>
            `;
        }
        
        if (pronData.suffix) {
            // Affichage du suffixe brut puis normalisé si différent (ex: un -> uen)
            const displaySuffix = pronData.suffix === pronData.normalizedSuffix 
                ? pronData.suffix 
                : `${pronData.suffix} (${pronData.normalizedSuffix})`;

            pronHTML += `
                <div class="zh-pron-part">
                    <span class="zh-pron-badge">${displaySuffix}</span>
                    <span class="zh-pron-text">${pronData.suffixExplanation}</span>
                </div>
            `;
        }
        pronContainer.innerHTML = pronHTML || `<span class="zh-pron-text">Données de prononciation indisponibles.</span>`;
    }

    // 3. GESTION DE LA FRÉQUENCE D'APPARITION
    const tiers = [
        { name: "Commun", min: 0, max: 40, color: 'var(--freq-commun)', chars: [] },
        { name: "Non commun", min: 40, max: 60, color: 'var(--freq-non-commun)', chars: [] },
        { name: "Rare", min: 60, max: 90, color: 'var(--freq-rare)', chars: [] },
        { name: "Très rare", min: 90, max: 100.1, color: 'var(--freq-tres-rare)', chars: [] }
    ];

    rawSimp.forEach((char, i) => {
        const c = char.trim();
        if (!c) return;
        const f = parseFloat(rawFreq[i]) || 99;
        const tier = tiers.find(t => f >= t.min && f < t.max);
        if (tier) {
            tier.chars.push({
                h: useTraditional ? (rawTrad[i]?.trim() || c) : c,
                hsk: rawHSK[i] ? rawHSK[i].trim() : ""
            });
        }
    });

    const freqContainer = document.getElementById('zh-freq-container');
    if(freqContainer) {
        tiers.forEach(t => {
            if (t.chars.length === 0) return;
            const charItems = t.chars.map(item => `
                <div class="zh-pinyin-char-box">
                    <span class="zh-pinyin-hanzi-text">${item.h}</span>
                    ${item.hsk ? `<span class="zh-pinyin-hsk-badge">HSK ${item.hsk}</span>` : ''}
                </div>
            `).join('');

            freqContainer.innerHTML += `
                <div class="zh-pinyin-freq-row">
                    <div class="zh-pinyin-freq-side" style="color: ${t.color}">
                        <div class="zh-pinyin-freq-text">${t.name}</div>
                    </div>
                    <div class="zh-pinyin-char-grid">${charItems}</div>
                </div>
            `;
        });
    }
})();
</script>

Et pour le style :

:root {
    --theme-color: #3395ea;
    --tone-1: #dc2626; --tone-2: #16a34a; --tone-3: #2563eb; --tone-4: #9333ea; --tone-5: #525252;
    --bg-dark: #1a1a1a;
    --card-bg: #262626;
    --text-main: #ffffff;
    --text-dim: #a3a3a3;
    /* Couleurs Fréquences */
    --freq-commun: #16a34a; 
    --freq-non-commun: #eab308; 
    --freq-rare: #f97316; 
    --freq-tres-rare: #dc2626; 
}

/* Application ciblée du box-sizing pour éviter d'influencer AnkiWeb */
.zh-pinyin-container, .zh-pinyin-container *, .zh-pinyin-container *::before, .zh-pinyin-container *::after {
    box-sizing: border-box;
}

/* On stylise le fond de la carte sans toucher au body d'AnkiWeb */
.card {
    background-color: var(--bg-dark);
    margin: 0;
    padding: 0;
    display: flex;
    justify-content: center;
}

.zh-pinyin-container {
    width: 100%;
    max-width: 680px;
    background: var(--card-bg);
    border-radius: 20px;
    padding: 25px 20px;
    box-shadow: 0 10px 25px rgba(0,0,0,0.3);
    text-align: center;
    overflow: hidden;
    color: var(--text-main);
    font-family: 'Lexend', sans-serif;
    -webkit-font-smoothing: antialiased;
    margin: 15px auto;
}

.zh-pinyin-title {
    color: var(--theme-color);
    font-family: 'Reggae One', cursive;
    font-size: 1.2rem;
    text-transform: uppercase;
    margin-bottom: 20px;
    letter-spacing: 2px;
}

/* INPUT SECTION (RECTO) */
.zh-pinyin-input-wrap { 
    margin-top: 20px; 
}

.zh-pinyin-container input {
    width: 100%; 
    outline: none; 
    font-size: 1.3rem; 
    padding: 15px;
    border-radius: 12px; 
    border: 2px solid var(--text-dim); 
    background: transparent;
    color: white; 
    text-align: center; 
    transition: all 0.2s;
    font-family: 'Lexend', sans-serif;
}

.zh-pinyin-container input:focus { border-color: var(--theme-color); }
.zh-pinyin-container input.zh-correct { border-color: var(--freq-commun); box-shadow: 0 0 15px rgba(22, 163, 74, 0.3); }
.zh-pinyin-container input.zh-wrong { border-color: var(--freq-tres-rare); box-shadow: 0 0 15px rgba(220, 38, 38, 0.3); }

.zh-pinyin-hint {
    font-size: 0.8rem;
    color: var(--text-dim);
    margin-top: 10px;
}

/* VERSO : PINYIN & AUDIO */
.zh-pinyin-audio-wrap { 
    margin-bottom: 15px; 
}

.zh-pinyin-audio-wrap a { 
    filter: saturate(0) invert(1); 
    display: inline-block;
    transform: scale(1.2);
}

.zh-pinyin-text-main { 
    font-size: clamp(2.5rem, 8vw, 3.5rem);
    font-weight: bold; 
    margin: 10px 0; 
}

/* Label de section Pinyin/Fréquence */
.zh-pinyin-section-title {
    font-family: 'Reggae One', cursive;
    color: var(--theme-color);
    font-size: 0.85rem;
    text-transform: uppercase;
    margin: 30px 0 10px 0;
    display: block;
    text-align: left;
    letter-spacing: 1px;
    opacity: 0.9;
    border-bottom: 1px solid var(--theme-color);
    padding-bottom: 5px;
}

/* NOUVEAUX STYLES PRONONCIATION */
.zh-pronunciation-box {
    background: rgba(0,0,0,0.25);
    border-radius: 12px;
    padding: 15px;
    margin-bottom: 20px;
    text-align: left;
    font-size: 0.9rem;
    line-height: 1.5;
    display: flex;
    flex-direction: column;
    gap: 12px;
    border: 1px solid rgba(255,255,255,0.05);
}

.zh-pron-part {
    display: flex;
    gap: 12px;
    align-items: flex-start;
}

.zh-pron-badge {
    background: rgba(51, 149, 234, 0.15);
    color: var(--theme-color);
    border: 1px solid rgba(51, 149, 234, 0.3);
    padding: 3px 8px;
    border-radius: 6px;
    font-weight: bold;
    font-family: 'Lexend', sans-serif;
    min-width: 40px;
    text-align: center;
    flex-shrink: 0;
}

.zh-pron-text {
    color: var(--text-dim);
    margin-top: 2px;
}

/* GRILLE DE FREQUENCE COMPACTE */
.zh-pinyin-freq-row {
    display: flex;
    margin-top: 15px;
    background: rgba(0,0,0,0.25);
    border-radius: 12px;
    overflow: hidden;
    min-height: 60px;
    width: 100%;
}

.zh-pinyin-freq-side {
    flex-shrink: 0;
    width: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255,255,255,0.05);
    border-right: 1px solid rgba(255,255,255,0.1);
}

.zh-pinyin-freq-text {
    writing-mode: vertical-rl;
    transform: rotate(180deg);
    font-size: 0.65rem;
    font-weight: bold;
    text-transform: uppercase;
    letter-spacing: 1px;
}

.zh-pinyin-char-grid {
    flex: 1;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 12px;
    align-content: center;
    justify-content: flex-start;
}

.zh-pinyin-char-box {
    background: #1a1a1a;
    padding: 4px 10px;
    border-radius: 8px;
    display: flex;
    align-items: center;
    gap: 6px;
    border: 1px solid rgba(255,255,255,0.05);
}

.zh-pinyin-hanzi-text { font-size: 1.4rem; font-family: "Microsoft YaHei", sans-serif; }

.zh-pinyin-hsk-badge {
    font-size: 0.6rem;
    background: var(--theme-color);
    color: white;
    padding: 2px 5px;
    border-radius: 4px;
    font-weight: bold;
    white-space: nowrap;
}

/* RESPONSIVE MOBILE */
@media (max-width: 450px) {
    .zh-pinyin-container { padding: 15px; }
    .zh-pinyin-text-main { font-size: 2.5rem; }
    .zh-pinyin-char-grid { gap: 6px; padding: 10px; }
    .zh-pinyin-hanzi-text { font-size: 1.2rem; }
    .zh-pinyin-freq-side { width: 32px; }
    .zh-pinyin-freq-text { font-size: 0.55rem; }
}

Belle journée !
Au plaisir,
Jonathan

1 « J'aime »