From b605d2722b3a909ac3f88e525d6ba8d9fda5426b Mon Sep 17 00:00:00 2001 From: Anas Rashid Date: Fri, 9 Oct 2026 00:42:21 +0200 Subject: [PATCH] =?UTF-8?q?Moderators'=20guide=20(=D8=B1=DB=81=D9=86=D9=85?= =?UTF-8?q?=D8=A7=D8=A6=DB=8C):=20writing=20Divan=20text=20with=20every=20?= =?UTF-8?q?tag,=20Urdu=20spelling,=20summaries=20and=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit /mod/guide, open to all: the tag summary table; the work header; ghazal couplets (Hasrat Mohani); stanzas (Hali's musaddas); prose chapters and sub-headings (Muhammad Husain Azad's Aab-e-Hayat); matla/maqta labels; dictionary links, footnotes and variant readings; Urdu letters, punctuation, digits, diacritics, ZWNJ compounds and spacing; edit summaries; the L2 -> L1 -> admin review. Every example shows its source beside the site's own rendering (shared DivanPreview component, also used on the revision page). Linked from the moderation tabs and the editor. Co-Authored-By: Claude Opus 5.5 --- web/src/components/DivanPreview.astro | 17 +++ web/src/components/ModNav.astro | 3 +- web/src/pages/mod/guide.astro | 156 ++++++++++++++++++++++++++ web/src/pages/mod/rev/[id].astro | 12 +- web/src/styles/global.css | 19 ++++ 5 files changed, 197 insertions(+), 10 deletions(-) create mode 100644 web/src/components/DivanPreview.astro create mode 100644 web/src/pages/mod/guide.astro diff --git a/web/src/components/DivanPreview.astro b/web/src/components/DivanPreview.astro new file mode 100644 index 00000000..217cf036 --- /dev/null +++ b/web/src/components/DivanPreview.astro @@ -0,0 +1,17 @@ +--- +// Divan text rendered like the site (moderation preview, guide examples): headings, paragraphs, couplets with +// their labels, lines and stanzas; dictionary links underlined, footnotes numbered, variants marked +import { parse } from '../../../api/src/divantext.ts'; +const { text } = Astro.props as { text: string }; +const doc = parse(text); +let n = 0; +const notes: string[] = []; +const line = (l: any) => { l.notes.forEach((x: string) => notes.push(x)); return l; }; +--- +
+ {doc.blocks.map((b: any) => b.type === 'heading' ? (b.level > 2 ?

{b.text}

:

{b.text}

) + : b.type === 'para' ?

{line(b.line).text}{b.line.notes.map(() => {++n})}

+ : b.type === 'couplet' ?
{b.lines.map((l: any) =>

{line(l).text}{l.notes.map(() => {++n})}

)}
+ :
{b.lines.map((l: any) =>

{line(l).text}{l.notes.map(() => {++n})}

)}
)} + {notes.length > 0 &&
    {notes.map((x) =>
  1. {x}
  2. )}
} +
diff --git a/web/src/components/ModNav.astro b/web/src/components/ModNav.astro index 12ab7dfe..611f4d02 100644 --- a/web/src/components/ModNav.astro +++ b/web/src/components/ModNav.astro @@ -1,7 +1,8 @@ --- -const { current } = Astro.props as { current?: 'queue' | 'log' }; +const { current } = Astro.props as { current?: 'queue' | 'log' | 'guide' }; --- diff --git a/web/src/pages/mod/guide.astro b/web/src/pages/mod/guide.astro new file mode 100644 index 00000000..d84926d4 --- /dev/null +++ b/web/src/pages/mod/guide.astro @@ -0,0 +1,156 @@ +--- +// رہنمائی: how moderators write Divan text with all its tags, Urdu spelling rules, summaries and review. +// Open to everyone (future contributors can read it); every example is rendered by the site's own parser. +import Base from '../../layouts/Base.astro'; +import ModNav from '../../components/ModNav.astro'; +import DivanPreview from '../../components/DivanPreview.astro'; + +const ex = { + header: `{{دیوان +| عنوان = چپکے چپکے رات دن آنسو بہانا یاد ہے +| شاعر = حسرت موہانی +| صنف = غزل +| ردیف = یاد ہے +| قافیہ = بہانا، زمانا +| ماخذ = ویکی ماخذ +| ماخذ_ربط = https://ur.wikisource.org/… +}}`, + ghazal: ` +چپکے چپکے رات دن آنسو بہانا یاد ہے +ہم کو اب تک عاشقی کا وہ زمانا یاد ہے + +باہزاراں اضطراب و صدہزاراں اشتیاق +تجھ سے وہ پہلے پہل دل کا لگانا یاد ہے + +بار بار اٹھنا اسی جانب نگاہ شوق کا +اور ترا غرفے سے وہ آنکھیں لڑانا یاد ہے +`, + stanza: ` +وہ نبیوں میں رحمت لقب پانے والا +مرادیں غریبوں کی بر لانے والا +مصیبت میں غیروں کے کام آنے والا +وہ اپنے پرائے کا غم کھانے والا +فقیروں کا ملجا ضعیفوں کا ماویٰ +یتیموں کا والی غلاموں کا مولیٰ +`, + prose: `== آب حیات == + +=== زبان اردو کی تاریخ === + +اتنی بات ہر شخص جانتا ہے کہ ہمارے اُردو زبان برج بھاشا سے نکلی ہے اور "برج بھاشا" خاص ہندوستانی زبان ہے۔ لیکن وہ ایسی زبان نہیں کہ دنیا کے پردے پر ہندوستان کے ساتھ آئی ہو۔ اس کی عمر آٹھ سو برس سے زیادہ نہیں ہے اور برج کا سبزہ زار اس کا وطن ہے۔`, + labels: ` +{{مطلع}} دل ناداں تجھے ہوا کیا ہے +آخر اس درد کی دوا کیا ہے + +{{مقطع}} میں نے مانا کہ کچھ نہیں غالبؔ +مفت ہاتھ آئے تو برا کیا ہے +`, + links: ` +دل [[ناداں]] تجھے ہوا کیا ہے +آخر اس درد کی [[دوا]] کیا ہےدوا: علاج۔ + +ہم ہیں [[مشتاق]] اور وہ [[لغت:بیزار|بے زار]] +یا الٰہی یہ {{نسخہ|ماجرا|ماجرہ|ماخذ=کسی دوسرے نسخے کا نام}} کیا ہے +`, +}; +const TAGS: [string, string, string][] = [ + ['{{دیوان | … }}', 'کلام کا خاکہ: عنوان، شاعر یا مصنف، صنف، ردیف، قافیہ، بحر، ماخذ', 'ہر کلام کے شروع میں، ایک بار'], + [' … ', 'شاعری کا حصہ', 'منظوم کلام کے گرد'], + ['دو سطریں', 'شعر (دو مصرعے)', 'اشعار کے درمیان ایک خالی سطر'], + ['ایک سطر', 'اکیلا مصرع', 'آگے پیچھے خالی سطر'], + ['تین یا زیادہ سطریں', 'بند (مسدس، مخمس، رباعی وغیرہ)', 'بند کے درمیان خالی سطر نہیں'], + ['== عنوان ==', 'باب کا عنوان', 'نثر میں، الگ سطر پر'], + ['=== عنوان ===', 'ذیلی عنوان', 'باب کے اندر'], + ['خالی سطر سے الگ متن', 'نثر کا پیراگراف', ' کے باہر'], + ['{{مطلع}} {{حسن مطلع}} {{مقطع}}', 'شعر کی نشانی', 'شعر کی پہلی سطر کے شروع میں، صرف درستی کے لیے'], + ['[[لفظ]]', 'لفظ کا لغت سے ربط', 'جب لفظ لغت میں اسی شکل میں ہو'], + ['[[لغت:دیوانہ|دیوانے]]', 'لغت سے ربط، لفظ کی بدلی ہوئی شکل کے ساتھ', 'پہلے لغت کی شکل، پھر متن کی شکل'], + [' … ', 'حاشیہ', 'جس لفظ یا سطر کے بعد ہو، وہیں'], + ['{{نسخہ|متن|دوسرا متن|ماخذ=…}}', 'نسخوں کا فرق: پہلا متن دکھایا جاتا ہے', 'ماخذ ضرور لکھیں'], +]; +--- + +

دیوان میں لکھنے کا طریقہ

+ {Astro.locals.user && ['mod-l2', 'mod-l1', 'admin'].includes(Astro.locals.user.role) && } +
+

+ دیوان کا ہر کلام دیوان متن میں لکھا جاتا ہے: سادہ اردو سطریں اور چند نشانیاں جو بتاتی ہیں کہ کیا شعر ہے، کیا مصرع، کیا بند، + کیا باب کا عنوان اور کیا پیراگراف۔ یہی متن جائزے کے بعد شائع ہوتا ہے اور دیوان کے کھلے ڈیٹا میں ہر تبدیلی سطر بہ سطر محفوظ رہتی ہے۔ + ہر مثال کے ساتھ اس کا پیش نظارہ وہی ہے جو سائٹ پر دکھائی دے گا۔ +

+ +

نشانیوں کا خلاصہ

+ + + {TAGS.map(([t, m, w]) => )} +
لکھیںمطلبکہاں اور کیسے
{t}{m}{w}
+ +

۱۔ کلام کا خاکہ

+

+ ہر کلام {'{{دیوان'} سے شروع ہوتا ہے اور ہر معلومات اپنی سطر پر | نام = قدر کی صورت میں لکھی جاتی ہے۔ + نثر کے لیے شاعر کی جگہ مصنف لکھیں۔ ردیف اور قافیہ خود بخود بھی معلوم کیے جاتے ہیں؛ یہاں صرف درست صورت لکھیں۔ +

+
{ex.header}
+ +

۲۔ غزل: شعر اور مصرعے

+

+ شاعری {''} اور {''} کے درمیان۔ ہر مصرع اپنی سطر پر، شعر کے دو مصرعے ساتھ ساتھ، + اور ہر شعر کے بعد ایک خالی سطر۔ مقطع میں تخلص پر تخلص کا نشان ؔ لگائیں (حسرتؔ، غالبؔ)، مقطع خود پہچانا جائے گا۔ + (مثال: حسرت موہانی کی غزل کے پہلے تین اشعار) +

+
{ex.ghazal}
+ +

۳۔ بند: مسدس، مخمس، رباعی

+

تین یا زیادہ مصرعے بغیر خالی سطر کے ایک بند بنتے ہیں۔ بندوں کے درمیان ایک خالی سطر چھوڑیں۔ (مثال: حالی کی مسدس)

+
{ex.stanza}
+ +

۴۔ نثر: باب، ذیلی عنوان اور پیراگراف

+

+ نثر {''} کے باہر لکھی جاتی ہے۔ ہر پیراگراف کے بعد ایک خالی سطر۔ باب کا عنوان == عنوان == + اور ذیلی عنوان === عنوان ===، دونوں الگ سطر پر۔ (مثال: محمد حسین آزاد کی "آب حیات"؛ کتاب کا نام باب کے عنوان کی طرح اور "زبان اردو کی تاریخ" ذیلی عنوان کی طرح) +

+
{ex.prose}
+ +

۵۔ مطلع اور مقطع کی نشانی

+

+ مطلع، مقطع اور ردیف عام طور پر خود معلوم ہو جاتے ہیں۔ اگر کہیں غلط ہوں تو شعر کی پہلی سطر کے شروع میں + {'{{مطلع}}'}، {'{{حسن مطلع}}'} یا {'{{مقطع}}'} لکھ دیں۔ +

+
{ex.labels}
+ +

۶۔ لغت کا ربط، حاشیہ اور نسخوں کا فرق

+
    +
  • [[لفظ]] لفظ کو لغت سے جوڑتا ہے۔ اگر متن میں لفظ کی بدلی ہوئی شکل ہو تو پہلے لغت کی شکل، پھر متن کی: [[لغت:بیزار|بے زار]]۔ ہر لفظ پر ربط نہ لگائیں؛ صرف مشکل یا کم معروف الفاظ پر۔
  • +
  • {'…'} حاشیہ ہے؛ جس لفظ یا سطر سے متعلق ہو اسی کے بعد لکھیں۔ پیش نظارہ میں اس کا نمبر اور نیچے متن دکھایا جاتا ہے۔
  • +
  • {'{{نسخہ|متن|دوسرا متن|ماخذ=…}}'} دو نسخوں کا فرق ہے؛ پہلا متن کلام میں دکھایا جاتا ہے۔ دوسرے نسخے کا نام ضرور لکھیں۔
  • +
+
{ex.links}
+ +

۷۔ املا اور رموزِ اوقاف

+
    +
  • اردو حروف: ی (عربی ي نہیں)، ک (عربی ك نہیں)، ہ اور دو چشمی ھ کا فرق رکھیں (کہ، کھ)، ے اپنی جگہ۔
  • +
  • رموز: ختمہ ۔، سکتہ ،، سوالیہ ؟، وقفہ ؛۔ انگریزی . , ? نہیں۔
  • +
  • اعداد: اردو ہندسے ۱۲۳۔
  • +
  • اعراب: زیر، زبر، پیش صرف جہاں ماخذ میں ہوں یا معنی بدلیں (مثلاً اضافت: دلِ ناداں)۔
  • +
  • مرکب الفاظ: بے‌ثبوت، نا‌امید جیسے الفاظ کو ایک لفظ رکھنے کے لیے درمیان میں "زیرو وِڈتھ نان جوائنر" (ZWNJ) استعمال کریں، خالی جگہ نہیں۔
  • +
  • فاصلے: الفاظ کے درمیان ایک ہی خالی جگہ؛ سطر کے شروع یا آخر میں نہیں۔
  • +
  • متن ماخذ کے مطابق رکھیں؛ اپنی طرف سے الفاظ نہ بدلیں۔ ماخذ مختلف ہوں تو {'{{نسخہ}}'} استعمال کریں۔
  • +
+ +

۸۔ ترمیم کا خلاصہ

+
    +
  • ہر مسودے کے ساتھ مختصر خلاصہ لکھیں کہ کیا بدلا اور کیوں: "دوسرے شعر کا مصرع نسخۂ … کے مطابق درست کیا"۔
  • +
  • ایک مسودے میں ایک ہی قسم کی تبدیلی رکھیں تاکہ جائزہ آسان ہو۔
  • +
  • ماخذ کا حوالہ دیں: کتاب، ایڈیشن، صفحہ۔
  • +
+ +

۹۔ جائزہ اور اشاعت

+
    +
  1. موڈریٹر (L2) مسودہ بنا کر جائزے کے لیے بھیجتا ہے۔
  2. +
  3. سینئر موڈریٹر (L1) جس کے پاس اس شاعر یا کتاب کی اجازت ہو، تبدیلیاں (سرخ: ہٹائی گئی، سبز: نئی) دیکھ کر منظور کرتا ہے، یا وجہ لکھ کر واپس یا مسترد کرتا ہے۔ واپس آیا مسودہ درست کر کے دوبارہ بھیجیں۔
  4. +
  5. ایڈمن شائع کرتا ہے: نیا ورژن نمبر ملتا ہے، کلام سائٹ پر فوراً بدل جاتا ہے، اور دیوان کے کھلے ڈیٹا میں آپ کے عوامی نام کے ساتھ محفوظ ہو جاتا ہے۔
  6. +
  7. L1 کا اپنا مسودہ سیدھا ایڈمن کو جاتا ہے؛ ایڈمن کی اپنی ترمیم فوراً شائع ہوتی ہے۔
  8. +
  9. اگر جائزے کے دوران کلام کا نیا ورژن شائع ہو جائے تو پرانا مسودہ شائع نہیں ہو سکتا؛ اسے تازہ متن پر دوبارہ بنائیں۔
  10. +
+
+ diff --git a/web/src/pages/mod/rev/[id].astro b/web/src/pages/mod/rev/[id].astro index 1dc25ae1..885bccf4 100644 --- a/web/src/pages/mod/rev/[id].astro +++ b/web/src/pages/mod/rev/[id].astro @@ -5,7 +5,7 @@ import ModNav from '../../../components/ModNav.astro'; import { asUser, COOKIE } from '../../../lib/auth'; import { STATUS, EVENT, when } from '../../../lib/mod'; import { ud } from '../../../lib/urdu'; -import { parse } from '../../../../../api/src/divantext.ts'; +import DivanPreview from '../../../components/DivanPreview.astro'; const me = Astro.locals.user; if (!me) return Astro.redirect(`/signin?next=${Astro.url.pathname}`); @@ -22,7 +22,6 @@ if (Astro.request.method === 'POST') { const res = await asUser(token, `/api/mod/revisions/${id}`); if (!res.ok) return new Response(res.data.error ?? 'نہیں ملا', { status: res.status }); const { revision: rev, diff, changes, events, may } = res.data; -const doc = parse(rev.content); const acts = ([['approve', 'منظور کریں'], ['return', 'واپس بھیجیں'], ['reject', 'مسترد کریں'], ['publish', 'شائع کریں']] as const).filter(([a]) => may[a]); --- @@ -43,7 +42,7 @@ const acts = ([['approve', 'منظور کریں'], ['return', 'واپس بھیج -

شعر کے دو مصرعے الگ سطروں پر، اشعار کے درمیان خالی سطر۔ == باب == عنوان، [[لفظ]] لغت کا ربط، <ref>…</ref> حاشیہ۔

+

شعر کے دو مصرعے الگ سطروں پر، اشعار کے درمیان خالی سطر۔ == باب == عنوان، [[لفظ]] لغت کا ربط، <ref>…</ref> حاشیہ۔ لکھنے کا مکمل طریقہ

@@ -64,12 +63,7 @@ const acts = ([['approve', 'منظور کریں'], ['return', 'واپس بھیج

پیش نظارہ

-
- {doc.blocks.map((b: any) => b.type === 'heading' ?

{b.text}

- : b.type === 'para' ?

{b.line.text}

- : b.type === 'couplet' ?
{b.lines.map((l: any) =>

{l.text}

)}
- : b.lines.map((l: any) =>

{l.text}

))} -
+
{acts.length > 0 && ( diff --git a/web/src/styles/global.css b/web/src/styles/global.css index 78e495ad..6ca35494 100644 --- a/web/src/styles/global.css +++ b/web/src/styles/global.css @@ -327,3 +327,22 @@ h1 + .muted { text-align: center; margin-top: 0; } .inline-form { display: inline; } .mod-edit-btn, .save-like { font: inherit; font-size: .85rem; padding: 1px 14px; border: 1.5px solid var(--gold); border-radius: 999px; background: var(--inner); color: var(--ink); cursor: pointer; } .mod-history { font-size: .85rem; margin-inline-start: 6px; } + +/* moderators' guide */ +.guide { max-width: 900px; margin: 0 auto; line-height: 2; } +.guide h2 { font-size: 1.15rem; color: var(--brand); text-align: start; margin-top: 28px; } +.guide code { font-family: inherit; background: var(--inner); border: 1px solid var(--gold-light); border-radius: 6px; padding: 0 6px; unicode-bidi: plaintext; display: inline-block; } /* Latin tags read left to right, Urdu right to left */ +.guide-table td:first-child { white-space: nowrap; } +.example { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; align-items: start; margin: 10px 0; } +.example pre { unicode-bidi: plaintext; margin: 0; padding: 12px 14px; background: var(--inner); border: 1px solid var(--border); border-radius: 10px; white-space: pre-wrap; + font-family: 'Noto Naskh Arabic', serif; font-size: .95rem; line-height: 1.9; } +.example:has(> pre:only-child) { grid-template-columns: 1fr; } +.preview { margin: 0; padding: 12px 16px; } +.preview .couplet { font-size: 1rem; grid-template-columns: 1fr; } +.preview .couplet p, .preview .couplet p + p { text-align: center; } +.preview .stanza { margin: 6px 0 12px; } +.preview .stanza p, .preview .single { text-align: center; margin: 0; } +.preview .mod-h.sub { font-size: 1rem; text-align: center; color: var(--lapis); } +.preview sup { color: var(--brand); font-size: .7em; } +.preview-notes { font-size: .85rem; border-top: 1px dashed var(--gold-light); margin-top: 8px; padding-top: 6px; } +@media (max-width: 760px) { .example { grid-template-columns: 1fr; } }