Download data/generate_samples.py from SevdanurGenc/Text-to-SQL: direct link, hf CLI and curl.
- Browser
- Download file 20.1 kB
-
https://huggingface.co/SevdanurGenc/Text-to-SQL/resolve/main/data/generate_samples.py
- Command line
-
hf download hf://SevdanurGenc/Text-to-SQL/data/generate_samples.py
-
curl -L -o generate_samples.py https://huggingface.co/SevdanurGenc/Text-to-SQL/resolve/main/data/generate_samples.py
20.1 kB
| """Örnek (sentetik) Türkçe belgeleri üretir. | |
| Belgeler gerçek kurumlara ait DEĞİLDİR; değerler tohumlanmış rastgele sayılarla | |
| üretilmiştir. Amaç, gerçek Türkçe rapor/mevzuat/finansal tabloların taşıdığı | |
| zorlukları (birleşik hücreler, çok satırlı başlıklar, '1.234,56' sayı biçimi, | |
| parantezli negatifler, '%4,5' yüzdeleri, 'Ocak 2024' tarihleri, toplam satırları, | |
| İ/ı büyük-küçük harf sorunları) kontrollü biçimde yeniden üretmektir. | |
| Her tablo için data/ground_truth/<tablo_id>.json altında "doğru" içerik saklanır: | |
| çıkarım doğruluğu ve referans veritabanı bu dosyalardan hesaplanır. | |
| Çalıştırma: python data/generate_samples.py | |
| """ | |
| from __future__ import annotations | |
| import json | |
| import random | |
| from pathlib import Path | |
| from reportlab.lib import colors | |
| from reportlab.lib.pagesizes import A4, landscape | |
| from reportlab.lib.styles import ParagraphStyle | |
| from reportlab.lib.units import cm | |
| from reportlab.pdfbase import pdfmetrics | |
| from reportlab.pdfbase.ttfonts import TTFont | |
| from reportlab.platypus import (PageBreak, Paragraph, SimpleDocTemplate, Spacer, | |
| Table, TableStyle) | |
| ROOT = Path(__file__).resolve().parent | |
| DOCS = ROOT / "docs" | |
| GT = ROOT / "ground_truth" | |
| # Türkçe karakterleri (ğ, ş, ı, İ) içeren yazı tipi: önce projeyle gelen DejaVu, sonra sistemdekiler | |
| _FONT_CANDIDATES = [ | |
| (ROOT.parent / "assets" / "fonts" / "DejaVuSans.ttf", ROOT.parent / "assets" / "fonts" / "DejaVuSans-Bold.ttf"), | |
| (Path("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"), Path("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf")), | |
| (Path("C:/Windows/Fonts/arial.ttf"), Path("C:/Windows/Fonts/arialbd.ttf")), | |
| (Path("/System/Library/Fonts/Supplemental/Arial.ttf"), Path("/System/Library/Fonts/Supplemental/Arial Bold.ttf")), | |
| (Path("/Library/Fonts/Arial.ttf"), Path("/Library/Fonts/Arial Bold.ttf")), | |
| ] | |
| for _reg, _bold in _FONT_CANDIDATES: | |
| if _reg.exists() and _bold.exists(): | |
| pdfmetrics.registerFont(TTFont("DejaVu", str(_reg))) | |
| pdfmetrics.registerFont(TTFont("DejaVu-Bold", str(_bold))) | |
| break | |
| else: | |
| raise SystemExit("Türkçe karakter destekli yazı tipi bulunamadı (assets/fonts/DejaVuSans.ttf eksik).") | |
| rng = random.Random(2026) | |
| # ---------------------------------------------------------------- yardımcılar | |
| def tr(x: float | int | None, dec: int = 2) -> str: | |
| """Sayıyı Türkçe biçimde yazar: 12450000.5 -> '12.450.000,50'.""" | |
| if x is None: | |
| return "-" | |
| neg = x < 0 | |
| s = f"{abs(x):,.{dec}f}" # 12,450,000.50 | |
| s = s.replace(",", "§").replace(".", ",").replace("§", ".") | |
| return ("-" if neg else "") + s | |
| def tr_paren(x: float, dec: int = 0) -> str: | |
| """Finansal tablo stili: negatifler parantez içinde.""" | |
| return f"({tr(abs(x), dec)})" if x < 0 else tr(x, dec) | |
| def pct(x: float, dec: int = 1) -> str: | |
| return f"%{tr(x, dec)}" if x >= 0 else f"-%{tr(abs(x), dec)}" | |
| def save_gt(tid: str, doc: str, fmt: str, caption: str, header_rows, body, page=None): | |
| """header_rows: [[(metin, colspan, rowspan), ...], ...] body: [[str,...],...]""" | |
| GT.mkdir(parents=True, exist_ok=True) | |
| (GT / f"{tid}.json").write_text(json.dumps({ | |
| "tablo_id": tid, "belge": doc, "bicim": fmt, "sayfa": page, | |
| "baslik": caption, "baslik_satirlari": header_rows, "govde": body, | |
| }, ensure_ascii=False, indent=1), encoding="utf-8") | |
| # ---------------------------------------------------------------- tablolar | |
| def t_butce(): | |
| kalemler = [ | |
| ("Personel Giderleri", 410e6), ("SGK Devlet Primi Giderleri", 62e6), | |
| ("Mal ve Hizmet Alım Giderleri", 538e6), ("Faiz Giderleri", 41e6), | |
| ("Cari Transferler", 37e6), ("Sermaye Giderleri", 655e6), | |
| ("Sermaye Transferleri", 18e6), ("Borç Verme", 4.5e6), | |
| ] | |
| body, tot = [], [0, 0, 0, 0] | |
| for ad, base in kalemler: | |
| b23 = round(base * rng.uniform(0.62, 0.70), -3) + rng.randint(0, 99) * 10 + 0.5 * rng.randint(0, 1) | |
| g23 = round(b23 * rng.uniform(0.78, 1.04), 2) | |
| b24 = round(base, -3) + rng.randint(0, 999) * 10 + 0.25 * rng.randint(0, 3) | |
| g24 = round(b24 * rng.uniform(0.74, 1.06), 2) | |
| tot = [tot[0] + b23, tot[1] + g23, tot[2] + b24, tot[3] + g24] | |
| body.append([ad, tr(b23), tr(g23), tr(b24), tr(g24), pct(g24 / b24 * 100)]) | |
| body.append(["Toplam", tr(tot[0]), tr(tot[1]), tr(tot[2]), tr(tot[3]), pct(tot[3] / tot[2] * 100)]) | |
| header = [ | |
| [("Gider Türü", 1, 2), ("2023", 2, 1), ("2024", 2, 1), ("Gerçekleşme Oranı 2024 (%)", 1, 2)], | |
| [("Bütçe", 1, 1), ("Gerçekleşme", 1, 1), ("Bütçe", 1, 1), ("Gerçekleşme", 1, 1)], | |
| ] | |
| cap = "Tablo 3: Gider Türlerine Göre Bütçe ve Gerçekleşme Tutarları (TL)" | |
| return cap, header, body | |
| def t_personel(): | |
| body = [] | |
| for yil in range(2020, 2025): | |
| m = rng.randint(1150, 1400) | |
| i = rng.randint(2100, 2600) | |
| s = rng.randint(80, 240) | |
| body.append([str(yil), tr(m, 0), tr(i, 0), tr(s, 0), tr(m + i + s, 0)]) | |
| header = [[("Yıl", 1, 1), ("Memur", 1, 1), ("İşçi", 1, 1), ("Sözleşmeli Personel", 1, 1), ("Toplam", 1, 1)]] | |
| cap = "Tablo 5: Yıllara Göre Personel Sayısı (Kişi)" | |
| return cap, header, body | |
| ILLER = [ | |
| ("İstanbul", "Marmara", 41000), ("Ankara", "İç Anadolu", 15500), ("İzmir", "Ege", 19800), | |
| ("Bursa", "Marmara", 11200), ("Kocaeli", "Marmara", 14600), ("Antalya", "Akdeniz", 8900), | |
| ("Konya", "İç Anadolu", 7400), ("Adana", "Akdeniz", 6200), ("Gaziantep", "Güneydoğu Anadolu", 7900), | |
| ("Kayseri", "İç Anadolu", 4300), ("Samsun", "Karadeniz", 3100), ("Trabzon", "Karadeniz", 1900), | |
| ("Erzurum", "Doğu Anadolu", 1400), ("Diyarbakır", "Güneydoğu Anadolu", 3600), | |
| ("Balıkesir", "Marmara", 3900), ("Isparta", "Akdeniz", 1150), ("Iğdır", "Doğu Anadolu", 420), | |
| ] | |
| def t_enerji(): | |
| body, tot = [], [0.0, 0.0, 0.0] | |
| for il, bolge, base in ILLER: | |
| v22 = round(base * rng.uniform(0.92, 0.98), 1) | |
| v23 = round(v22 * rng.uniform(0.97, 1.06), 1) | |
| v24 = round(v23 * rng.uniform(0.96, 1.07), 1) | |
| tot = [tot[0] + v22, tot[1] + v23, tot[2] + v24] | |
| body.append([il, bolge, tr(v22, 1), tr(v23, 1), tr(v24, 1), tr((v24 - v23) / v23 * 100, 1)]) | |
| body.append(["Toplam (17 İl)", "-", tr(tot[0], 1), tr(tot[1], 1), tr(tot[2], 1), | |
| tr((tot[2] - tot[1]) / tot[1] * 100, 1)]) | |
| header = [[("İl", 1, 1), ("Bölge", 1, 1), ("2022", 1, 1), ("2023", 1, 1), ("2024", 1, 1), | |
| ("Değişim 2023-2024 (%)", 1, 1)]] | |
| cap = "Tablo 2: İllere Göre Elektrik Tüketimi (bin MWh)" | |
| return cap, header, body | |
| def t_gelir(): | |
| has24, has23 = 18_452_300, 14_118_750 | |
| sm24, sm23 = -13_210_455, -10_402_120 | |
| gy24, gy23 = -1_204_330, -985_410 | |
| pz24, pz23 = -942_118, -801_207 | |
| fin24, fin23 = -1_118_920, -644_310 | |
| vg24, vg23 = -412_560, -380_115 | |
| rows = [] | |
| def add(ad, a, b): | |
| rows.append([ad, tr_paren(a), tr_paren(b)]) | |
| add("Hasılat", has24, has23) | |
| add("Satışların Maliyeti (-)", sm24, sm23) | |
| bk24, bk23 = has24 + sm24, has23 + sm23 | |
| add("Brüt Kâr", bk24, bk23) | |
| add("Genel Yönetim Giderleri (-)", gy24, gy23) | |
| add("Pazarlama Giderleri (-)", pz24, pz23) | |
| ef24, ef23 = bk24 + gy24 + pz24, bk23 + gy23 + pz23 | |
| add("Esas Faaliyet Kârı", ef24, ef23) | |
| add("Finansman Giderleri (-)", fin24, fin23) | |
| vo24, vo23 = ef24 + fin24, ef23 + fin23 | |
| add("Vergi Öncesi Kâr", vo24, vo23) | |
| add("Vergi Gideri (-)", vg24, vg23) | |
| add("Dönem Net Kârı", vo24 + vg24, vo23 + vg23) | |
| header = [[("Kalem", 1, 1), ("Cari Dönem 01.01.2024-31.12.2024", 1, 1), | |
| ("Önceki Dönem 01.01.2023-31.12.2023", 1, 1)]] | |
| cap = "Tablo 1: Özet Gelir Tablosu (bin TL)" | |
| return cap, header, rows | |
| def t_tarife(): | |
| gruplar = { | |
| "İmar Hizmetleri": [("Yapı Ruhsatı İnceleme", "m²", 18.5, "01.01.2025"), | |
| ("İskân Belgesi", "adet", 2450.0, "01.01.2025"), | |
| ("İmar Durumu Belgesi", "adet", 1275.0, "15.03.2025"), | |
| ("Proje Tadilat İncelemesi", "adet", 3150.0, "01.07.2025")], | |
| "Zabıta Hizmetleri": [("İşyeri Açma Ruhsatı", "adet", 4800.0, "01.01.2025"), | |
| ("Seyyar Satıcı İzin Belgesi", "ay", 650.0, "01.01.2025"), | |
| ("Reklam Tabelası İzni", "m²", 420.0, "15.03.2025")], | |
| "Sosyal Tesisler": [("Düğün Salonu Kiralama", "gün", 12500.0, "01.01.2025"), | |
| ("Toplantı Salonu Kiralama", "saat", 1150.0, "01.01.2025"), | |
| ("Spor Salonu Üyeliği", "ay", 875.0, "01.07.2025"), | |
| ("Yüzme Havuzu Girişi", "seans", 180.0, "01.07.2025")], | |
| "Çevre Hizmetleri": [("Moloz Döküm Bedeli", "ton", 310.0, "01.01.2025"), | |
| ("Fosseptik Çekimi", "sefer", 1450.0, "15.03.2025"), | |
| ("Ağaç Kesim İzni", "adet", 2250.0, "01.07.2025")], | |
| } | |
| body, html_rows = [], [] | |
| for g, items in gruplar.items(): | |
| for k, (h, b, u, t) in enumerate(items): | |
| body.append([g, h, b, tr(u), t]) | |
| html_rows.append(([(g, len(items))] if k == 0 else []) + [h, b, tr(u), t]) | |
| header = [[("Hizmet Grubu", 1, 1), ("Hizmet", 1, 1), ("Birim", 1, 1), ("Ücret (TL)", 1, 1), | |
| ("Yürürlük Tarihi", 1, 1)]] | |
| cap = "Tablo 1: 2025 Yılı Belediye Hizmet Ücret Tarifesi" | |
| return cap, header, body, html_rows | |
| AYLAR = ["Ocak", "Şubat", "Mart", "Nisan", "Mayıs", "Haziran", "Temmuz", "Ağustos", | |
| "Eylül", "Ekim", "Kasım", "Aralık"] | |
| def t_endeks(): | |
| endeks = 1984.02 | |
| body, by_month = [], {} | |
| yillik24 = [64.8, 67.1, 68.5, 69.8, 71.6, 71.6, 61.8, 52.0, 49.4, 48.6, 47.1, 44.4] | |
| for yil in (2024, 2025): | |
| for m in range(12 if yil == 2024 else 6): | |
| aylik = round(rng.uniform(1.4, 4.6), 2) | |
| endeks = round(endeks * (1 + aylik / 100), 2) | |
| by_month[(yil, m)] = endeks | |
| if yil == 2024: | |
| yillik = yillik24[m] | |
| else: | |
| yillik = round((endeks / by_month[(2024, m)] - 1) * 100, 2) | |
| body.append([f"{AYLAR[m]} {yil}", tr(endeks), tr(aylik), tr(yillik)]) | |
| header = [ | |
| [("Dönem", 1, 2), ("Endeks (2003=100)", 1, 2), ("Değişim (%)", 2, 1)], | |
| [("Aylık", 1, 1), ("Yıllık", 1, 1)], | |
| ] | |
| cap = "Tablo 4: Örnek Tüketici Fiyat Endeksi ve Değişim Oranları" | |
| return cap, header, body | |
| def t_su(): | |
| mahalleler = ["Cumhuriyet", "Atatürk", "Yenimahalle", "Merkez", "İstiklal", "Fatih", | |
| "Bahçelievler", "Yıldırım Beyazıt", "Kurtuluş", "Gazi"] | |
| body, ta, tt = [], 0, 0 | |
| for m in mahalleler: | |
| abone = rng.randint(900, 6800) | |
| tuk = round(abone * rng.uniform(9.5, 14.5) * 12, 0) | |
| ta, tt = ta + abone, tt + tuk | |
| body.append([m, tr(abone, 0), tr(tuk, 0), tr(tuk / abone, 1)]) | |
| body.append(["Genel Toplam", tr(ta, 0), tr(tt, 0), tr(tt / ta, 1)]) | |
| header = [[("Mahalle", 1, 1), ("Abone Sayısı", 1, 1), ("Yıllık Tüketim (m³)", 1, 1), | |
| ("Abone Başına Tüketim (m³)", 1, 1)]] | |
| cap = "Tablo 6: Mahallelere Göre Su Abone Sayısı ve Tüketimi (2024)" | |
| return cap, header, body | |
| # ---------------------------------------------------------------- PDF yazımı | |
| STY = ParagraphStyle("p", fontName="DejaVu", fontSize=9.5, leading=13) | |
| H1 = ParagraphStyle("h", fontName="DejaVu-Bold", fontSize=14, leading=18, spaceAfter=8) | |
| CAP = ParagraphStyle("c", fontName="DejaVu-Bold", fontSize=9.5, leading=12, spaceAfter=4) | |
| NOTE = ParagraphStyle("n", fontName="DejaVu", fontSize=7.5, leading=10, textColor=colors.grey) | |
| def rl_table(header_rows, body, col_widths, num_from_col=1): | |
| """Başlık satırlarını (colspan/rowspan) reportlab ızgarasına çevirir.""" | |
| ncols = len(col_widths) | |
| nh = len(header_rows) | |
| grid = [["" for _ in range(ncols)] for _ in range(nh)] | |
| spans, occupied = [], set() | |
| for r, row in enumerate(header_rows): | |
| c = 0 | |
| for text, cs, rs in row: | |
| while (r, c) in occupied: | |
| c += 1 | |
| grid[r][c] = text | |
| for dr in range(rs): | |
| for dc in range(cs): | |
| occupied.add((r + dr, c + dc)) | |
| if cs > 1 or rs > 1: | |
| spans.append(("SPAN", (c, r), (c + cs - 1, r + rs - 1))) | |
| c += cs | |
| hstyle = ParagraphStyle("th", fontName="DejaVu-Bold", fontSize=8, leading=10, alignment=1) | |
| grid = [[Paragraph(x, hstyle) if x else "" for x in row] for row in grid] | |
| data = grid + body | |
| t = Table(data, colWidths=col_widths, repeatRows=nh) | |
| st = [ | |
| ("FONT", (0, 0), (-1, -1), "DejaVu", 8), | |
| ("FONT", (0, 0), (-1, nh - 1), "DejaVu-Bold", 8), | |
| ("GRID", (0, 0), (-1, -1), 0.5, colors.black), | |
| ("BACKGROUND", (0, 0), (-1, nh - 1), colors.HexColor("#e6ecf2")), | |
| ("VALIGN", (0, 0), (-1, -1), "MIDDLE"), | |
| ("ALIGN", (0, 0), (-1, nh - 1), "CENTER"), | |
| ("ALIGN", (num_from_col, nh), (-1, -1), "RIGHT"), | |
| ] + spans | |
| if body and str(body[-1][0]).lower().startswith("toplam"): | |
| st.append(("FONT", (0, len(data) - 1), (-1, len(data) - 1), "DejaVu-Bold", 8)) | |
| t.setStyle(TableStyle(st)) | |
| return t | |
| def build_pdfs(): | |
| # 1) Belediye faaliyet raporu: 2 tablo, 2 sayfa | |
| c1, h1, b1 = t_butce() | |
| c2, h2, b2 = t_personel() | |
| doc = SimpleDocTemplate(str(DOCS / "belediye_faaliyet_raporu_2024.pdf"), pagesize=landscape(A4), | |
| leftMargin=1.5 * cm, rightMargin=1.5 * cm, topMargin=1.5 * cm) | |
| story = [ | |
| Paragraph("Örnek Belediyesi 2024 Yılı Faaliyet Raporu", H1), | |
| Paragraph("3.2 Mali Bilgiler", CAP), | |
| Paragraph("5018 sayılı Kamu Mali Yönetimi ve Kontrol Kanunu uyarınca hazırlanan bu bölümde, " | |
| "belediyemizin ekonomik sınıflandırmaya göre bütçe ödenekleri ve gerçekleşmeleri " | |
| "sunulmaktadır. Tutarlar Türk Lirası cinsindendir.", STY), | |
| Spacer(1, 10), Paragraph(c1, CAP), | |
| rl_table(h1, b1, [6.2 * cm, 3.4 * cm, 3.4 * cm, 3.4 * cm, 3.4 * cm, 3.6 * cm]), | |
| Spacer(1, 6), | |
| Paragraph("Not: Bu belge sentetik örnek veridir; gerçek bir kuruma ait değildir.", NOTE), | |
| PageBreak(), | |
| Paragraph("3.4 İnsan Kaynakları", CAP), | |
| Paragraph("Belediyemizde istihdam edilen personelin kadro türlerine göre dağılımı aşağıda " | |
| "verilmiştir.", STY), | |
| Spacer(1, 10), Paragraph(c2, CAP), | |
| rl_table(h2, b2, [3 * cm, 3.5 * cm, 3.5 * cm, 4.5 * cm, 3.5 * cm]), | |
| ] | |
| doc.build(story) | |
| save_gt("butce_gerceklesme", "belediye_faaliyet_raporu_2024.pdf", "pdf", c1, h1, b1, page=1) | |
| save_gt("personel_sayisi", "belediye_faaliyet_raporu_2024.pdf", "pdf", c2, h2, b2, page=2) | |
| # 2) Enerji raporu | |
| c3, h3, b3 = t_enerji() | |
| doc = SimpleDocTemplate(str(DOCS / "il_enerji_tuketimi_raporu.pdf"), pagesize=A4, | |
| leftMargin=1.5 * cm, rightMargin=1.5 * cm) | |
| story = [ | |
| Paragraph("Örnek Enerji Piyasası Gözlem Raporu", H1), | |
| Paragraph("Bu raporda seçili 17 ilin son üç yıldaki elektrik tüketimleri karşılaştırılmaktadır. " | |
| "Değerler bin MWh cinsindendir; değişim oranları 2023 yılına göredir.", STY), | |
| Spacer(1, 10), Paragraph(c3, CAP), | |
| rl_table(h3, b3, [3.6 * cm, 3.9 * cm, 2.4 * cm, 2.4 * cm, 2.4 * cm, 3.3 * cm], num_from_col=2), | |
| Spacer(1, 6), Paragraph("Kaynak: Sentetik örnek veri.", NOTE), | |
| ] | |
| doc.build(story) | |
| save_gt("il_elektrik_tuketimi", "il_enerji_tuketimi_raporu.pdf", "pdf", c3, h3, b3, page=1) | |
| # 3) Finansal rapor | |
| c4, h4, b4 = t_gelir() | |
| doc = SimpleDocTemplate(str(DOCS / "ornek_as_finansal_rapor_2024.pdf"), pagesize=A4) | |
| story = [ | |
| Paragraph("ÖRNEK SANAYİ VE TİCARET A.Ş.", H1), | |
| Paragraph("31 Aralık 2024 Tarihinde Sona Eren Hesap Dönemine Ait Konsolide Finansal Tablolar. " | |
| "Aksi belirtilmedikçe tutarlar bin Türk Lirası (bin TL) olarak gösterilmiştir.", STY), | |
| Spacer(1, 10), Paragraph(c4, CAP), | |
| rl_table(h4, b4, [6.5 * cm, 4.8 * cm, 4.8 * cm]), | |
| ] | |
| doc.build(story) | |
| # 4) Çizgisiz (borderless) tablo: pdfplumber'ın çizgi stratejisi bulamaz, Camelot-stream bulur | |
| c7, h7, b7 = t_su() | |
| doc = SimpleDocTemplate(str(DOCS / "su_istatistikleri_2024.pdf"), pagesize=A4) | |
| t7 = Table([[x[0] for x in h7[0]]] + b7, colWidths=[5 * cm, 3.4 * cm, 4.2 * cm, 4.4 * cm]) | |
| t7.setStyle(TableStyle([("FONT", (0, 0), (-1, -1), "DejaVu", 8), | |
| ("FONT", (0, 0), (-1, 0), "DejaVu-Bold", 8), | |
| ("ALIGN", (1, 1), (-1, -1), "RIGHT")])) # hiç çizgi yok | |
| doc.build([Paragraph("Örnek Su ve Kanalizasyon İdaresi — 2024 İstatistikleri", H1), | |
| Paragraph("Abone ve tüketim verileri mahalle bazında derlenmiştir.", STY), | |
| Spacer(1, 10), Paragraph(c7, CAP), t7]) | |
| save_gt("su_abone_tuketim", "su_istatistikleri_2024.pdf", "pdf", c7, h7, b7, page=1) | |
| save_gt("gelir_tablosu", "ornek_as_finansal_rapor_2024.pdf", "pdf", c4, h4, b4, page=1) | |
| # ---------------------------------------------------------------- HTML yazımı | |
| def html_header(header_rows): | |
| out = [] | |
| for row in header_rows: | |
| cells = "" | |
| for t, cs, rs in row: | |
| attrs = (' colspan="%d"' % cs if cs > 1 else "") + (' rowspan="%d"' % rs if rs > 1 else "") | |
| cells += "<th%s>%s</th>" % (attrs, t) | |
| out.append(f"<tr>{cells}</tr>") | |
| return "\n".join(out) | |
| HTML_TMPL = """<!doctype html> | |
| <html lang="tr"><head><meta charset="utf-8"><title>{title}</title> | |
| <style>body{{font-family:sans-serif;max-width:900px;margin:2em auto}} | |
| table{{border-collapse:collapse}}td,th{{border:1px solid #888;padding:4px 8px}} | |
| td.n{{text-align:right}}</style></head><body> | |
| <h1>{title}</h1> | |
| {intro} | |
| <table> | |
| <caption>{caption}</caption> | |
| <thead> | |
| {thead} | |
| </thead> | |
| <tbody> | |
| {tbody} | |
| </tbody></table> | |
| <p><small>Sentetik örnek veridir.</small></p> | |
| </body></html>""" | |
| def build_htmls(): | |
| c5, h5, b5, rows5 = t_tarife() | |
| tb = [] | |
| for r in rows5: | |
| cells = [] | |
| for v in r: | |
| if isinstance(v, tuple): | |
| cells.append(f'<td rowspan="{v[1]}">{v[0]}</td>') | |
| else: | |
| cls = ' class="n"' if v[:1].isdigit() else "" | |
| cells.append(f"<td{cls}>{v}</td>") | |
| tb.append("<tr>" + "".join(cells) + "</tr>") | |
| intro = ("<p><b>ÖRNEK BELEDİYESİ ÜCRET TARİFESİ YÖNETMELİĞİ</b></p>" | |
| "<p><b>MADDE 4 –</b> (1) 2464 sayılı Belediye Gelirleri Kanunu kapsamında belediyece " | |
| "sunulan hizmetlere ilişkin ücretler aşağıdaki tabloda gösterilmiştir. Ücretlere KDV " | |
| "dahildir.</p>") | |
| (DOCS / "ucret_tarifesi_yonetmeligi.html").write_text(HTML_TMPL.format( | |
| title="Örnek Belediyesi Ücret Tarifesi", intro=intro, caption=c5, | |
| thead=html_header(h5), tbody="\n".join(tb)), encoding="utf-8") | |
| save_gt("hizmet_ucret_tarifesi", "ucret_tarifesi_yonetmeligi.html", "html", c5, h5, b5) | |
| c6, h6, b6 = t_endeks() | |
| tb = ["<tr>" + "".join(("<td class=\"n\">%s</td>" if i else "<td>%s</td>") % v | |
| for i, v in enumerate(r)) + "</tr>" for r in b6] | |
| intro = ("<p>Örnek İstatistik Bülteni — Fiyat endeksleri aylık olarak yayımlanır. " | |
| "Değişim oranları yüzde olarak verilmiştir.</p>") | |
| (DOCS / "fiyat_endeksi_bulteni.html").write_text(HTML_TMPL.format( | |
| title="Örnek Fiyat Endeksi Bülteni", intro=intro, caption=c6, | |
| thead=html_header(h6), tbody="\n".join(tb)), encoding="utf-8") | |
| save_gt("fiyat_endeksi", "fiyat_endeksi_bulteni.html", "html", c6, h6, b6) | |
| if __name__ == "__main__": | |
| DOCS.mkdir(parents=True, exist_ok=True) | |
| build_pdfs() | |
| build_htmls() | |
| print("Belgeler:", sorted(p.name for p in DOCS.iterdir())) | |
| print("Doğru içerik:", sorted(p.name for p in GT.iterdir())) | |