為 AWS Manila Community Day 打造 Tagalog 卡片打造文法與發音補強流程
Tagalog 學習 App 已經有文章頁面與句子卡片。下一個開發挑戰是內容補強:替每個額外例句加入更好的文法拆解與發音指南,而且不要手動編輯數百個重複的 HTML 區塊。Python 展示了一個實用的批次處理模式。
此文章現在已發布於 AWS 官方 Builder Center。你可以前往官方文章,或關閉此視窗並留在此頁繼續閱讀。
Tagalog 學習 App 已經有文章頁面與句子卡片。下一個開發挑戰是內容補強:替每個額外例句加入更好的文法拆解與發音指南,而且不要手動編輯數百個重複的 HTML 區塊。Python 展示了一個實用的批次處理模式。
Tagalog 學習 App 已經有文章頁面與句子卡片。下一個開發挑戰是內容補強:替每個額外例句加入更好的文法拆解與發音指南,而且不要手動編輯數百個重複的 HTML 區塊。Python 展示了一個實用的批次處理模式。
目的:本專案是獨立的教育原型,用於語言學習、社群準備與技術分享。它的設計目標,是協助開發者在參加 AWS Manila Community Day 前練習簡單的 Tagalog。
非商業用途:本專案沒有商業模式、付費存取、廣告計畫、聯盟行銷方案或營利目標。它是為社群準備與開發者教育而建立的學習作品。
不保證正確性:App 可能使用生成式 AI 內容,因此翻譯、發音指南、文法說明與文化註解,在公開使用前都應由 Tagalog 母語者審閱。
範圍:目標不是打造完整的翻譯平台,而是示範如何用清楚的資料結構、可重複的產生邏輯與驗證檢查,將靜態學習網站在地化。
尊重社群:App 應避免刻板印象,並謹慎教導禮貌用語。像 po、opo、kayo、ninyo 這類詞,應被解釋為表達尊重的工具,而不是裝飾。
Paki-check po kung pumasok ang bayad.
逐字發音可以讀成:
pah-kee-chehk poh koong poo-mah-sohk ahng bah-yahd.
核心補強任務:
說明為什麼補強流程拆成多個腳本,而不是寫成一個巨大檔案。
說明腳本如何用字典條目提供初學者友善的文法意思與本地 loanword 解釋。
說明 pronunciation map、token 處理、母音 fallback 與初學者可讀的拆音輸出。
說明如何找到現有段落,並只替換特定標題後面的內容。
說明為什麼腳本要印出額外例句、發音句、local tip 與文法拆解的數量。
不用手動編輯每張卡片,也能改善 24 個文章頁的文法與發音內容。
關鍵技能是受控的批次處理。每個腳本負責一小組文章檔案,並搭配該主題專用的 glossary。
files = [
"article-22-manila-daily-home-laundry-bills-and-errands.html",
"article-23-manila-daily-work-study-and-social-plans.html",
"article-24-manila-daily-health-safety-weather-and-money.html",
]
這個模式比一個巨大腳本更容易審閱,因為每個批次都能帶有自己的主題詞彙。Community Day 頁面需要 registration、workshop、badge、volunteer。Manila Daily 頁面需要 laundry、delivery、battery、cash、clinic、medicine。
針對每個文章群組,更新所有 extra example。
保留既有 Tagalog 句子。
用初學者友善的詞義替換文法拆解。
用逐字發音替換發音指南。
寫出更新後的 HTML 檔案並印出摘要。
專案得到一個可重複的補強流程:
文章群組
-> 主題 glossary
-> 可見 Tagalog 句子
-> 文法清單
-> 發音指南
-> 更新後 HTML
-> sanity check
讓每個腳本成為小型、可檢查的語言輔助工具。
腳本使用 dictionary 作為本地知識庫。像 po 或 saan 這類詞會得到穩定的初學者說明;未知詞則會回退到通用的本地使用說明。
defs = {
"po": "Respect marker used for polite speech.",
"saan": "Means where.",
"workshop": "English loanword used locally; means workshop.",
"badge": "English loanword used locally; means badge.",
}
def get_def(word):
key = token_key(word)
if key in defs:
return defs[key]
return f'English loanword or useful word used locally; means "{word}" in this context.'
這不是完整文法解析器,但對靜態學習原型很實用。學習者會看到一致的詞義;開發者也能在需要改善意思時,只更新一個 dictionary entry。
句子:
Saan po ang registration area?
產生的文法拆解:
- Saan: Means where.
- po: Respect marker used for polite speech.
- ang: Focus marker placed before the main noun or idea.
- registration: English loanword used locally; means registration.
- area: English loanword or useful word used locally; means "area" in this context.
即使 pronunciation map 沒有涵蓋所有字,也要讓每個 extra example 有可讀的發音指南。
腳本結合兩種策略:
已知詞:
使用人工整理過的發音與可選音節拆解。
未知詞:
使用簡單母音 fallback,讓學習者仍有可讀的指南。
pron = {
"salamat": ("sah-lah-maht", [("sa", "sah"), ("la", "lah"), ("mat", "maht")]),
"kayo": ("kah-yoh", [("ka", "kah"), ("yo", "yoh")]),
"bayad": ("bah-yahd", [("ba", "bah"), ("yad", "yahd")]),
}
vmap = {"a": "ah", "e": "eh", "i": "ee", "o": "oh", "u": "oo"}
def fallback_pron(word):
output = []
for character in word.lower():
if character in vmap:
output.append(vmap[character])
elif character.isalpha():
output.append(character)
return "".join(output) or word
Tagalog:
Uminom po kayo ng tubig dahil mainit.
發音:
oo-mee-nohm poh kah-yoh ngah too-beeg dah-heel mah-ee-neet.
拆解:
- Uminom: oo-mee-nohm.
- po: poh.
- kayo: kah-yoh.
- tubig: too-beeg.
- dahil: dah-heel.
- mainit: mah-ee-neet.
不重寫整個文章頁,也能更新產生後的 HTML。
補強腳本用 BeautifulSoup 解析頁面,找到每個 div.extra-example,讀取 Tagalog span,並替換特定標題後面的內容。
for fname in files:
soup = BeautifulSoup(Path(fname).read_text(encoding="utf-8"), "html.parser")
divs = soup.find_all("div", class_="extra-example")
for div in divs:
span = div.find("span", lang="tl")
if not span:
continue
sentence = " ".join(span.get_text(" ", strip=True).split())
replace_after_heading(div, "Grammatical Breakdown:", [make_breakdown_ul(soup, sentence)])
replace_after_heading(div, "Pronunciation Guide:", make_pronunciation(soup, sentence))
replace_after_heading 很重要,因為它避免替換整張卡片,只移除某個標題到下一個已知標題之間的舊內容。
def replace_after_heading(div, heading_text, new_nodes):
heading = None
for candidate in div.find_all("p", recursive=False):
strong = candidate.find("strong")
if strong and heading_text in strong.get_text():
heading = candidate
break
if not heading:
return False
sibling = heading.find_next_sibling()
while sibling:
next_sibling = sibling.find_next_sibling()
if sibling.name == "p":
strong = sibling.find("strong")
if strong and "Pronunciation Guide:" in strong.get_text():
break
sibling.extract()
sibling = next_sibling
last = heading
for node in new_nodes:
last.insert_after(node)
last = node
return True
證明批次更新確實處理了預期內容。
腳本在寫檔後印出摘要列與 sanity check。
print("Update summary:")
for source, out, total, updated, missing in summary:
print(f"{source} -> {out}: extra_examples={total}, updated={updated}, missing={missing}")
print("Sanity check:")
for out in outputs:
soup = BeautifulSoup(Path(out).read_text(encoding="utf-8"), "html.parser")
divs = soup.find_all("div", class_="extra-example")
phrase = sum(1 for div in divs if "It is pronounced word by word as:" in div.get_text())
breakdown = sum(1 for div in divs if "Grammatical Breakdown:" in div.get_text())
print(f"{out}: extra_examples={len(divs)}, pron_phrase={phrase}, has_breakdown={breakdown}")
開發者可以把補強流程解釋成可量測的流程,而不是手動清理。
輸入:
article HTML files
轉換:
grammar and pronunciation regeneration
輸出:
updated HTML files
證據:
extra examples、pronunciation phrases、grammar breakdowns 的數量
背景:只有 phrase pair 很有用,但文法與發音會把它變成學習卡片。
目標:不改變句子卡版型,也能加入可重複的學習支援。
Prompt:從可見的 Tagalog 句子產生文法與發音。
結果:每個 extra example 對初學者更有幫助。
Review check:產生的輔助內容是否真的解釋卡片上的句子?
背景:一個腳本處理 24 篇文章會太大,也很難調整詞彙。
目標:讓每個批次貼近自己的詞彙領域。
Prompt:每個腳本只處理三個文章檔案。
結果:Community Day、Friendship、Manila Daily 內容都能有更貼切的本地 glossary。
Review check:審閱者能否從 file list 與註解理解詞彙範圍?
背景:發音 fallback 有用,但不是母語者保證。
目標:給學習者起點,同時保留審閱需求。
Prompt:已知詞用整理過的發音,需要時才用簡單 fallback。
結果:就算每個字還沒有完美發音條目,網站仍然可用。
Review check:重要活動短句是否有整理過,而不是只依賴 fallback?
對開發者分享來說,這個補強流程是很好的內容工程案例:
HTML article files
->
BeautifulSoup parser
->
extra-example blocks
->
Tagalog sentence extraction
->
glossary definitions
->
pronunciation map and fallback
->
section replacement
->
updated HTML files
->
sanity checks
重點很簡單:AI 輔助的學習內容仍然需要確定性的工具。小型腳本可以把產生出的頁面變成可審閱的教育材料。
文法與發音腳本展示了手動編輯與過度工程之間的實用中間點。專案不需要資料庫或語言引擎,也能改善每張卡片。它需要的是清楚的文章批次、主題 glossary、發音 helper、謹慎的 HTML patching 與驗證輸出。這讓 App 對學習者更有用,也更容易向開發者解釋。