PHP | חילוץ טקסט בעברית מקובץ PDF
-
@WWW אמר בPHP | חילוץ טקסט בעברית מקובץ PDF:
זה מוסיף איזה תו בתחילת המחרוזת ובסופה.
אני מדבר על משהו אחר, להפוך סדר התווים מסדר חזותי לסדר לוגי. יש תוכנת שורת הפקודה שעושה את זה, זה נקרא
bidiv
. אני בטוח שיש גם ספריות עבור PHP שיעשו את זה.כל ספרייה שמוציאה טקסט תקין לכאורה עושה את זה. אתה צריך רק למצוא ספרייה שיעשה את זה. או לממש את החלק הזה בעצמך.
אגב, בדקתי עכשיו PDF מוורד 2013, והטקסט מרונדר בתוך ה-PDF הוא בכיוון הפוך (משמאל לימין).
בדקתי גם PDF שהודפסה למדפסת PDF וגם PDF שיוצא ל-PDF באמצעות הייצוא המובנה של וורד. -
@WWW
כאשר יש לך מחרוזת"Hello, עולם!"
, אז יש לתווים סדר חזותי וסדר לוגי, חזותי זה מה שאתה רואה לפניך ולוגי זה הסדר שבו זה נשמר בזכרון המחשב (וזה גם הסדר האמיתי של התווים).1 2 3 4 5 6 7 8 9 10 11 12 סדר לוגי H e l l o , ע ו ל ם ! סדר חזותי קטע LTR ! ע ו ל ם , o l l e H סדר חזותי קטע RTL o l l e H , ע ו ל ם ! אתה מקבל כרגע טקסט שחולץ מתוך ה-PDF עם שתי בעיות: א) זה חולץ משמאל לימין, וב) זה בסדר חזותי ולא בסדר לוגי.
האלגוריתם כדי לסדר את הטקסט לכאורה הוא כדלהלן:
צריך לעבור על כל הקטעים, קטע קטע. על כל קטע להחליט מה אמור להיות הכיוון של הקטע. (איך אתה עושה את זה זה נושא בפני עצמו).
ואז על כל קטע:
א. אם החלטת שזה קטע ימין לשמאל, צריך להפוך את הסדר של התווים --strrev()
ב. בכל מקרה צריך להריץ את הקטע שורה שורה לפונקציה שמקבלת סדר חזותי ומחזירה סדר לוגי.- לקטע ימין לשמאל:
fribidi_log2vis ( $str , FRIBIDI_RTL , FRIBIDI_CHARSET_UTF8 )
- לקטע שמאל לימין:
fribidi_log2vis ( $str , FRIBIDI_LTR , FRIBIDI_CHARSET_UTF8 )
(בעצם הפונקציה הנ"ל עושה בדיוק הפוך, מקבלת סדר לוגי ומחזירה סדר חזותי. אבל אאל"ט האלגוריתם אמור לעבוד גם בכיוון ההפוך)
- לקטע ימין לשמאל:
-
@yossiz תודה רבה!
-
הפונקציה הזאת מצוינת! היא ממירה אוטומטית את הסדר של התווים (רוורס). מעניין שאין אזכור לזה ברשת..
-
יש לה אופציה לדגל FRIBIDI_AUTO במקום RTL, ככה שזה אמור להיות אוטומטי (זה לא מושלם בכלל).
-
הפונקציה אינה כלולה ב PHP ברירת מחדל, צריך לבנות את הספריה fribidi ואח"כ לרשום את התוסף ב PHP.INI.
-
זה עדיין לא מושלם בכלל
-
-
@WWW אמר בPHP | חילוץ טקסט בעברית מקובץ PDF:
יש לה אופציה לדגל FRIBIDI_AUTO במקום RTL, ככה שזה אמור להיות אוטומטי (זה לא מושלם בכלל).
אל תשתמש באופציית FRIBIDI_AUTO. זה טוב רק בכיוון של לוגי לוויזואלי, אבל בכיוון ההפוך אתה מוסר לפונקציה שורות - לא קטעים שלמים, וזה לא יזהה את הכיוון נכון. (חוץ מזה שזה לא תמיד מזהה את הכיוון הנכון.)
-
@WWW אמר בPHP | חילוץ טקסט בעברית מקובץ PDF:
אז איך זה כן עובד?
ולמה זה אוטומטית הופך את סדר התווים?לא כל כך הבנתי מה אתה שואל אבל אני אסביר יותר מה התכוונתי.
מה זה אופציות אלו FRIBIDI_XXXX?
זה קובע את כיוון הבסיס של הקטע. בטקסט דו כיווני יש תווים שאין להם אורינטציה כיוונית מובהקת והכיוון שלהם נקבע לפי כוון הבסיס של הקטע.
FRIBIDI_RTL אומר לפונקציה שכיוון הבסיס הוא RTL.
AUTO אומר לקבוע את הכיוון לפי התו הראשון בקטע שיש לו כיוון מובהק (לאפוקי פיסוק וכו').
אופציית AUTO יכול לעבוד רק אם נותנים לפונקציה קטע שלם. אין הגיון לקבוע את הכיוון לכל שורה בפני עצמה לפי התו הראשון של השורה.
מכיוון שאתה חייב לעבוד שורה שורה ולא בקטעים שלמים, (כי יש לך טקסט בסדר וויזואלי שזה מפוסק על ידי מעבר שורה, הבנת? אין לי כח להסביר יותר...) לכן אתה לא יכול להשתמש באופצית AUTO.
חוץ מזה, בכללות לא מומלץ להשתמש באופציה האוטומטית אם יש לך דרך אחר לדעת את הכוון הנכון כי האוטומטי לא תמיד מזהה נכון. (ע"ע כווני הקטעים בפורום אתמול). -
אני רואה שעשיתי טעות.
חשבתי שבקטע RTL הפונקציה יביא סדר חזותי מימין לשמאל. למעשה לפי מה שאתה אומר זה מביא את הסדר משמאל לימין.יש דבר שאני לא מבין,
@WWW אמר בPHP | חילוץ טקסט בעברית מקובץ PDF:במקור זה מופיע כך:
Hello !םלוע ,למה? זה לא סדר וויזואלי, אולי זה הסדר של הרינדור ב-PDF? אתה יכול להעלות את ה-PDF?
-
@yossiz אמר בPHP | חילוץ טקסט בעברית מקובץ PDF:
אולי זה הסדר של הרינדור ב-PDF?
זה בדיוק עיקר הבעיה עם קריאה של PDF, כנראה כל מיני צורות של ספריות שאחראיות לסגירה. לא יודע מה במקרה הזה, אבל עבדתי עם מסמכים (לועזית) שהטקסט היה מאונך וכל מיני טריקים הזויים. היה ממש קשה נורא לקחת אפילו שתי תוים אחד ליד השני ובזמנו הוצאתי לפי מיקום עם rectangles שעשיתי לפי השורות.
-
@WWW אמר בPHP | חילוץ טקסט בעברית מקובץ PDF:
עדיין יש קצת בעיות עם תווים בלתי מזוהים.
גם עם זה הסתדתי ב"ה, עם זה: https://stackoverflow.com/a/3466049
/** * Removes invalid XML * * @access public * @param string $value * @return string */ function stripInvalidXml($value) { $ret = ""; $current;// למחוק גורם לשגיאה. if (empty($value)) { return $ret; } $length = strlen($value); for ($i=0; $i < $length; $i++) { $current = ord($value{$i}); if (($current == 0x9) || ($current == 0xA) || ($current == 0xD) || (($current >= 0x20) && ($current <= 0xD7FF)) || (($current >= 0xE000) && ($current <= 0xFFFD)) || (($current >= 0x10000) && ($current <= 0x10FFFF))) { $ret .= chr($current); } else { $ret .= " "; } } return $ret; }