Skip to content

Remove syntax highlighting from show command - #23

Merged
amirbiron merged 1 commit into
mainfrom
cursor/remove-syntax-highlighting-from-show-command-d159
Aug 6, 2025
Merged

amirbiron merged 1 commit into
mainfrom
cursor/remove-syntax-highlighting-from-show-command-d159

Conversation

@amirbiron

Copy link
Copy Markdown
Owner

Remove syntax highlighting to fix /show command failures caused by Telegram API's lack of support for pygments generated HTML tags.


Open in Cursor Open in Web

Co-authored-by: amirbiron <amirbiron@gmail.com>
@cursor

cursor Bot commented Aug 6, 2025

Copy link
Copy Markdown
Contributor

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

@amirbiron
amirbiron marked this pull request as ready for review August 6, 2025 07:55
@amirbiron
amirbiron merged commit d7071c2 into main Aug 6, 2025
@amirbiron
amirbiron deleted the cursor/remove-syntax-highlighting-from-show-command-d159 branch August 6, 2025 07:55
amirbiron pushed a commit that referenced this pull request Sep 20, 2026
הפטור "נבנה כולו לפני שהוא מתפרסם" בכלל האתחול העצל נבדק על הקוד
שלנו, ולא על אובייקט ספרייה שבונה חלק מעצמו בשימוש הראשון. הדפוס
עצמו נוסף ל-amir-bug-patterns ב-PR #23 שם; השורה כאן היא הצד השני
של אותו צעד — דפוס בלי שורת טריגר הוא דפוס שלא ייקרא בזמן המימוש.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSksrtTEth7eY52jwgYVbb
amirbiron added a commit that referenced this pull request Sep 20, 2026
* feat(mcp): פארסר Markdown ל-docs_get_section, מעל markdown-it-py

services/md_parser.py בונה את אותו מודל סעיפים ש-services/doc_sections.py
מגדיר, כך ש-docs_handlers יוכל לבחור פארסר לפי סיומת ולהמשיך זהה. הפארסר
מתווסף ו**אינו מחווט** לאף כלי — החיווט הוא PR נפרד, ולכן אין כאן שינוי
התנהגות בייצור.

שש ההכרעות שהמדידה קבעה, כל אחת עם טסט שנופל בלי המימוש:

1. רק heading_open עם token.level == 0 נכנס למפה. כותרת בתוך ציטוט או
   פריט רשימה היא חלק מהמכל שלה, והטווח שלה שבור מעצם ההגדרה.
2. ‏\r בודד נדחה לפני הפרסור (InconsistentLineEndings), CRLF עובד במלואו.
   הבדיקה היא על נוכחות ולא על השוואת ספירות: נמדד קלט שבו split("\n")
   ו-splitlines() נותנים אותו מספר בדיוק והכותרת בכל זאת זזה.
3. ה-front matter מטופל על ידי mdit_py_plugins.front_matter — ההגדרה
   ש-MyST מריץ — ולא בכלל שנכתב ביד. נמדד שכלל כזה היה חולק עליה בחמש
   מתוך שלוש-עשרה צורות, ושהתוסף אינו מזיז אף מספר שורה באף צורה.
4. ‏MAX_SECTIONS = 50,000, אותו ערך כמו MAX_SYMBOLS ועם הפניה הדדית
   בהערות, נאכף בתוך הפרסור דרך md.block.ruler עם מונה שאינו סורק טוקן
   פעמיים.
5. עיבוד ה-inline כבוי, והשם נלקח מ-token.content כטקסט גולמי.
6. ‏end_line מחושב ב-_finalize המשותף ולא נלקח מ-token.map, שמכסה את
   שורת הכותרת בלבד.

הראיה היא טבלת אמת מחוללת — 11,507 צורות מול cmark-gfm, כולל קינון
גדרות באותו אורך, בלוקי HTML צמודים ומופרדים, טאבים, ‏:::‏, RLM וכותרות
בתוך מכלים — ובנוסף תשעה קובצי קורפוס אמיתיים. אפס אי-הסכמות, וכך גם על
כל 93 קובצי ה-.md החיים של amir-bug-patterns (1,171 כותרות) דרך
scripts/compare_md_parser_to_cmark.py.

markdown-it-py ו-mdit-py-plugins ננעצים ישירות ב-base.txt (עד היום
markdown-it-py הגיע רק כתלות עקיפה של rich, בטווח פתוח), ו-cmarkgfm נכנס
ל-development.txt בלבד כאורקל.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSksrtTEth7eY52jwgYVbb

* test(mcp): הטסט על התקרה מבחין בין עצירה בפרסור לסינון אחריו

בדיקת מוטציה מצאה שהטענה "התקרה נאכפת בתוך הפרסור" לא הייתה ניתנת
לבדיקה: הסף היה ``stopped_at < total_lines // 2``, ומימוש שמפרסר הכול
ומסנן בסוף היה עובר אותו — כי השער שאחרי הפרסור נשא את שורת הסעיף
החורג, שנראית זהה.

שני תיקונים, והשורש הוא הראשון:

1. השער שאחרי הפרסור מרים ``TooManySections(len(lines))`` — סוף הקובץ,
   כלומר המקום שאליו הפרסור באמת הגיע לפני שסירב. עכשיו שני השערים
   מבדילים את עצמם.
2. הטסט מהדק את הסף ל-21 השורות הראשונות, ונוסף טסט שמראה שהשער השני
   אינו קוד מת: כשהסעיף האחרון יושב בסוף הקובץ ממש, הכלל שבתוך הפרסור
   לעולם אינו רואה אותו.

אחרי התיקון כל שמונה המוטציות מפילות את הטסט שלהן.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSksrtTEth7eY52jwgYVbb

* test(mcp): הסרת קורפוס ה-fixtures — הצורות המחוללות הן הרשת, לא העותק

תשעה קובצי .md הועתקו מ-amir-bug-patterns ל-tests/fixtures/md_corpus/
(224KB) כדי שההשוואה מול cmark-gfm תרוץ על קבצים אמיתיים גם ב-CI. שתי
סיבות להסיר:

1. זה עותק של תוכן ריפו אחר, צילום של קומיט אחד, שאין מה שיעדכן אותו.
2. והחזקה יותר: הקורפוס אינו מה שתופס רגרסיה עתידית. מה שיתפוס שדרוג
   של markdown-it-py שמשנה זיהוי כותרות הוא 11,507 הצורות המחוללות —
   סינתטיות, דטרמיניסטיות, שלוש שניות. קורפוס אמיתי מפעיל **מחלקת
   אזור אחת** (כל 30 מופעי ה-#-שאינו-כותרת שם יושבים בגדרות קוד),
   ולכן 100% עליו הוא ביטחון שווא — וזה בדיוק מה שדוח המדידה אמר.

ה-docstring של קובץ הטסטים אומר עכשיו במפורש שהוא **אינו** מריץ אף
קובץ אמיתי ושזו החלטה, ולא משאיר את זה להיראות כהשמטה.

ההרצה על קורפוס אמיתי עוברת ל-scripts/compare_md_parser_to_cmark.py,
על פי דרישה, עם שלוש הנקודות בזמן שבהן כדאי להריץ אותו. נמדד אחרי
ההסרה: 93 קבצים, 1,171 כותרות, אפס אי-הסכמות — הסקריפט לא נשבר.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSksrtTEth7eY52jwgYVbb

* fix(mcp): טבלת GFM אינה כותרת setext, והנעיצה מיושרת ל-myst-parser

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

1. **הפריסט commonmark משאיר את כלל הטבלאות כבוי, ולכן טבלה שאחריה
   קו צמוד נבלעה לכותרת setext.** נמדד על
   `| a | b |` / `|---|---|` / `| 1 | 2 |` / `---`: נוצר סעיף ברמה 2
   שכותרתו היא **הטבלה כולה**, והסעיף שמעליו נגמר לפני הטבלה במקום
   אחריה — כלומר section_text שלו כבר לא הכיל אותה. cmark-gfm מחזיר
   שלוש כותרות, אנחנו החזרנו ארבע. `enable("table")` מחזיר התאמה
   מדויקת.

   ארבע ההרחבות האחרות של GFM נבדקו ואינן משנות דבר, ולכן נשארות
   כבויות: strikethrough ו-autolink הן inline, tagfilter נוגע ברינדור,
   ו-tasklist משנה פריט רשימה ולא גבול בלוק. הערות שוליים אינן ברשימה
   כלל — github_flavored_markdown_to_html מפעיל חמש הרחבות בדיוק.

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

2. **הנעיצה סתרה קובץ תלויות אחר באותו ריפו.** `myst-parser==4.0.1`
   ב-docs/requirements.txt דורש `markdown-it-py~=3.0` ו-
   `mdit-py-plugins>=0.4.1,~=0.4`, ונמדד שהתקנה משותפת עם 4.2.0 נופלת
   ב-ResolutionImpossible — ו-documentation-py39.yml מתקין את שתי
   הקבוצות לאותה סביבה. הנעיצה ירדה ל-3.0.0 ו-0.4.2, ונמדד שכל 86
   הטסטים כולל 11,507 הצורות מול cmark-gfm עוברים שם בדיוק כמו על
   4.2.0. טסט חדש מקבע את הקשר בין שני הקבצים, וייפול בכוונה ביום
   ששדרגו את myst-parser.

3. **ה-docstring של doc_sections עדיין הצהיר ש-md_parser אינו קיים**,
   בדיוק במודול שנכתב כחוזה המשותף לשניהם. תוקן, ונוסף שם גם ההבדל
   בברירת המחדל של max_sections בין שני הפארסרים.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSksrtTEth7eY52jwgYVbb

* md_parser: תיקוני סקירת הקוד — מרוץ האתחול, התקרה, והמספרים בפרוזה

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

CRIT-001 — המופע המשותף התפרסם לפני ש-markdown-it בנה את טבלאות
הכללים שלו. הוא בונה אותן עצלה בקריאה הראשונה ל-getRules, בלי מנעול,
ו-__compile__ מפרסם מילון ריק לפני שהוא ממלא אותו. הפתרון הוא פרסור
חימום בתוך _build_parser, ולא מניית ה-rulers בשמם — רשימת שמות
מתיישנת ברגע שגרסה עתידית מוסיפה ruler, ואז החלון נפתח שוב בשקט.
נמדד: 8 חוטים ממחסום, מופע טרי בכל איטרציה, 12,800 פרסורים לכל אגף —
105 תוצאות שגויות לפני, אפס אחרי.

WARN-002 — התקרה ספרה רק כותרות ברמת המסמך, ולכן 500KB של כותרות
בתוך ציטוט לא נעצרו כלל. המונה סופר עכשיו כל heading_open, והשער
שאחרי הפרסור קורא את אותו מונה במקום לספור סעיפים — אחרת שני השערים
מודדים שני דברים ונפתח דלף. ב-2MB: 12.5 שניות ו-585MB בלי סירוב
לפני, 2.5 שניות ו-175MB עם סירוב אחרי.

SUGG-010 — האורקל השווה מיקום בלבד. נוספה השוואת טקסט על תת-הקבוצה
שאין בה סימון פנימי, והיא תפסה סטייה אמיתית: הזחת שורת ההמשך בכותרת
setext שרדה אצלנו רק מפני ש-inline מכובה. ה-HTML של markdown-it עצמה
מסיר אותה, וכך גם cmark. _title_of מיישם עכשיו את אותו כלל.

עוד: הסקריפט קורא בבתים ומבודד קובץ שבור; InconsistentLineEndings
נושאת את מספר השורה; heading_open בלי map מרים RuntimeError במקום
להידלג בשקט; בדיקת הנעיצות מעריכה את המפרט האמיתי עם packaging;
ושלושה מספרים בפרוזה נגזרים עכשיו מהקוד בטסט במקום להיות מוקלדים.

SUGG-008 תועד ב-doc_sections במקום לשנות את rst_parser, ופתוח עליו
אישו #3421. שלושת פריטי ה-YAGNI נשארו כפי שהם במכוון.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSksrtTEth7eY52jwgYVbb

* CLAUDE.md: שורת טריגר לדפוס שנתפס בסקירה של #3418

הפטור "נבנה כולו לפני שהוא מתפרסם" בכלל האתחול העצל נבדק על הקוד
שלנו, ולא על אובייקט ספרייה שבונה חלק מעצמו בשימוש הראשון. הדפוס
עצמו נוסף ל-amir-bug-patterns ב-PR #23 שם; השורה כאן היא הצד השני
של אותו צעד — דפוס בלי שורת טריגר הוא דפוס שלא ייקרא בזמן המימוש.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSksrtTEth7eY52jwgYVbb

* CLAUDE.md: ניסוח חדש לשורת הטריגר, ורמז הדדי לשורת import-time

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

ונוסף חצי משפט הדדי בין השורה הזאת לשורה על ברמה העליונה של מודול.
נמדד שעל `client = SDK(api_key=os.environ[...])` ברמת המודול שתיהן
נדלקות, והחדשה יושבת ראשונה בטבלה — כלומר מי שיעצור בה יפספס דווקא
את זו שמדברת על זהות שנלכדת, שהיא HIGH. שתי השורות נשארות נפרדות
כי הן עונות על שתי שאלות שונות; מיזוג לשורה ארוכה מלמד לדלג על
הטבלה. הרמזים מצביעים לפי הטקסט של הצד השמאלי ולא לפי מיקום.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSksrtTEth7eY52jwgYVbb

* md_parser: BOM מוסר בכניסה, פער סוג 7 מקובע ולא מושתק, וטענת הייצוא מצומצמת

ארבעה ממצאי סקירה, כולם אומתו בהרצה:

BOM — קובץ שמתחיל ב-U+FEFF החזיר אפס סעיפים בלי חריגה: מפה ריקה
שמתחזה לקובץ בלי כותרות, בדיוק מחלקת הכשל שהמודול מצהיר שאין בו.
parse_document מסיר עכשיו BOM אחד בתחילת המחרוזת, לפני בדיקת ה-\r.
זה יישור ל-cmark ול-GitHub ולא למפרט: מימוש הייחוס (commonmark.py
0.9.2) אינו מסיר. ההסרה אינה מזיזה מספרי שורות. הייצור לא נפגע
(המראה מפענחת ב-utf-8-sig); הסקריפט נשאר ב-utf-8 בכוונה, כדי
שהפארסר יראה את ה-BOM וייבדק עליו.

סוג 7 — תגית HTML כמו <br> צמודה לשורת פריט רשימה: אצלנו שני
סעיפים, ב-GitHub אחד. markdown-it (הפורט וגם המקור ב-JS 14.3.2)
סוטה מ-cmark-gfm וממימוש הייחוס. לא תוקן ביד — הפיכת דגל ה-terminate
נמדדה ומחליפה פער בפער. במקום זה משפחה מחוללת: חצי הבקרה (עם שורה
ריקה) עובר ב-_compare, החצי הצמוד מקובע כפער מדוד עם אזהרה שנפילה
היא מכוונת, וטסט שלישי מאשר שהמוחרג הוא בדיוק הצורות הצמודות ולא
יותר. "אפס אי-הסכמות" קיבל את ההיקף המדויק בשלושת המקומות, ומספר
הצורות (11,543 + 8 מוחרגות) נגזר בטסט הסחיפה.

linkify — הטענה "autolink לא ב-inline2" לא יכלה ליפול: autolink יושב
ב-inline, והוא כלל CommonMark (<url>) שדלוק ונשאר דלוק. ההרחבה של
GFM היא linkify, בשני rulers; הטענה החדשה נופלת על enable("linkify").

ייצוא — "אותם שמות בדיוק" צומצם למה שנכון: MAX_SECTIONS
ו-InconsistentLineEndings רק מ-md_parser, כי rst_parser אינו מרים
את השנייה לעולם. טסט סחיפה על שני ה-__all__.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSksrtTEth7eY52jwgYVbb

---------

Co-authored-by: Claude <noreply@anthropic.com>
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