Add 13 new grammar notes with 1010 exercises from video extraction
Scraped a 4h Spanish fundamentals YouTube video (transcript + OCR on 14810 frames), extracted structured content across 52 chapters, and generated fill-in-the-blank quizzes for every grammar topic. - 13 new GrammarNote entries (articles, possessives, demonstratives, greetings, poder, al/del, prepositional pronouns, irregular yo, stem-changing, stressed possessives, present/future perfect, present indicative conjugation) - 1010 generated exercises across all 36 grammar notes (new + existing) - Fix tense guide parser to handle unnumbered *Usages* blocks - Rewrite 6 broken tense guide bodies (imperative, subj pluperfect, subj future) with numbered usage format - Bump courseDataVersion 5→6 with TenseGuide refresh on upgrade - Add docs/spanish-fundamentals/ with raw transcripts, polished notes, structured JSON, and exercise data Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1274,4 +1274,445 @@ struct GrammarNote: Identifiable {
|
||||
**Tip:** Use the Irregularity Drills in the Practice tab to focus on each type separately — spelling changes, stem changes, or unique irregulars.
|
||||
"""
|
||||
)
|
||||
|
||||
// MARK: - BEGIN generated notes (do not edit — regenerate via scrape/work/generate_swift.py)
|
||||
|
||||
static let generatedNotes: [GrammarNote] = [
|
||||
GrammarNote(
|
||||
id: "present-indicative-conjugation",
|
||||
title: "Present Indicative Conjugation",
|
||||
category: "Core Concepts",
|
||||
body: """
|
||||
The present indicative describes what someone **does** or **is doing** right now, habitually, or as a general truth. To conjugate a regular verb, drop the infinitive ending (-ar, -er, -ir) and add the person-ending that matches the subject.
|
||||
|
||||
**-ar verbs** (hablar — to speak):
|
||||
*hablo, hablas, habla, hablamos, habláis, hablan*
|
||||
|
||||
**-er verbs** (comer — to eat):
|
||||
*como, comes, come, comemos, coméis, comen*
|
||||
|
||||
**-ir verbs** (vivir — to live):
|
||||
*vivo, vives, vive, vivimos, vivís, viven*
|
||||
|
||||
Notice -er and -ir verbs share the same endings EXCEPT in the nosotros and vosotros forms (-emos/-éis vs -imos/-ís).
|
||||
|
||||
*Yo hablo español todos los días.* — I speak Spanish every day.
|
||||
*¿Tú comes carne?* — Do you eat meat?
|
||||
*Ellos viven en Madrid.* — They live in Madrid.
|
||||
|
||||
**Key tip:** Since the verb ending already tells you the subject, Spanish often drops subject pronouns: *Hablo español* already means *I speak Spanish.*
|
||||
"""
|
||||
),
|
||||
GrammarNote(
|
||||
id: "articles-and-gender",
|
||||
title: "Articles & Gender",
|
||||
category: "Core Concepts",
|
||||
body: """
|
||||
Every Spanish noun has a grammatical gender (masculine or feminine) and a number (singular or plural). The article must agree with both.
|
||||
|
||||
**Definite articles** (the):
|
||||
*el* (m. sing.), *la* (f. sing.), *los* (m. pl.), *las* (f. pl.)
|
||||
|
||||
**Indefinite articles** (a/an/some):
|
||||
*un* (m. sing.), *una* (f. sing.), *unos* (m. pl.), *unas* (f. pl.)
|
||||
|
||||
*el libro / los libros* — the book(s)
|
||||
*la mesa / las mesas* — the table(s)
|
||||
*un amigo / unos amigos* — a friend / some friends
|
||||
|
||||
**General rules:**
|
||||
- Nouns ending in -o are usually masculine: *el carro, el vino.*
|
||||
- Nouns ending in -a are usually feminine: *la casa, la silla.*
|
||||
- Nouns ending in -ción, -sión, -dad, -tad are feminine: *la canción, la ciudad.*
|
||||
- Nouns ending in -ma, -pa, -ta from Greek are often masculine: *el problema, el mapa, el planeta.*
|
||||
|
||||
**Common exceptions to memorize:**
|
||||
*la mano, la foto, la moto, la radio* (feminine but end in -o)
|
||||
*el día, el clima, el tema, el idioma, el sofá* (masculine but end in -a)
|
||||
|
||||
**Tip:** Always learn a new noun together with its article — *la mano*, not just *mano*.
|
||||
"""
|
||||
),
|
||||
GrammarNote(
|
||||
id: "possessive-adjectives",
|
||||
title: "Possessive Adjectives",
|
||||
category: "Adjectives",
|
||||
body: """
|
||||
Spanish possessive adjectives go **before** the noun and agree in number with the item possessed (not with the possessor). Only *nuestro* and *vuestro* also agree in gender.
|
||||
|
||||
| | Singular | Plural |
|
||||
|---|---|---|
|
||||
| my | mi | mis |
|
||||
| your (tú) | tu | tus |
|
||||
| his/her/your(Ud.) | su | sus |
|
||||
| our | nuestro/a | nuestros/as |
|
||||
| your (vosotros) | vuestro/a | vuestros/as |
|
||||
| their/your(Uds.) | su | sus |
|
||||
|
||||
*mi libro / mis libros* — my book(s)
|
||||
*tu casa / tus casas* — your house(s)
|
||||
*nuestra familia / nuestros amigos* — our family / our friends
|
||||
|
||||
**Note:** *tu* (your) has no accent; *tú* (you) does.
|
||||
|
||||
**Ambiguity of *su*:** *su* can mean his, her, its, your (Ud./Uds.), or their. Context or *de + pronoun* clarifies: *la casa de él* (his house), *la casa de ella* (her house).
|
||||
|
||||
*Su coche es rojo* — His / Her / Their / Your car is red.
|
||||
*El coche de ella es rojo.* — Her car is red.
|
||||
"""
|
||||
),
|
||||
GrammarNote(
|
||||
id: "demonstrative-adjectives",
|
||||
title: "Demonstrative Adjectives",
|
||||
category: "Adjectives",
|
||||
body: """
|
||||
Demonstratives point to something and agree with the noun in gender and number. Spanish has three levels of distance:
|
||||
|
||||
**este/esta/estos/estas** — this/these (near the speaker)
|
||||
**ese/esa/esos/esas** — that/those (near the listener)
|
||||
**aquel/aquella/aquellos/aquellas** — that/those over there (far from both)
|
||||
|
||||
*este libro* — this book
|
||||
*esta mesa* — this table
|
||||
*esos zapatos* — those shoes (near you)
|
||||
*aquellas montañas* — those mountains (in the distance)
|
||||
|
||||
**Neuter pronouns** — use *esto, eso, aquello* when pointing to something unidentified or to an abstract idea. They don't change form.
|
||||
|
||||
*¿Qué es esto?* — What is this?
|
||||
*Eso no me gusta.* — I don't like that.
|
||||
*Aquello fue un desastre.* — That was a disaster.
|
||||
|
||||
**Tip:** *este/ese/aquel* follow the distance triangle — speaker → listener → beyond. The *-ese* forms (ese/esos) sit in the middle.
|
||||
"""
|
||||
),
|
||||
GrammarNote(
|
||||
id: "greetings-farewells",
|
||||
title: "Greetings & Farewells",
|
||||
category: "Core Concepts",
|
||||
body: """
|
||||
Spanish greetings are highly time-of-day aware. Using the wrong one sounds jarring.
|
||||
|
||||
**Greetings**
|
||||
*hola* — hi (anytime)
|
||||
*buenos días* — good morning (until ~noon)
|
||||
*buenas tardes* — good afternoon (noon until sunset)
|
||||
*buenas noches* — good evening / good night (after dark, also used when leaving)
|
||||
|
||||
**Common questions**
|
||||
*¿cómo estás?* — how are you? (tú)
|
||||
*¿cómo está usted?* — how are you? (formal)
|
||||
*¿qué tal?* — what's up?
|
||||
*¿qué hay?* — what's new?
|
||||
*¿cómo te va?* — how's it going?
|
||||
|
||||
**Responses**
|
||||
*bien, gracias* — fine, thanks
|
||||
*muy bien* — very well
|
||||
*más o menos* — so-so
|
||||
*todo bien* — all good
|
||||
|
||||
**Introductions**
|
||||
*mucho gusto* — nice to meet you
|
||||
*encantado / encantada* — delighted (m./f.)
|
||||
*igualmente* — likewise
|
||||
|
||||
**Farewells**
|
||||
*adiós* — goodbye
|
||||
*hasta luego* — see you later
|
||||
*hasta pronto* — see you soon
|
||||
*hasta mañana* — see you tomorrow
|
||||
*nos vemos* — see you (around)
|
||||
*chau / chao* — bye (informal)
|
||||
|
||||
**Tip:** *buenas noches* works for both *good evening* (hello) and *good night* (goodbye) — context tells which.
|
||||
"""
|
||||
),
|
||||
GrammarNote(
|
||||
id: "poder-infinitive",
|
||||
title: "Poder + Infinitive",
|
||||
category: "Irregular Verbs",
|
||||
body: """
|
||||
*Poder* means "to be able to / can" and is one of the most-used verbs in Spanish. It's an o→ue stem-changer in the present tense (all forms except nosotros and vosotros) and takes an infinitive directly — no preposition.
|
||||
|
||||
**Present indicative:**
|
||||
*puedo, puedes, puede, podemos, podéis, pueden*
|
||||
|
||||
**Preterite (irregular stem pud-):**
|
||||
*pude, pudiste, pudo, pudimos, pudisteis, pudieron*
|
||||
|
||||
**Future / Conditional stem:** *podr-*
|
||||
*podré, podrás, podrá...* (future)
|
||||
*podría, podrías, podría...* (conditional — often softens a request)
|
||||
|
||||
*Puedo hablar tres idiomas.* — I can speak three languages.
|
||||
*¿Puedes ayudarme?* — Can you help me?
|
||||
*No pudimos ir al concierto.* — We couldn't go to the concert.
|
||||
*¿Podrías pasar la sal?* — Could you pass the salt? (polite request)
|
||||
|
||||
**Pattern:** poder + infinitive. Never *poder a* or *poder de*.
|
||||
|
||||
**Nuance:** The preterite *pude* often carries the meaning "managed to / succeeded in"; *no pude* means "I failed to / couldn't."
|
||||
"""
|
||||
),
|
||||
GrammarNote(
|
||||
id: "al-del-contractions",
|
||||
title: "al & del Contractions",
|
||||
category: "Core Concepts",
|
||||
body: """
|
||||
Spanish has only **two mandatory contractions**, and they both collapse the redundant vowel between a preposition and the article *el*.
|
||||
|
||||
**a + el = al** (to the)
|
||||
**de + el = del** (of the / from the)
|
||||
|
||||
*Voy al mercado.* — I'm going to the market. (NOT *a el*)
|
||||
*La puerta del coche está abierta.* — The door of the car is open. (NOT *de el*)
|
||||
|
||||
No other preposition + article pair contracts:
|
||||
*en el parque, por el camino, con el amigo* — all uncontracted.
|
||||
|
||||
None of the other articles contract either:
|
||||
*a la escuela, a los niños, a las chicas, de la casa, de los libros* — all separate.
|
||||
|
||||
**Exception — proper names:** Don't contract with *Él* (the pronoun *he*) or when *El* is part of a name (*El Salvador*, *El Paso*).
|
||||
|
||||
*Le doy el regalo a él.* — I give the gift to him. (NOT *al*)
|
||||
*Vuelvo de El Salvador.* — I'm coming back from El Salvador. (NOT *del*)
|
||||
|
||||
**Tip:** Think of al/del as a pronunciation shortcut — Spanish hates two vowels smashed together (a-el, de-el).
|
||||
"""
|
||||
),
|
||||
GrammarNote(
|
||||
id: "prepositional-pronouns",
|
||||
title: "Prepositional Pronouns",
|
||||
category: "Pronouns",
|
||||
body: """
|
||||
After most prepositions (a, de, en, para, por, sin, sobre, etc.) Spanish uses a special set of object-of-preposition pronouns. Only *yo* and *tú* change form.
|
||||
|
||||
| Subject | After preposition |
|
||||
|---|---|
|
||||
| yo | **mí** |
|
||||
| tú | **ti** |
|
||||
| él / ella / usted | él / ella / usted |
|
||||
| nosotros/as | nosotros/as |
|
||||
| vosotros/as | vosotros/as |
|
||||
| ellos/as / ustedes | ellos/as / ustedes |
|
||||
|
||||
*Este regalo es para mí.* — This gift is for me.
|
||||
*No puedo ir sin ti.* — I can't go without you.
|
||||
*Hablan de nosotros.* — They're talking about us.
|
||||
*Pienso en ella.* — I'm thinking about her.
|
||||
|
||||
**Note the accent:** *mí* (me) has an accent, *mi* (my) doesn't. *ti* never has an accent.
|
||||
|
||||
**Special: con + mí/ti**
|
||||
The preposition *con* fuses with *mí* and *ti* into single words:
|
||||
*conmigo* — with me
|
||||
*contigo* — with you
|
||||
*consigo* — with himself/herself/yourself (reflexive, less common)
|
||||
|
||||
*¿Quieres venir conmigo?* — Do you want to come with me?
|
||||
*Iré contigo.* — I'll go with you.
|
||||
|
||||
**Exceptions:** After *entre, según, incluso, excepto, menos* use subject pronouns: *entre tú y yo* — between you and me.
|
||||
"""
|
||||
),
|
||||
GrammarNote(
|
||||
id: "irregular-yo-verbs",
|
||||
title: "Irregular Yo Verbs",
|
||||
category: "Irregular Verbs",
|
||||
body: """
|
||||
A group of Spanish verbs conjugates regularly in every present-tense form **except yo**, which takes a special irregular ending. Once you learn these yo forms, the rest of the conjugation behaves normally.
|
||||
|
||||
**-go endings (very common):**
|
||||
*hacer → hago* (I do/make)
|
||||
*poner → pongo* (I put)
|
||||
*salir → salgo* (I leave)
|
||||
*tener → tengo* (I have) — also stem-changes in tú/él forms
|
||||
*venir → vengo* (I come) — also stem-changes
|
||||
*decir → digo* (I say) — also stem-changes
|
||||
*traer → traigo* (I bring)
|
||||
*oír → oigo* (I hear)
|
||||
*caer → caigo* (I fall)
|
||||
|
||||
**-zco endings** (verbs ending in -cer or -cir after a vowel):
|
||||
*conocer → conozco* (I know)
|
||||
*conducir → conduzco* (I drive)
|
||||
*traducir → traduzco* (I translate)
|
||||
*ofrecer → ofrezco* (I offer)
|
||||
*parecer → parezco* (I seem)
|
||||
|
||||
**-oy endings:**
|
||||
*dar → doy* (I give)
|
||||
*estar → estoy* (I am)
|
||||
*ir → voy* (I go)
|
||||
*ser → soy* (I am)
|
||||
|
||||
**Standalone irregulars:**
|
||||
*ver → veo* (I see)
|
||||
*saber → sé* (I know — has an accent)
|
||||
*caber → quepo* (I fit)
|
||||
|
||||
*Yo tengo dos hermanos.* — I have two brothers.
|
||||
*Hago la tarea cada día.* — I do homework every day.
|
||||
*Conozco a tu padre.* — I know your father.
|
||||
"""
|
||||
),
|
||||
GrammarNote(
|
||||
id: "stem-changing-verbs",
|
||||
title: "Stem-Changing Verbs",
|
||||
category: "Irregular Verbs",
|
||||
body: """
|
||||
Stem-changing verbs modify the vowel inside their stem in **all present-tense forms except nosotros and vosotros**. The affected forms map out like a boot on a conjugation chart — hence *boot verbs*.
|
||||
|
||||
**Four categories:**
|
||||
|
||||
**1. e → ie** (pensar — to think):
|
||||
*pienso, piensas, piensa, pensamos, pensáis, piensan*
|
||||
Also: cerrar, empezar, querer, entender, preferir, sentir.
|
||||
|
||||
**2. o → ue** (poder — to be able):
|
||||
*puedo, puedes, puede, podemos, podéis, pueden*
|
||||
Also: dormir, contar, volver, encontrar, recordar, morir.
|
||||
|
||||
**3. e → i** (only -ir verbs) (pedir — to ask for):
|
||||
*pido, pides, pide, pedimos, pedís, piden*
|
||||
Also: servir, repetir, seguir, vestirse.
|
||||
|
||||
**4. u → ue** (*jugar* — to play — the ONLY one):
|
||||
*juego, juegas, juega, jugamos, jugáis, juegan*
|
||||
|
||||
**Why nosotros/vosotros are spared:** the stress falls on the ending in those forms, so the stem vowel stays unstressed and unchanged.
|
||||
|
||||
*Yo quiero un café.* — I want a coffee.
|
||||
*Nosotros queremos café.* — We want coffee. (no change)
|
||||
*Ella duerme ocho horas.* — She sleeps eight hours.
|
||||
*Nosotros dormimos poco.* — We sleep little. (no change)
|
||||
*Pido la cuenta.* — I ask for the check.
|
||||
|
||||
**Tip:** Stem changes carry through into the present subjunctive and sometimes affect the gerund (*durmiendo, pidiendo*) and 3rd-person preterite (*durmió, pidió*) — but only for -ir verbs.
|
||||
"""
|
||||
),
|
||||
GrammarNote(
|
||||
id: "stressed-possessives",
|
||||
title: "Stressed Possessive Adjectives",
|
||||
category: "Adjectives",
|
||||
body: """
|
||||
Stressed possessives are the "long-form" possessives used for emphasis, after the noun, or after *ser*. Unlike the short forms (mi, tu, su…), they agree in BOTH gender and number with the item possessed.
|
||||
|
||||
| | Singular m. / f. | Plural m. / f. |
|
||||
|---|---|---|
|
||||
| mine | mío / mía | míos / mías |
|
||||
| yours (tú) | tuyo / tuya | tuyos / tuyas |
|
||||
| his/hers/yours (Ud.) | suyo / suya | suyos / suyas |
|
||||
| ours | nuestro / nuestra | nuestros / nuestras |
|
||||
| yours (vosotros) | vuestro / vuestra | vuestros / vuestras |
|
||||
| theirs/yours (Uds.) | suyo / suya | suyos / suyas |
|
||||
|
||||
**Used three ways:**
|
||||
|
||||
1. **After a noun** (emphatic, often with *un/una*):
|
||||
*un amigo mío* — a friend of mine
|
||||
*una idea tuya* — an idea of yours
|
||||
*unos primos nuestros* — some cousins of ours
|
||||
|
||||
2. **After ser** (ownership):
|
||||
*El libro es mío.* — The book is mine.
|
||||
*Esta casa es nuestra.* — This house is ours.
|
||||
*¿Son tuyas estas llaves?* — Are these keys yours?
|
||||
|
||||
3. **As a pronoun** with *el / la / los / las*:
|
||||
*Mi coche es rojo; el tuyo es azul.* — My car is red; yours is blue.
|
||||
*Tus hijos y los míos juegan juntos.* — Your kids and mine play together.
|
||||
|
||||
**Ambiguity of *suyo***: Like short *su*, stressed *suyo/a* can mean his, hers, yours (Ud./Uds.), or theirs. Use *de él / de ella* if ambiguous.
|
||||
"""
|
||||
),
|
||||
GrammarNote(
|
||||
id: "present-perfect-tense",
|
||||
title: "Present Perfect",
|
||||
category: "Verb Tenses",
|
||||
body: """
|
||||
The present perfect (*pretérito perfecto*) describes what someone **has done** — an action completed in the recent past or within an unfinished time frame that extends to now (today, this week, this year, ever).
|
||||
|
||||
**Formula:** *haber* (present) + past participle
|
||||
|
||||
| | haber |
|
||||
|---|---|
|
||||
| yo | he |
|
||||
| tú | has |
|
||||
| él/ella/Ud. | ha |
|
||||
| nosotros | hemos |
|
||||
| vosotros | habéis |
|
||||
| ellos/Uds. | han |
|
||||
|
||||
**Regular participles:**
|
||||
-ar verbs → -ado: *hablar → hablado*
|
||||
-er/-ir verbs → -ido: *comer → comido, vivir → vivido*
|
||||
|
||||
**Common irregular participles:**
|
||||
*abrir → abierto* (opened)
|
||||
*decir → dicho* (said)
|
||||
*escribir → escrito* (written)
|
||||
*hacer → hecho* (done/made)
|
||||
*morir → muerto* (died)
|
||||
*poner → puesto* (put)
|
||||
*romper → roto* (broken)
|
||||
*ver → visto* (seen)
|
||||
*volver → vuelto* (returned)
|
||||
*cubrir → cubierto* (covered)
|
||||
*resolver → resuelto* (solved)
|
||||
|
||||
*He comido demasiado hoy.* — I have eaten too much today.
|
||||
*¿Has visto la nueva película?* — Have you seen the new movie?
|
||||
*Todavía no han llegado.* — They haven't arrived yet.
|
||||
*Este año hemos viajado mucho.* — This year we've traveled a lot.
|
||||
|
||||
**Key rule:** *Haber* and the participle must stay together. Never put a pronoun between them: *Lo he comido*, NOT *He lo comido*.
|
||||
|
||||
**Tip:** The participle never changes in this tense — always ends in -o. (It only agrees in gender/number when used as an adjective with *ser/estar*.)
|
||||
"""
|
||||
),
|
||||
GrammarNote(
|
||||
id: "future-perfect-tense",
|
||||
title: "Future Perfect",
|
||||
category: "Verb Tenses",
|
||||
body: """
|
||||
The future perfect (*futuro perfecto*) describes what **will have happened** by some point in the future. It's also used to speculate about the recent past ("they must have…").
|
||||
|
||||
**Formula:** *haber* (future) + past participle
|
||||
|
||||
| | haber |
|
||||
|---|---|
|
||||
| yo | habré |
|
||||
| tú | habrás |
|
||||
| él/ella/Ud. | habrá |
|
||||
| nosotros | habremos |
|
||||
| vosotros | habréis |
|
||||
| ellos/Uds. | habrán |
|
||||
|
||||
**Two main uses:**
|
||||
|
||||
1. **Will-have-happened before a future point:**
|
||||
*Para las ocho, habré terminado el trabajo.* — By eight, I will have finished the work.
|
||||
*Cuando lleguen, ya habremos cenado.* — By the time they arrive, we'll have eaten.
|
||||
*En un año, habrás aprendido mucho español.* — In a year, you'll have learned a lot of Spanish.
|
||||
|
||||
2. **Speculation / guess about recent past** (like English "must have…"):
|
||||
*Habrá olvidado la cita.* — He must have forgotten the appointment.
|
||||
*Se habrán ido ya.* — They must have left already.
|
||||
*¿Habrás dejado las llaves en casa?* — Could you have left the keys at home?
|
||||
|
||||
**Pattern reminder:** Same irregular participles as present perfect (dicho, hecho, visto, escrito, puesto, abierto, etc.).
|
||||
|
||||
**Tip:** When preceded by a time clause with *cuando/antes de que/para cuando*, Spanish usually puts a subjunctive in the time clause and future perfect in the main clause: *Cuando vengas, ya habré salido.*
|
||||
"""
|
||||
),
|
||||
]
|
||||
|
||||
/// Combined list used by the UI: 24 hand-authored notes + generated ones.
|
||||
static let allNotesIncludingGenerated: [GrammarNote] = allNotes + generatedNotes
|
||||
|
||||
// MARK: - END generated notes
|
||||
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import SharedModels
|
||||
import Foundation
|
||||
|
||||
actor DataLoader {
|
||||
static let courseDataVersion = 5
|
||||
static let courseDataVersion = 6
|
||||
static let courseDataKey = "courseDataVersion"
|
||||
|
||||
/// Quick check: does the DB need seeding or course data refresh?
|
||||
@@ -145,12 +145,29 @@ actor DataLoader {
|
||||
print("Course data version outdated — re-seeding...")
|
||||
let context = ModelContext(container)
|
||||
|
||||
// Delete existing course data
|
||||
// Delete existing course data + tense guides so they can be re-seeded
|
||||
// with updated bodies from the bundled conjuga_data.json.
|
||||
try? context.delete(model: VocabCard.self)
|
||||
try? context.delete(model: CourseDeck.self)
|
||||
try? context.delete(model: TenseGuide.self)
|
||||
try? context.save()
|
||||
|
||||
// Re-seed
|
||||
// Re-seed tense guides from the bundled JSON
|
||||
if let url = Bundle.main.url(forResource: "conjuga_data", withExtension: "json"),
|
||||
let data = try? Data(contentsOf: url),
|
||||
let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
|
||||
let guides = json["tenseGuides"] as? [[String: Any]] {
|
||||
for g in guides {
|
||||
guard let tenseId = g["tenseId"] as? String,
|
||||
let title = g["title"] as? String,
|
||||
let body = g["body"] as? String else { continue }
|
||||
context.insert(TenseGuide(tenseId: tenseId, title: title, body: body))
|
||||
}
|
||||
try? context.save()
|
||||
print("Re-seeded \(guides.count) tense guides")
|
||||
}
|
||||
|
||||
// Re-seed course data
|
||||
seedCourseData(context: context)
|
||||
|
||||
shared.set(courseDataVersion, forKey: courseDataKey)
|
||||
|
||||
@@ -19,9 +19,9 @@ struct GrammarNotesListView: View {
|
||||
@Binding var selectedNote: GrammarNote?
|
||||
|
||||
private var groupedNotes: [(String, [GrammarNote])] {
|
||||
let grouped = Dictionary(grouping: GrammarNote.allNotes, by: \.category)
|
||||
let grouped = Dictionary(grouping: GrammarNote.allNotesIncludingGenerated, by: \.category)
|
||||
var seen: [String] = []
|
||||
for note in GrammarNote.allNotes {
|
||||
for note in GrammarNote.allNotesIncludingGenerated {
|
||||
if !seen.contains(note.category) {
|
||||
seen.append(note.category)
|
||||
}
|
||||
|
||||
@@ -450,14 +450,17 @@ struct GuideContent {
|
||||
var spanishLine: String?
|
||||
|
||||
func flushUsage() {
|
||||
if currentUsageNumber > 0 {
|
||||
// Only emit a usage if it has at least one example. This suppresses
|
||||
// the implicit "Usage 1" seeded when we enter an unnumbered
|
||||
// *Usages* block but the body actually has numbered headers below.
|
||||
if currentUsageNumber > 0 && !currentExamples.isEmpty {
|
||||
usages.append(GuideUsage(
|
||||
number: currentUsageNumber,
|
||||
title: currentUsageTitle,
|
||||
examples: currentExamples
|
||||
))
|
||||
currentExamples = []
|
||||
}
|
||||
currentExamples = []
|
||||
}
|
||||
|
||||
for line in lines {
|
||||
@@ -491,6 +494,11 @@ struct GuideContent {
|
||||
let title = String(match.1).replacingOccurrences(of: "*", with: "")
|
||||
if title.lowercased().contains("usage") {
|
||||
inUsages = true
|
||||
// Seed an implicit Usage 1 so content that follows without a
|
||||
// numbered "*1 Title*" header still gets captured. Any numbered
|
||||
// header below will replace this via flushUsage().
|
||||
currentUsageNumber = 1
|
||||
currentUsageTitle = "Usage"
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user