Skip to content

Fix - #1

Open
YOSEFTT wants to merge 9 commits into
mainfrom
fix
Open

Fix#1
YOSEFTT wants to merge 9 commits into
mainfrom
fix

Conversation

@YOSEFTT

@YOSEFTT YOSEFTT commented Sep 14, 2026

Copy link
Copy Markdown
Member

@mmichaelush
אשמח שתעבור על זה.
השינויים מוסברים בשמות הקומיטים.
שינויים קטנים מאוד אך חשובים מאוד

YOSEFTT and others added 6 commits September 14, 2026 23:41
מוסיף על שלושת הקומיטים של ה-PR, בלי לבטל אף אחד מהם.

1. החזרת footnotes לתפריט. FOOTNOTES הוא ConnectionType אמיתי באוצריא
   (LinkTypes.dependentTextTypes, עם תווית עברית וטסטים), ולא סוג שחסר ב-DB.
   ההסתרה גם שברה את buildOfflineHtml: השורה
   `connectionTypeSelect.value = "footnotes"` נכשלת בשקט כשה-option חסר,
   וכל עותק ה-HTML האופליין נוצר עם "לא ידוע (ריק)".

2. העברת footnotes ו-explication לקבוצת המפרשים. שניהם חברים ב-
   LinkTypes.dependentTextTypes ולכן מוצגים באוצריא בפאנל המפרשים,
   לא בפאנל הקישורים. explication היה בקבוצה הלא נכונה, ו-footnotes
   היה בה עוד לפני ה-PR.

3. הוספת elucidation (מפרשים) ו-essay (קישורים) — סוגים נתמכים באוצריא
   שנעדרו מהתפריט.

4. איחוד none, ערך ריק ו-other לאפשרות אחת. ConnectionType.fromString
   בגנרטור ממפה גם "" וגם "none" ל-OTHER, ולכן שלוש האפשרויות ייצרו
   בדיוק את אותו קישור. נשאר other, הסוג הקנוני.

5. תיקון נסיגה שנוצרה מהמעבר לכמתים חמדניים: פיסוק נגרר בלי פותח תואם
   ("1." ,"1)") שורד את stripWrapperChars ונשאר במפתח, ולכן isPlainNumericKey
   החזירה false וזיהוי איפוס-המספור בין פרקים כבה בשקט בספרים שמסמנים כך.
   הבדיקה מקבלת עכשיו עיטור פיסוק אך פוסלת כוכבית, שהיא חלק מהמזהה.
   באותה הזדמנות, ההשוואות הקשיחות למחרוזות "1"/"2"/"3" ב-
   shouldAdvanceBookChapter הוחלפו בהשוואה על num — מפתח מעוטר כמו "(2)"
   מעולם לא היה שווה ל-"2".

6. תיקון נוסח ההערה מעל האפשרויות המוסתרות. אומת מול
   ConnectionType.fromString ב-SeforimLibrary: quotation_auto ו-
   quotation_auto_tanakh ממופים ל-QUOTATION, related passage ל-RELATED,
   ו-"ein mishpat / ner mitsvah" ל-EIN_MISHPAT. אלה שמות חלופיים, לא
   סוגים שחסרים ב-DB.

השמות עם קו תחתון נשארו: fromString עושה lowercase ו-replace(' ', '_'),
ולכן "mesorat hashas" ו-"mesorat_hashas" שקולים לחלוטין.
linker נשאר — הוא סוג מוכר באוצריא ולא נמצאה שום עדות שהגנרטור מדלג עליו.
המעבר לכמתים חמדניים תיקן את בעיית הכוכבית אבל הכניס רגרסיה חמורה יותר:
הכמת הנגרר בולע גם פיסוק לא-מאוזן, והפיסוק נשאר בתוך המפתח.

הנזק העיקרי הוא א-סימטריה בין שני הצדדים. ספר שמסמן <sup>1</sup> וקובץ
הערות שפותח כל הערה ב-"1)" או ב-"1." הם אותה הערה, אבל קיבלו מפתחות
"1" מול "1)" ולכן לא הותאמו כלל. נמדד על buildLinks: קובץ שלם ירד
מ-3/3 קישורים ל-0/3. הצירוף הזה נפוץ מאוד.

בעיות נוספות שנבעו מאותו שורש:
- תגית <sup> לא סגורה נופלת ל-tail.slice(0, 220), והמפתח בלע את כל
  220 התווים.
- מפתחות כמו "(1" ,"1a" ,"abc1def" עברו את isPlainNumericKey שהרחבתי
  בקומיט הקודם, וגרמו לפיצול פרקים שווא. "1 2 (1 3 4" התפצל לשני
  פרקים במקום אחד.
- stripWrapperChars מקלף צמדי עטיפה בלי לבדוק התאמה, והחמדנות הזינה
  אליו הרבה יותר צמדים לא תואמים: "(1)(2)" יצא "1)".

הפתרון אינו כיוונון של מחלקות התווים אלא הפרדה נכונה: המפתח נבנה
מהמספר ומהכוכביות בלבד, וכל שאר העיטור נזרק. הכוכבית היא חלק מזהות
הסימון ("סג*" ≠ "סג") ולכן נשמרת; סוגריים, נקודה או פסיק הם עיטור
שכל צד רשאי לכתוב אחרת. prefix/suffix הגולמיים נשמרים לדוח הכפילויות.

בעקבות זאת isPlainNumericKey חוזרת לבדיקה המחמירה /^\d+$/ — העיטור
כבר לא מגיע אליה.

אומת בהרצה של הפונקציות האמיתיות מתוך index.html:
- ספר <sup>N</sup> מול הערות "N)" ,"N." ,"(N)" ו-"N": 3/3 בכל ארבעת
  הסגנונות (לפני: 0/3 בשניים הראשונים).
- (א)/(א*)/(א**) ו-(סג)/(סג*) נשארים מפתחות נפרדים.
- תגית לא סגורה: המפתח ירד מ-220 תווים ל-"1".
- "1 2 (1 3 4" ו-"1 2 1a 3 4" חוזרים לפרק אחד; "1 2 3 1 2" עדיין
  מזוהה כשני פרקים.
- מצב תגית ומצב regex מחזירים כעת מפתחות זהים לאותם סימונים.
- rawStart/rawEnd עדיין עוטפים את התגית המלאה.

לא נגעתי בפענוח ישויות HTML (&#1488; מתפרש כמספר 1488) — באג קדם-קיים
שאינו קשור לדיף הזה.
שלושה תיקונים שאומתו אחד-אחד מול קוד אוצריא. אין שינוי בלוגיקת הקישור
ואין שינוי במבנה ה-JSON.

1. sifrei_mitsvot -> sifrei_mitzvot

   LinkTypes.sifreiMitzvot באוצריא הוא 'SIFREI_MITZVOT' עם z
   (lib/models/link_types.dart:28), וכל הטסטים משתמשים באיות הזה
   (link_types_test.dart:110,158,218,297 ו-selected_line_links_view_test.dart).
   LinkTypes.normalize רק עושה uppercase ומחליף רווחים בקווים תחתונים,
   ולכן 'sifrei_mitsvot' הופך ל-'SIFREI_MITSVOT' — ערך שאינו מוכר,
   ש-hebrewLabel מחזירה כמות שהוא. בפועל הקישור היה מוצג בפאנל תחת
   צ׳יפ בשם הלטיני SIFREI_MITSVOT במקום "ספרי מצוות", ולא היה מקבל את
   מקומו ב-_typeChipOrder (links_list_view.dart:200).

   נבדק גם מול הגנרטור: ConnectionType.fromString ב-SeforimLibrary אינו
   מכיר אף אחד משני האיותים, ולכן השינוי אינו משנה דבר בצד ה-DB
   ואינו יכול לשבור קבצים קיימים.

2. שש תוויות עבריות יושרו ל-LinkTypes.hebrewLabels

   התפריט הציג תוויות שאינן אלה שהמשתמש רואה אחר כך בפאנל:

     reference  הפניה              -> עיון
     related    קשור               -> נושא קרוב
     allusion   רמז                -> אזכור
     law        הלכה               -> פסיקת הלכה
     liturgy    ליטורגיה — נוסח תפילה -> תפילה
     linker     קישור אוטומטי       -> אוטומטי

   שתיים מהן אינן עניין של טעם. הטסט באוצריא מנמק במפורש
   (link_types_test.dart:151): "רמז" בעולם התורני הוא חלק מפרד"ס או
   מספר סימן, ו"הלכה" רחב מדי. התוויות הנותרות בתפריט כבר תאמו.

3. השלמת המעבר להשוואה על num ב-buildLinks

   מסלול ההצלה "מעבר לאחר פספוסים" נשאר עם ההשוואה הקשיחה
   occ.key === "1" בעוד ששאר הקוד עבר להשוואה על occ.num יחד עם
   isPlainNumericKey. מאז שהמפתח נושא רק מספר וכוכביות שתי הצורות
   שקולות בדיוק, ולכן זהו שינוי משמר-התנהגות — אבל הוא מונע סטייה
   בין שני המסלולים אם המפתח ישתנה שוב בעתיד.

כל מערך הבדיקות שנבנה לקומיט הקודם הורץ מחדש על הפונקציות האמיתיות
ועבר ללא שינוי: התאמה חוצת-צדדים 3/3 בארבעה סגנוני סימון, הבחנה בין
(א)/(א*)/(א**), פרקים, ועוגנים. התפריט: 23 אפשרויות, בלי כפילויות,
וכל תווית תואמת ל-hebrewLabels.

@mmichaelush mmichaelush left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@YOSEFTT תודה, עברתי על זה לעומק. התיקון של הכוכבית הוא באג אמיתי וחשוב, ושמחתי שתפסת אותו — אבל בדרך התברר שהוא גורר עוד כמה דברים, אז הוספתי מעליך שלושה קומיטים במקום להחזיר לך את ה-PR. הכול מפורט כאן, ואם משהו נראה לך לא נכון נשמח לדבר עליו.

מה שבדקנו ואיך

השוונו כל טענה מול שלושה מקורות: קוד אוצריא (lib/models/link_types.dart והמסלולים שקוראים _links.json), הגנרטור kdroidFilter/SeforimLibrary, והרצה בפועל של הפונקציות מתוך index.html ב-Node.


1. תיקון הכוכבית — נכון, ואומת

בקוד הישן (סג) ו-(סג*) קיבלו את אותו מפתח בדיוק ((63), כלומר הערה עם כוכבית התנגשה בהערה בלעדיה. אחרי השינוי הן 63 ו-63* — שני מזהים נפרדים. אומת בהרצה.

בונוס שלא צוין בקומיט: הכמת החמדני מאפשר ל-stripWrapperChars לקלף סוגריים תואמים, ולכן (1) ו-[1] הפכו למפתחות נקיים וזיהוי איפוס-המספור בין פרקים התחיל לעבוד גם על ספרים שמסמנים בסוגריים. קודם הוא היה מת שם.

2. אבל הכמת החמדני הכניס רגרסיה חמורה

הוא בולע גם פיסוק לא מאוזן, והפיסוק נשאר בתוך המפתח. הבעיה אינה בצד אחד אלא באי-התאמה בין הצדדים: ספר שמסמן <sup>1</sup> וקובץ הערות שפותח כל הערה ב-1) או ב-1. הם אותה הערה, אבל קיבלו "1" מול "1)".

מדדנו על buildLinks:

ספר:   ['t<sup>1</sup>','t<sup>2</sup>','t<sup>3</sup>']
הערות: ['<b>1)</b> a','<b>2)</b> b','<b>3)</b> c']
  לפני השינוי: 3 קישורים
  אחרי:        0 קישורים

קובץ שלם יורד ל-אפס, והצירוף הזה נפוץ מאוד. בנוסף, תגית <sup> לא סגורה נופלת ל-tail.slice(0, 220), ושם המפתח בלע 220 תווי זבל.

הפתרון (קומיט 0113e79) אינו כיוונון של מחלקות התווים אלא הפרדה: המפתח נבנה מהמספר ומהכוכביות בלבד. הכוכבית היא חלק מזהות הסימון ולכן נשמרת; סוגריים, נקודה ופסיק הם עיטור שכל צד רשאי לכתוב אחרת. prefix/suffix הגולמיים נשמרים לדוח הכפילויות.

אחרי התיקון, בהרצה על הקוד האמיתי:

בדיקה תוצאה
ספר <sup>N</sup> מול הערות N) / N. / (N) / N 3/3 בכל הארבעה
(א) / (א*) / (א**), (סג) / (סג*) נשארים נפרדים
תגית לא סגורה המפתח ירד מ-220 תווים ל-1
מצב תגית מול מצב regex מחזירים כעת מפתחות זהים לאותם סימונים
rawStart / rawEnd עדיין עוטפים את התגית המלאה

3. שמות עם קו תחתון — צדקת, אין כאן בעיה

ConnectionType.fromString בגנרטור עושה trim().lowercase().replace(' ', '_'), כלומר mesorat hashas ו-mesorat_hashas שקולים לחלוטין. גם LinkTypes.normalize באפליקציה מנרמל רווחים לקווים תחתונים. השארנו את השינוי שלך.

4. הסוגים שהוכנסו להערה — ברובו נכון, חוץ מאחד

quotation_auto, quotation_auto_tanakh, related passage ו-ein mishpat / ner mitsvah הם באמת שמות חלופיים שממופים לסוג אחר, ולכן צדקת שאין טעם להציע אותם ליצירת קישורים חדשים. הגנרטור מאשר זאת במפורש. רק עדכנו את נוסח ההערה מ-"לא קיים כרגע ב-DB" ל-"שמות חלופיים שאינם נשמרים כסוג נפרד", כי זה מה שהם.

footnotes הוא המקרה החריג, ושני המקורות חלוקים עליו. באפליקציה FOOTNOTES הוא סוג מלא: קבוע ב-LinkTypes, חבר ב-dependentTextTypes, תווית עברית, טסטים, וקומיט ייעודי. בגנרטור הציבורי הוא נופל ל-OTHER. החזרנו אותו לתפריט משתי סיבות: האפליקציה מתארת את מה שיש ב-DB בפועל, וגם כי ההסתרה שברה קוד קיים — buildOfflineHtml עושה connectionTypeSelect.value = "footnotes", וכשה-option חסר ההשמה נכשלת בשקט וכל עותק ה-HTML האופליין נוצר עם "לא ידוע (ריק)".

5. תיקונים נוספים שנכנסו

  • explication היה בקבוצת הקישורים; הוא dependentTextType ולכן מוצג בפאנל המפרשים. הועבר, וגם footnotes שהיה שם עוד לפני ה-PR.
  • נוספו elucidation ו-essay — סוגים נתמכים שנעדרו מהתפריט.
  • none והערך הריק אוחדו ל-other: שלושתם ממופים ל-OTHER וייצרו בדיוק אותו קישור.
  • sifrei_mitsvotsifrei_mitzvot. באוצריא הקבוע הוא SIFREI_MITZVOT עם z והטסטים משתמשים באיות הזה; normalize לא מתקן s→z, ולכן הערך הישן היה מוצג בפאנל כצ׳יפ בשם הלטיני SIFREI_MITSVOT במקום "ספרי מצוות".
  • שש תוויות עבריות בתפריט יושרו ל-LinkTypes.hebrewLabels, כדי שמה שנבחר יהיה מה שרואים אחר כך: reference הפניה→עיון, related קשור→נושא קרוב, allusion רמז→אזכור, law הלכה→פסיקת הלכה, liturgy→תפילה, linker→אוטומטי. שתיים מהן מנומקות במפורש בטסט של אוצריא: "רמז" בעולם התורני הוא חלק מפרד"ס או מספר סימן, ו"הלכה" רחב מדי.

שאלות פתוחות — לא חוסמות את ה-PR

אלה לא באגים בכלי אלא פערים מול הצד השני, ושווה שמישהו שמכיר את צינור הבנייה יענה עליהן:

  1. עשרה סוגים נבלעים ל-OTHER. ה-enum ב-SeforimLibrary (master, הענף החדש והרחב ביותר מבין 39) מכיר 14 ערכים בלבד. elucidation, explication, footnotes, allusion, law, liturgy, linker, summary, sifrei_mitzvot ו-essay נופלים כולם ל-OTHER בשקט מוחלט, בלי שורת לוג. אבל האפליקציה מכירה את כולם עם תוויות וטסטים — כלומר ה-seforim.db שנשלח בפועל נבנה בגרסה שאינה ציבורית. מה המצב האמיתי?

  2. מצב טווח לא מגיע ל-DB. הכלי מייצר line_index_1_end / line_index_2_end, ו-Link.fromJson מאפסת אותם קשיח עם ההערה "קישורי-טווח מגיעים רק ממסד הנתונים, לא מקבצי JSON". השדות נזרקים בלי הודעה.

  3. מצב עוגן לא מגיע ל-DB. start/end נזרקים על ידי הגנרטור (ignoreUnknownKeys), והמסלול היחיד שמשתמש בהם מסומן "not yet implemented". בנוסף, באפליקציה קישור עם start/end שאינו תלוי-טקסט מוסתר מפאנל הקישורים ומוצג רק כקו-תחתון בטקסט.

  4. רשומה פגומה אחת מפילה קובץ שלם. ארבעת השדות בגנרטור הם required בלי ברירת מחדל, וחריגה בפענוח מחזירה רשימה ריקה עם אזהרה אחת. שווה לשקול ולידציה בצד הכלי לפני הייצוא.

  5. מסלול ייבוא התוכן באוצריא מקבל חמישה סוגים בלבד (kHebrewConnectionTypes). מי שמייבא דרך "תיקיות מותאמות" במקום להניח את הקובץ ידנית ב-links/ יקבל "סוג קישור לא מוכר" על רוב הסוגים.


מבחינתי הקוד מוכן למיזוג אחרי שלושת הקומיטים שנוספו. תודה על התיקון — הוא תפס משהו אמיתי שאף אחד לא שם לב אליו.

@YOSEFTT

YOSEFTT commented Sep 18, 2026

Copy link
Copy Markdown
Member Author

@mmichaelush
יישר כח גדול על הכל!

יש לך כאן טעות.

השוונו כל טענה מול שלושה מקורות: קוד אוצריא (lib/models/link_types.dart והמסלולים שקוראים _links.json), הגנרטור kdroidFilter/SeforimLibrary, והרצה בפועל של הפונקציות מתוך index.html ב-Node.

זה טעות!
אתה צריך להשוות מול הגנרטור של אוצריא, לא של זית!
https://github.com/Otzaria/SeforimLibrary

כנ"ל אותו דבר לגבי זה: > עשרה סוגים נבלעים ל-OTHER. ה-enum ב-SeforimLibrary (master, הענף החדש והרחב ביותר מבין 39) מכיר 14 ערכים בלבד. elucidation, explication, footnotes, allusion, law, liturgy, linker, summary, sifrei_mitzvot ו-essay נופלים כולם ל-OTHER בשקט מוחלט, בלי שורת לוג. אבל האפליקציה מכירה את כולם עם תוויות וטסטים — כלומר ה-seforim.db שנשלח בפועל נבנה בגרסה שאינה ציבורית. מה המצב האמיתי?

תשלח אותו שיבדוק לפי המזלג של אוצריא!!

לגבי:

FOOTNOTES הוא סוג מלא: קבוע ב-LinkTypes, חבר ב-dependentTextTypes

אם הבנתי נכון מה שכתב הרב קלוד, אז השינוי הזה באמת התבצע לאחר ששלחתי את ה PR שלי.
בקומיט הזה:
Otzaria/otzaria@3b29fd3
שנוצר רק אתמול...
אמנם במחשבה שני', אולי הוא מתכוין שגם לפני כן זה זוהה אבל הי' זה הי' נופל ל - OTHER.
אכן כך הי' עד לא מזמן. אבל זה השתנה אתמול. כדאי שתשלח אותו שיבדוק שוב מה בדיוק קורה כעת, ויעדכן את ה PR לפי זה.

?M> מצב טווח לא מגיע ל-DB. הכלי מייצר line_index_1_end / line_index_2_end, ו-Link.fromJson מאפסת אותם קשיח עם ההערה "קישורי-טווח מגיעים רק ממסד הנתונים, לא מקבצי JSON". השדות נזרקים בלי הודעה.

מצב עוגן לא מגיע ל-DB. start/end נזרקים על ידי הגנרטור (ignoreUnknownKeys), והמסלול היחיד שמשתמש בהם מסומן "not yet implemented". בנוסף, באפליקציה קישור עם start/end שאינו תלוי-טקסט מוסתר מפאנל הקישורים ומוצג רק כקו-תחתון בטקסט.

לא הבנתי.

דבר נוסף, כדאי שתכתוב ברשימה הפתחת המוצגת למשתמש על כל סוג של קישור האם הוא נהי' פופאפ בתוך מסך העיון להצגת הקישור, או לא. (אני בעצמי לא ברור לי בדיוק הכללים של זה מתי כן ומתי לא).

לגבי:

sifrei_mitsvot → sifrei_mitzvot. באוצריא הקבוע הוא SIFREI_MITZVOT עם z והטסטים משתמשים באיות הזה; normalize לא מתקן s→z, ולכן הערך הישן היה מוצג בפאנל כצ׳יפ בשם הלטיני SIFREI_MITSVOT במקום "ספרי מצוות".

למה הוא לא תיקן?

אומת מול המזלג Otzaria/SeforimLibrary (ענף otzaria), שהוא הגנרטור
שבונה את seforim.db — לא ה-upstream של kdroidFilter שנבדק קודם בטעות.

generator/otzariasqlite/.../Generator.kt:2014-2018:

    val declaredType = ConnectionType.fromString(linkData.connectionType)
    // "linker"-typed rows are an old Dicta linker experiment (removed from
    // otzaria-library, may linger in old zips) — never imported. The LINKER
    // layer comes solely from LinkerToOtzaria's Phase-2.
    if (declaredType == ConnectionType.LINKER) continue

ה-continue קודם ל-insertLinkStable, ולכן לא נוצרת שורת link, לא עוגן
ולא טווח, והמונה processed אינו עולה. אין אזהרה ואין דיווח: הרשומה
נעלמת בשקט מוחלט. שכבת LINKER מיוצרת אך ורק ב-Phase-2 של
LinkerToOtzaria, מ-sidecar בפורמט TSV ולא מ-JSON, ולכן אין שום דרך
להזריק אותה דרך <שם הספר>_links.json.

השארת האפשרות בתפריט הייתה מייצרת JSON שנראה תקין בעוד שהקישורים
שבו נמחקים בבנייה. הערך הועבר לבלוק המוסתר עם הנימוק, כמו שאר
האפשרויות שאינן ליצירת קישורים חדשים.

התפריט: 22 אפשרויות פעילות, בלי כפילויות.
@mmichaelush

Copy link
Copy Markdown
Member

@YOSEFTT צדקת, ותודה שעצרת אותי. בדקתי מול kdroidFilter/SeforimLibrary במקום מול המזלג Otzaria/SeforimLibrary, ומכיוון שה-upstream של זית מפגר מאוד אחרי המזלג — כמה מהמסקנות שלי היו פשוט שגויות. חזרתי ובדקתי הכול מול ענף otzaria במזלג. להלן התיקונים.

מה שהיה שגוי אצלי

1. "עשרה סוגים נבלעים ל-OTHER" — בטל לחלוטין.
ה-enum במזלג מונה 24 ערכים וכולל בדיוק את אלה שטענתי שחסרים: LINKER, SIFREI_MITZVOT, ESSAY, ALLUSION, LITURGY, ELUCIDATION, EXPLICATION, LAW, SUMMARY, FOOTNOTES. כולם ממופים ב-fromKnownStringOrNull ונשמרים כסוג נפרד. אין "גרסה שאינה ציבורית" ואין תעלומה — הסתכלתי במקום הלא נכון.

2. linker — טעיתי, וה-AI שבדק קודם צדק.
כתבתי שהשורה הזו לא קיימת בשום מקום. היא קיימת, במזלג, generator/otzariasqlite/.../Generator.kt:2014-2018:

val declaredType = ConnectionType.fromString(linkData.connectionType)
// "linker"-typed rows are an old Dicta linker experiment (removed from
// otzaria-library, may linger in old zips) — never imported. The LINKER
// layer comes solely from LinkerToOtzaria's Phase-2.
if (declaredType == ConnectionType.LINKER) continue

ה-continue קודם ל-insertLinkStable, ולכן לא נוצרת שורת link, לא עוגן ולא טווח, והרשומה נעלמת בלי שום אזהרה. שכבת LINKER מיוצרת רק ב-Phase-2 של LinkerToOtzaria, מ-sidecar בפורמט TSV. הסרתי את linker מהתפריט בקומיט 8034043.

3. fromKnownStringOrNull — קיים. כתבתי שהוא בדוי. הוא במזלג, והוא הווריאנט המחמיר שמחזיר null במקום OTHER.

4. "מצב טווח ומצב עוגן לא מגיעים ל-DB" — שגוי. שניהם נתמכים.
זה מה ששאלת עליו "לא הבנתי", ובצדק, כי מה שכתבתי לא היה נכון. LinkData במזלג מצהיר על כל ארבעת השדות:

val start: Double? = null,
val end: Double? = null,
val line_index_1_end: Double? = null,
val line_index_2_end: Double? = null

start/end נכתבים לטבלת link_anchor אחרי המרה מאופסט גולמי לקואורדינטת תווים-נראים, ו-line_index_*_end נכתבים ל-link_range ו-link_coverage. שני המצבים בכלי עובדים. ההערה באפליקציה שציטטתי ("קישורי-טווח מגיעים רק ממסד הנתונים") נכונה — אבל היא מתארת את מסלול קריאת ה-JSON הישיר, לא את הגנרטור.

תשובה לשאלת הפופאפ

שאלת שנכתוב לכל סוג אם הוא נהיה פופאפ במסך העיון. בדקתי, ומסתבר שזו בכלל לא תכונה של הסוג — לכן גם לא ברורים לך הכללים. הפילטר ב-simple_text_viewer.dart:3164 וב-utils/text/text_with_inline_links.dart:20 הוא בדיוק זה:

.where((link) => link.start != null && link.end != null)

בלי שום בדיקת סוג. כלומר:

  • מצב עוגן בכלי (start/end) → הקישור נהיה סימון לחיץ בתוך הטקסט עם פופאפ. לכל סוג.
  • בלי עוגן → אין פופאפ, הקישור מופיע בפאנל (מפרשים או קישורים לפי הסוג).

הסוג קובע רק לאן הלחיצה על הפופאפ מובילה: shouldOpenPreviewLinkInBook מחזיר true רק ל-LINKER ואז נפתח ספר היעד בטאב חדש; אחרת סוג תלוי-טקסט פותח את פאנל המפרשים, והשאר את פאנל הקישורים.

שני תנאים נוספים שכדאי להכיר: הפופאפ פעיל רק בטקסט הראשי (לא בעמודת מפרש), רק כשההגדרה enableHtmlLinks דלוקה, ולא במהדורה חלופית. ובכיוון השני — computeVisibleLinks מוציא כל קישור שיש לו start/end מפאנל הקישורים, כלומר קישור עם עוגן מופיע inline בלבד ולא בפאנל.

אם זה מספיק ברור, אפשר להוסיף את המשפט הזה כהסבר ליד מתג מצב-העוגן בכלי, במקום להצמיד הערה לכל אחד מ-22 הסוגים.

sifrei_mitzvot — כן תוקן

שאלת "למה הוא לא תיקן?". זה כן תוקן, בקומיט 42883e1. ה-Review פשוט תיאר את מה שכבר נדחף.

והבדיקה מול המזלג מחזקת את זה: fromKnownStringOrNull ממפה "sifrei_mitzvot" רק עם z. האיות הישן sifrei_mitsvot היה נופל ל-OTHER. כלומר זה לא תיקון תצוגה אלא תיקון שמונע אובדן סוג ב-DB.

footnotes — צדקת, ואני מתקן את הניסוח שלי

בדקתי את התאריכים: הקומיט 3b29fd3f9 באוצריא הוא מ-16.9, וה-PR שלך מ-14.9. כשכתבת "לא קיים כרגע ב-DB מקווה שישתנה בקרוב" זה היה תיאור מדויק של המצב באותו רגע. אני התייחסתי לזה כאי-דיוק וטעיתי; זה היה נכון ופשוט התיישן תוך יומיים.

ההחזרה של footnotes לתפריט עדיין נכונה להיום, וגם בלי זה ההסתרה שברה את buildOfflineHtml.

שני דברים חדשים ששווה שתכיר

הידרדרות שקטה ל-OTHER. ב-Generator.kt:2019-2028, תשעת הסוגים המכוונים (COMMENTARY, SUPER_COMMENTARY, TARGUM, MIDRASH, PARSHANUT, DIBUR_HAMATCHIL, EIN_MISHPAT, ELUCIDATION, FOOTNOTES) מודרדרים ל-OTHER כשהקישור מצביע מספר שאינו ספר-בסיס אל ספר בסיס, וכותרת המקור אינה מכריזה תלות בנוסח "X על Y". בלי שום לוג. זה נוגע בדיוק לשימוש העיקרי של הכלי, וכדאי לוודא ששם קובץ ההערות מכריז תלות.

רשומה פגומה אחת מפילה קובץ שלם. ארבעת השדות הם required בלי ברירת מחדל, וכשל פענוח אחד מחזיר רשימה ריקה עם אזהרה יחידה. שווה לשקול ולידציה בכלי לפני הייצוא.


מצטער על הסיבוב המיותר. התפריט עומד כעת על 22 אפשרויות פעילות, ומבחינתי זה מוכן למיזוג.

mmichaelush added 2 commits September 20, 2026 09:50
סוגר את איסיו #2 ("הסרת האימוג'ים - זה נראה לא מקצועי בעליל").

אייקונים
--------
כל 23 האימוג'ים הוחלפו באייקוני SVG מוטמעים מתוך הספרייט של
Otzaria/OtzariaLinker — אותו ארגון, אותה שפה חזותית קווית, viewBox
24x24. 14 סימבולים נבחרו מתוך 60 והשאר הוסרו כדי לא לנפח את הקובץ.

הספרייט מוטמע בגוף המסמך ולא נטען מהרשת, וזה מכוון: איסיו #2 ב-
OtzariaLinker נפתח בדיוק בגלל פונט אייקונים שלא נטען אופליין והציג
את שם האייקון כטקסט על כל כפתור. SVG מוטמע חסין לזה, והוא גם נשמר
כמות שהוא ב-buildOfflineHtml שמשכפל את כל המסמך.

גם הפאביקון, שהיה אימוג'י בתוך תגית text, הוחלף בנתיב של ic-link.

במקומות שבהם האימוג'י היה חלק ממשפט ("לחצו על ⚙️ יצירת ה-JSON")
הוא פשוט הוסר — שם הכפתור במרכאות קורא טוב יותר בלי אייקון באמצע
המשפט. החץ ↔ נשאר: הוא תו טיפוגרפי, לא אימוג'י.

טוקנים
------
:root אימץ את מערכת הצבעים של OtzariaLinker, שנגזרה בעצמה מ-
AppTokens ו-AppSurfaces של אוצריא: תפקידי M3 מלאים (primary,
surface-container על גווניו, outline-variant, error, warning).
הטוקנים הישנים נשארו כשמות והפכו לכינויים, כדי ששאר 23KB של CSS
ימשיכו לעבוד בלי שכתוב.

השינוי המורגש ביותר הוא radius: 16px היה חורג מאוצריא, שבה
AppTokens.radius = 8 הוא מקור אמת יחיד. כל ערכי ה-border-radius
הקשיחים (18/14/12/10/24/3/999) עברו לטוקנים.

בנוסף: 12 רקעים לבנים קשיחים עברו ל-surface-container-lowest,
והאדומים האד-הוק של כפתור המחיקה עברו לתפקידי error של M3.

אימות
-----
- 0 אימוג'ים בקובץ.
- 14 סימבולים, 23 הפניות use, אף הפניה חסרה.
- איזון תגיות: svg 25/25, button 16/16, select 2/2, optgroup 2/2,
  details 2/2, style ו-script 1/1; 203/203 סוגריים ב-CSS.
- ה-JS עובר new Function ללא שגיאת תחביר.
- מערך הבדיקות של לוגיקת הקישור הורץ מחדש ועבר: התאמה חוצת-צדדים
  3/3 בארבעה סגנוני סימון, הבחנה בין (א)/(א*)/(א**), פרקים ועוגנים.

לא נכנס מצב כהה — OtzariaLinker תומך בו, וזו הרחבה נפרדת.
מצב כהה
-------
התווסף מצב כהה מלא, בערכים של OtzariaLinker שנגזרו מ-AppSurfaces של
אוצריא (panelBackground כהה = שחור).

המימוש הוא דריסת תפקידים בלבד: :root[data-theme="dark"] דורס את
תפקידי ה-M3, וכל הכינויים הישנים וכל הכללים שמתחתיהם נגזרים מהם.
לא שוכפל אף כלל עיצוב.

כדי שזה יעבוד באמת היה צריך לחסל קודם את הצבעים הקשיחים: 27 כללים
עוד החזיקו ערכי hex ישירים — כחולים של מצב regex ושל עוגן, ירוקים של
כפתור האופליין ושל שורות מקושרות, אדומים של שורות יתומות, והרקע הכהה
של בלוק ה-JSON. כולם עברו לתפקידים סמנטיים חדשים (info, success,
warning ו-error על גווניהם, highlight, code) שלכל אחד מהם יש ערך נגדי
בבלוק הכהה. בלי זה היו נשארים כתמים בהירים על רקע כהה.

ברירת המחדל היא העדפת המערכת דרך prefers-color-scheme, והיא מסויגת
ב-:not([data-theme="light"]) כדי שבחירה מפורשת של המשתמש תנצח בשני
הכיוונים. הבחירה נשמרת ב-localStorage בתוך try/catch — בחלון פרטי או
מקובץ file:// הגישה עלולה לזרוק, ואסור שזה יעצור את אתחול הדף.

המתג משתמש ב-ic-sun ו-ic-moon שהוחזרו לספרייט. האייקון מראה לאן
הלחיצה תוביל ולא היכן אנחנו נמצאים: במצב בהיר ירח, במצב כהה שמש.

buildOfflineHtml מסיר כעת את data-theme מהעותק. הסקריפט קובע את
הערכה מחדש בטעינה, ותכונה מקובעת הייתה רק גורמת להבהוב של ערכה אחת
לפני שהאחרת נכנסת.

אייקונים בטור הקישורים
----------------------
ל-.ic יש margin-inline-end לטובת מכלים שאינם flex, והוא אופס עבור
button, .ttl ו-.editorColHd שכבר מרווחים עם gap. .extraLabel נשכח,
והוא inline-flex עם gap:6px — כך שהאייקונים של "טווח" ו"עוגן" בטור
הקישורים קיבלו מרווח כפול. הכלל אוחד ל-:where() אחד שמכסה את ארבעת
המכלים.

אימות
-----
- 0 צבעים קשיחים מחוץ לבלוקי הטוקנים — מה שמבטיח שאין כלל שלא מתהפך.
- לוגיקת הערכה הורצה על הפונקציות האמיתיות בארבעה תרחישים: מערכת
  בהירה, מערכת כהה, העדפה שמורה שמנצחת את המערכת, ו-localStorage
  שזורק. בכולם התוצאה נכונה והדף שורד.
- איזון תגיות: svg 27/27, symbol 16/16, button 17/17; 215/215
  סוגריים ב-CSS; ה-JS עובר new Function.
- מערך בדיקות הקישור הורץ מחדש ועבר ללא שינוי.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants