דילוג לתוכן
  • חוקי הפורום
  • לא נפתר
  • משתמשים
  • חיפוש גוגל בפורום
  • צור קשר
עיצובים
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • ברירת מחדל (ללא עיצוב (ברירת מחדל))
  • ללא עיצוב (ברירת מחדל)
כיווץ
לוגו מותג
  1. דף הבית
  2. מחשבים וטכנולוגיה
  3. עזרה הדדית - מחשבים וטכנולוגיה
  4. בירור | תגובה: איך לעשות שCMD יכתוב בעברית

בירור | תגובה: איך לעשות שCMD יכתוב בעברית

מתוזמן נעוץ נעול הועבר עזרה הדדית - מחשבים וטכנולוגיה
25 פוסטים 7 כותבים 608 צפיות 7 Watching
  • מהישן לחדש
  • מהחדש לישן
  • הכי הרבה הצבעות
תגובה
  • תגובה כנושא
התחברו כדי לפרסם תגובה
נושא זה נמחק. רק משתמשים עם הרשאות מתאימות יוכלו לצפות בו.
  • מ מנותק
    מ מנותק
    מתלמד צעיר
    כתב נערך לאחרונה על ידי מתלמד צעיר
    #1

    תגובה: איך לעשות שCMD יכתוב בעברית

    @amit5470 כתב באיך לעשות שCMD יכתוב בעברית:

    Rev.bat

    האם יש כזה קובץ שהופך טקסט בהתאם ל"כיווניות" שלו?
    כלומר שרק החלק שבטקסט שהוא בעברית יתהפך אבל לא החלק שבאנגלית?
    אחרת זה נראה ככה:

    3pm.)1(אודיו
    
    3pm.פרק 92- המבחן של המדינה\sdaolnwoD\resu\sresU\:C הקובץ
    
    י צ נ נחנ 3 תגובות תגובה אחרונה
    1
    • מ מתלמד צעיר

      תגובה: איך לעשות שCMD יכתוב בעברית

      @amit5470 כתב באיך לעשות שCMD יכתוב בעברית:

      Rev.bat

      האם יש כזה קובץ שהופך טקסט בהתאם ל"כיווניות" שלו?
      כלומר שרק החלק שבטקסט שהוא בעברית יתהפך אבל לא החלק שבאנגלית?
      אחרת זה נראה ככה:

      3pm.)1(אודיו
      
      3pm.פרק 92- המבחן של המדינה\sdaolnwoD\resu\sresU\:C הקובץ
      
      י מנותק
      י מנותק
      ישראל בוכבינדר
      כתב נערך לאחרונה על ידי
      #2

      @מתלמד-צעיר זה הבעיה (עם ה הידיעה) של כל האתרים הקיימים...
      כל מי שכותב פוסט בלינקדאין נתקל בזה בלי סוף
      אני הייתי מנסה לכתוב בוורד ששם יש לך יותר שליטה ואז לגזור ולהדביק בCMD
      או בקידודים אחרים (לא UTF-8) כמו CP1255
      וגם יש את היבוא המפורסם של עברית לCMD זה נקרא CHCP 1255 כל זה אני זורק סתם מהזיכרון אז הכל בעירבון מוגבל

      מ תגובה 1 תגובה אחרונה
      1
      • י ישראל בוכבינדר

        @מתלמד-צעיר זה הבעיה (עם ה הידיעה) של כל האתרים הקיימים...
        כל מי שכותב פוסט בלינקדאין נתקל בזה בלי סוף
        אני הייתי מנסה לכתוב בוורד ששם יש לך יותר שליטה ואז לגזור ולהדביק בCMD
        או בקידודים אחרים (לא UTF-8) כמו CP1255
        וגם יש את היבוא המפורסם של עברית לCMD זה נקרא CHCP 1255 כל זה אני זורק סתם מהזיכרון אז הכל בעירבון מוגבל

        מ מנותק
        מ מנותק
        מתלמד צעיר
        כתב נערך לאחרונה על ידי
        #3

        @ישראל-בוכבינדר כתב בבירור | תגובה: איך לעשות שCMD יכתוב בעברית:

        וגם יש את היבוא המפורסם של עברית לCMD זה נקרא CHCP 1255 כל זה אני זורק סתם מהזיכרון אז הכל בעירבון מוגבל

        זה אני מכיר ויישמתי
        זה לא פותר את ימין ושמאל
        rev.bat פותר את זה אבל לא כאשר מעורב בטקסט גם עברית וגם אנגלית

        א תגובה 1 תגובה אחרונה
        1
        • מ מתלמד צעיר

          @ישראל-בוכבינדר כתב בבירור | תגובה: איך לעשות שCMD יכתוב בעברית:

          וגם יש את היבוא המפורסם של עברית לCMD זה נקרא CHCP 1255 כל זה אני זורק סתם מהזיכרון אז הכל בעירבון מוגבל

          זה אני מכיר ויישמתי
          זה לא פותר את ימין ושמאל
          rev.bat פותר את זה אבל לא כאשר מעורב בטקסט גם עברית וגם אנגלית

          א מנותק
          א מנותק
          ארץ הצבי
          מורחק
          כתב נערך לאחרונה על ידי ארץ הצבי
          #4

          @מתלמד-צעיר

          https://aseleha.wordpress.com/2018/10/10/שמאל-ימין-שמאל-הצגת-טקסט-משולב-בעברית-ו/

          תגובה 1 תגובה אחרונה
          1
          • מ מתלמד צעיר

            תגובה: איך לעשות שCMD יכתוב בעברית

            @amit5470 כתב באיך לעשות שCMD יכתוב בעברית:

            Rev.bat

            האם יש כזה קובץ שהופך טקסט בהתאם ל"כיווניות" שלו?
            כלומר שרק החלק שבטקסט שהוא בעברית יתהפך אבל לא החלק שבאנגלית?
            אחרת זה נראה ככה:

            3pm.)1(אודיו
            
            3pm.פרק 92- המבחן של המדינה\sdaolnwoD\resu\sresU\:C הקובץ
            
            צ מנותק
            צ מנותק
            צללית
            כתב נערך לאחרונה על ידי צללית
            #5

            @מתלמד-צעיר
            לאחר הלוך-ושוב מיגע עם הבינה [היא ממש גרועה בקבצי BAT]
            rev_hebrew.bat
            תוריד את כל ההדפסות המיותרות שנעשו לצורך בדיקות
            עריכה: זה לא מושלם עדיין, אם יהיה לי אפשרות אתקן בהמשך בלנ"ד.
            @NH-LOCAL כמרא דשמעתא גם של בינה וגם של BAT אולי אתה תוכל לעזור?

            NH.LOCALN מ 2 תגובות תגובה אחרונה
            1
            • צ צללית

              @מתלמד-צעיר
              לאחר הלוך-ושוב מיגע עם הבינה [היא ממש גרועה בקבצי BAT]
              rev_hebrew.bat
              תוריד את כל ההדפסות המיותרות שנעשו לצורך בדיקות
              עריכה: זה לא מושלם עדיין, אם יהיה לי אפשרות אתקן בהמשך בלנ"ד.
              @NH-LOCAL כמרא דשמעתא גם של בינה וגם של BAT אולי אתה תוכל לעזור?

              NH.LOCALN מנותק
              NH.LOCALN מנותק
              NH.LOCAL
              מדריכים
              כתב נערך לאחרונה על ידי NH.LOCAL
              #6

              @צללית לי אישית יש סקריפט בדיוק בשביל זה:
              https://mitmachim.top/post/461914

              אבל זה לא פותר את הבעיה של פותח הנושא באופן מלא.

              לאינדקס המלא של כלל הסקריפטים שלי
              https://nhlocal.github.io

              תגובה 1 תגובה אחרונה
              0
              • צ צללית

                @מתלמד-צעיר
                לאחר הלוך-ושוב מיגע עם הבינה [היא ממש גרועה בקבצי BAT]
                rev_hebrew.bat
                תוריד את כל ההדפסות המיותרות שנעשו לצורך בדיקות
                עריכה: זה לא מושלם עדיין, אם יהיה לי אפשרות אתקן בהמשך בלנ"ד.
                @NH-LOCAL כמרא דשמעתא גם של בינה וגם של BAT אולי אתה תוכל לעזור?

                מ מנותק
                מ מנותק
                מתלמד צעיר
                כתב נערך לאחרונה על ידי
                #7

                @צללית זה טוב להרצה מתוך סקריפט אחר כמו rev המקורי?

                צ תגובה 1 תגובה אחרונה
                1
                • מ מתלמד צעיר

                  @צללית זה טוב להרצה מתוך סקריפט אחר כמו rev המקורי?

                  צ מנותק
                  צ מנותק
                  צללית
                  כתב נערך לאחרונה על ידי צללית
                  #8

                  @מתלמד-צעיר כן, זה מבוסס עליו רק עם שינויים
                  אבל יש בזה בעיה שכשיש עברית ואנגלית זה אמנם הופך רק את העברית אבל הסדר של העברית והאנגלית בתוך הטקסט הכולל לא נשמר.
                  עריכה: לאחר לופ אינסופי עם הבינה שלא הצליחה לפתור את הבעיה, נאלצתי להפעיל את הבינה שלי...
                  הענין סודר.
                  הנה הקובץ המתוקן [לא היה לי כח לשנות את כל הקוד הקודם אז רק הוספתי שם משתנים חדשים ע"ש].
                  תמחק את כל הלוגים ותן לו להחזיר רק את התוצאה הסופית שנמצאת במשתנה res
                  rev_hebrew.bat
                  מה שכן כדי שזה יעבוד אני חושב שחייבים להריץ קודם את chcp 1255 ולוודא שכשאתה שומר את הקובץ rev_hebrew.bat אחר השינויים זה יהיה בקידוד ansi

                  תגובה 1 תגובה אחרונה
                  2
                  • מ מתלמד צעיר

                    תגובה: איך לעשות שCMD יכתוב בעברית

                    @amit5470 כתב באיך לעשות שCMD יכתוב בעברית:

                    Rev.bat

                    האם יש כזה קובץ שהופך טקסט בהתאם ל"כיווניות" שלו?
                    כלומר שרק החלק שבטקסט שהוא בעברית יתהפך אבל לא החלק שבאנגלית?
                    אחרת זה נראה ככה:

                    3pm.)1(אודיו
                    
                    3pm.פרק 92- המבחן של המדינה\sdaolnwoD\resu\sresU\:C הקובץ
                    
                    נ נחנ מנותק
                    נ נחנ מנותק
                    נ נח
                    כתב נערך לאחרונה על ידי
                    #9

                    @מתלמד-צעיר עשיתי תוכנה בHaskell, ונראה לי שזה עובד טוב ב"ה

                    hecho.exe

                    יש שתי אפשרויות:

                    1. היפוך כל הסדר של הטקסט (עם הארגומנט -a)
                    2. היפוך המילים בעברית בלבד (עם הארגומנט -b)

                    דוגמאות לשימוש:

                    hecho -a "שלום, hi עולם!"
                    

                    be58a2b2-97e0-40fb-a740-0868be5999db-image.png

                    hecho -b "C:\Users\User\Downloads\מסמך טקסט חדש (2).txt"
                    

                    d7b7047e-a4f0-4278-a1d4-de14169fbc93-image.png

                    זה הקוד: (עשיתי עם GPT ואני עדיין לא מבין הרבה חלקים בקוד)

                    import System.Environment (getArgs)
                    import Control.Monad (when)
                    import Data.Char (isAlpha, isAsciiLower, isAsciiUpper)
                    import Data.Maybe (fromMaybe)
                    
                    -- הגדרות לסיווג תו לפי שפה
                    isHebrew :: Char -> Bool
                    isHebrew c = c >= 'א' && c <= 'ת'
                    
                    isEnglish :: Char -> Bool
                    isEnglish c = isAsciiLower c || isAsciiUpper c
                    
                    -- מחזירה Just "Hebrew" או Just "English" עבור אות, או Nothing עבור סימן פיסוק/רווח
                    charLang :: Char -> Maybe String
                    charLang c
                      | isHebrew c  = Just "Hebrew"
                      | isEnglish c = Just "English"
                      | otherwise   = Nothing
                    
                    ------------------------------------------------------------
                    -- טיפוסי טוקנים: טוקן אות – כולל מחרוזת ותווית שפה;
                    -- טוקן פיסוק/רווח
                    data Token = Letter { content :: String, lang :: String }
                               | Punct  { content :: String }
                               deriving (Show)
                    
                    -- פונקציה שמפצלת מחרוזת לרשימת טוקנים:
                    -- קבוצות רציפות של אותיות (אותן מסווגים לפי charLang) או קבוצות של סימני פיסוק/רווח
                    tokenize :: String -> [Token]
                    tokenize "" = []
                    tokenize s@(c:_)
                      | isAlpha c =
                          let (letters, rest) = span (\ch -> isAlpha ch && charLang ch == charLang c) s
                          in Letter letters (fromMaybe "" (charLang c)) : tokenize rest
                      | otherwise =
                          let (punct, rest) = break isAlpha s
                          in Punct punct : tokenize rest
                    
                    ------------------------------------------------------------
                    -- מצב סגמנטציה: בשיטה זו נבצע הקצאה מחדש של סימני פיסוק בגבולות בלוקים.
                    -- במצב SegHebrew – target היא "Hebrew"
                    -- במצב SegEnglish – target היא "English"
                    data SegMode = SegHebrew | SegEnglish deriving (Eq, Show)
                    
                    -- עוזרת: האם שפה נתונה היא target בהתאם למצב הסגמנטציה
                    isTarget :: SegMode -> String -> Bool
                    isTarget SegHebrew l = l == "Hebrew"
                    isTarget SegEnglish l = l == "English"
                    
                    -- נרצה לאסוף טוקנים לכדי בלוקים (מחרוזות) כך שהטוקנים המקוריים לא ישתנו,
                    -- אך סימני הפיסוק שבגבולות יועברו בהתאם לכלל הבא:
                    --
                    -- נניח שיש לנו גבול בין טוקן אות (T_prev) לטוקן אות (T_next) עם טוקני פיסוק ביניהם (PunctSeq).
                    -- אז:
                    -- • אם T_prev ו–T_next שונות בשייכות target, נחלק את PunctSeq לשניים:
                    --   - במצב SegHebrew (target = Hebrew): אם T_prev הוא target (Hebrew) ו–T_next אינו, נרצה שהתוצאה תהיה:
                    --         בלוק target: T_prev בלבד,
                    --         בלוק non-target: (PunctSeq עם הסימן האחרון מופיע בסופו) <> T_next...
                    --   - במצב SegEnglish (target = English): אם T_prev אינו target וה–T_next הוא target, אזי
                    --         בלוק non-target: T_prev <> (PunctSeq עם הסימן הראשון בסופו),
                    --         בלוק target: T_next...
                    -- • במקרים בהם שני הטוקנים הם מאותה קטגוריה – פשוט מצרפים את הפיסוק לטוקן הקודם.
                    --
                    -- בפועל, נממש פונקציה שמסכמת את רשימת הטוקנים ומעבירה את סימני הפיסוק בהתאם.
                    reassemble :: SegMode -> [Token] -> [String]
                    reassemble mode toks = mergeBlocks (assignPunct mode toks)
                      where
                        -- assignPunct מעבירה סימני פיסוק בגבולות לפי הכלל הפשוט הבא:
                        assignPunct :: SegMode -> [Token] -> [Token]
                        assignPunct _ [] = []
                        assignPunct _ [t] = [t]
                        assignPunct m (t1 : Punct punc : t2 : rest) =
                          case (t1, t2) of
                            (Letter _ l1, Letter _ l2) 
                              | isTarget m l1 || isTarget m l2 ->
                                  -- במקרה של גבול target–non-target
                                  if isTarget m l1 && not (isTarget m l2)
                                     then -- במצב SegHebrew: אם הטוקן השמאלי הוא target, העבר את כל הפיסוק לבלוק הימני
                                          t1 : assignPunct m (Letter punc l2 : t2 : rest)
                                     else if not (isTarget m l1) && isTarget m l2
                                          then -- במצב SegEnglish: אם הטוקן הימני הוא target, העבר את כל הפיסוק לבלוק השמאלי
                                               let newT1 = Letter (content t1 ++ punc) l1
                                               in newT1 : assignPunct m (t2 : rest)
                                          else
                                               -- אם שני הצדדים target או שניהם non-target – צרף לפסיק ל-T_prev
                                               let newT1 = Letter (content t1 ++ punc) (lang t1)
                                               in newT1 : assignPunct m (t2 : rest)
                            _ -> t1 : assignPunct m (Punct punc : t2 : rest)
                        assignPunct m (t:rest) = t : assignPunct m rest
                    
                        -- mergeBlocks פשוט ממזג טוקנים עוקבים לשרשרת אחת (מבוסס על content)
                        mergeBlocks :: [Token] -> [String]
                        mergeBlocks [] = []
                        mergeBlocks (t:ts) = let (grp, rest) = span (sameType t) ts
                                                 block = concatMap content (t:grp)
                                             in block : mergeBlocks rest
                          where
                            sameType :: Token -> Token -> Bool
                            sameType (Letter _ l1) (Letter _ l2) = l1 == l2
                            sameType (Punct _) (Punct _) = True
                            -- לא ממזג בין אות לפיסוק
                            sameType _ _ = False
                    
                    ------------------------------------------------------------
                    -- פונקציות עיבוד טקסט:
                    --
                    -- במצב all:
                    -- 1. הופכים את כל הטקסט (reverse)
                    -- 2. מפצלים לבלוקים בעזרת reassemble במצב SegEnglish
                    -- 3. בתוך הרשימה, בלוקים ששייכים לאנגלית (target במצב SegEnglish) חוזרים הפיכה כדי לשחזר את הסדר המקורי.
                    processAll :: String -> String
                    processAll s =
                      let revText = reverse s
                          toks = tokenize revText
                          blocks = reassemble SegEnglish toks
                          fixed = map (\blk -> if any isEnglish blk then reverse blk else blk) blocks
                      in concat fixed
                    
                    -- במצב blocks:
                    -- מפצלים לבלוקים בעזרת reassemble במצב SegHebrew
                    -- ואז הופכים רק את הבלוקים בהם מופיעות אותיות בעברית.
                    processBlocks :: String -> String
                    processBlocks s =
                      let toks = tokenize s
                          blocks = reassemble SegHebrew toks
                          fixed = map (\blk -> if any isHebrew blk then reverse blk else blk) blocks
                      in concat fixed
                    
                    -- Add helper function to remove invisible characters.
                    removeInvisible :: String -> String
                    removeInvisible = filter (\c -> c /= '\x200F' && c /= '\x202B')
                    
                    main :: IO ()
                    main = do
                      args <- getArgs
                      when (length args >= 2) $ do
                        let (flag:rest) = args
                            txt = removeInvisible $ unwords rest  -- remove invisible characters from input
                        case flag of
                          "-a" -> putStrLn $ processAll txt
                          "-b" -> putStrLn $ processBlocks txt
                          _ -> return ()
                    

                    מ תגובה 1 תגובה אחרונה
                    3
                    • נ נחנ נ נח

                      @מתלמד-צעיר עשיתי תוכנה בHaskell, ונראה לי שזה עובד טוב ב"ה

                      hecho.exe

                      יש שתי אפשרויות:

                      1. היפוך כל הסדר של הטקסט (עם הארגומנט -a)
                      2. היפוך המילים בעברית בלבד (עם הארגומנט -b)

                      דוגמאות לשימוש:

                      hecho -a "שלום, hi עולם!"
                      

                      be58a2b2-97e0-40fb-a740-0868be5999db-image.png

                      hecho -b "C:\Users\User\Downloads\מסמך טקסט חדש (2).txt"
                      

                      d7b7047e-a4f0-4278-a1d4-de14169fbc93-image.png

                      זה הקוד: (עשיתי עם GPT ואני עדיין לא מבין הרבה חלקים בקוד)

                      import System.Environment (getArgs)
                      import Control.Monad (when)
                      import Data.Char (isAlpha, isAsciiLower, isAsciiUpper)
                      import Data.Maybe (fromMaybe)
                      
                      -- הגדרות לסיווג תו לפי שפה
                      isHebrew :: Char -> Bool
                      isHebrew c = c >= 'א' && c <= 'ת'
                      
                      isEnglish :: Char -> Bool
                      isEnglish c = isAsciiLower c || isAsciiUpper c
                      
                      -- מחזירה Just "Hebrew" או Just "English" עבור אות, או Nothing עבור סימן פיסוק/רווח
                      charLang :: Char -> Maybe String
                      charLang c
                        | isHebrew c  = Just "Hebrew"
                        | isEnglish c = Just "English"
                        | otherwise   = Nothing
                      
                      ------------------------------------------------------------
                      -- טיפוסי טוקנים: טוקן אות – כולל מחרוזת ותווית שפה;
                      -- טוקן פיסוק/רווח
                      data Token = Letter { content :: String, lang :: String }
                                 | Punct  { content :: String }
                                 deriving (Show)
                      
                      -- פונקציה שמפצלת מחרוזת לרשימת טוקנים:
                      -- קבוצות רציפות של אותיות (אותן מסווגים לפי charLang) או קבוצות של סימני פיסוק/רווח
                      tokenize :: String -> [Token]
                      tokenize "" = []
                      tokenize s@(c:_)
                        | isAlpha c =
                            let (letters, rest) = span (\ch -> isAlpha ch && charLang ch == charLang c) s
                            in Letter letters (fromMaybe "" (charLang c)) : tokenize rest
                        | otherwise =
                            let (punct, rest) = break isAlpha s
                            in Punct punct : tokenize rest
                      
                      ------------------------------------------------------------
                      -- מצב סגמנטציה: בשיטה זו נבצע הקצאה מחדש של סימני פיסוק בגבולות בלוקים.
                      -- במצב SegHebrew – target היא "Hebrew"
                      -- במצב SegEnglish – target היא "English"
                      data SegMode = SegHebrew | SegEnglish deriving (Eq, Show)
                      
                      -- עוזרת: האם שפה נתונה היא target בהתאם למצב הסגמנטציה
                      isTarget :: SegMode -> String -> Bool
                      isTarget SegHebrew l = l == "Hebrew"
                      isTarget SegEnglish l = l == "English"
                      
                      -- נרצה לאסוף טוקנים לכדי בלוקים (מחרוזות) כך שהטוקנים המקוריים לא ישתנו,
                      -- אך סימני הפיסוק שבגבולות יועברו בהתאם לכלל הבא:
                      --
                      -- נניח שיש לנו גבול בין טוקן אות (T_prev) לטוקן אות (T_next) עם טוקני פיסוק ביניהם (PunctSeq).
                      -- אז:
                      -- • אם T_prev ו–T_next שונות בשייכות target, נחלק את PunctSeq לשניים:
                      --   - במצב SegHebrew (target = Hebrew): אם T_prev הוא target (Hebrew) ו–T_next אינו, נרצה שהתוצאה תהיה:
                      --         בלוק target: T_prev בלבד,
                      --         בלוק non-target: (PunctSeq עם הסימן האחרון מופיע בסופו) <> T_next...
                      --   - במצב SegEnglish (target = English): אם T_prev אינו target וה–T_next הוא target, אזי
                      --         בלוק non-target: T_prev <> (PunctSeq עם הסימן הראשון בסופו),
                      --         בלוק target: T_next...
                      -- • במקרים בהם שני הטוקנים הם מאותה קטגוריה – פשוט מצרפים את הפיסוק לטוקן הקודם.
                      --
                      -- בפועל, נממש פונקציה שמסכמת את רשימת הטוקנים ומעבירה את סימני הפיסוק בהתאם.
                      reassemble :: SegMode -> [Token] -> [String]
                      reassemble mode toks = mergeBlocks (assignPunct mode toks)
                        where
                          -- assignPunct מעבירה סימני פיסוק בגבולות לפי הכלל הפשוט הבא:
                          assignPunct :: SegMode -> [Token] -> [Token]
                          assignPunct _ [] = []
                          assignPunct _ [t] = [t]
                          assignPunct m (t1 : Punct punc : t2 : rest) =
                            case (t1, t2) of
                              (Letter _ l1, Letter _ l2) 
                                | isTarget m l1 || isTarget m l2 ->
                                    -- במקרה של גבול target–non-target
                                    if isTarget m l1 && not (isTarget m l2)
                                       then -- במצב SegHebrew: אם הטוקן השמאלי הוא target, העבר את כל הפיסוק לבלוק הימני
                                            t1 : assignPunct m (Letter punc l2 : t2 : rest)
                                       else if not (isTarget m l1) && isTarget m l2
                                            then -- במצב SegEnglish: אם הטוקן הימני הוא target, העבר את כל הפיסוק לבלוק השמאלי
                                                 let newT1 = Letter (content t1 ++ punc) l1
                                                 in newT1 : assignPunct m (t2 : rest)
                                            else
                                                 -- אם שני הצדדים target או שניהם non-target – צרף לפסיק ל-T_prev
                                                 let newT1 = Letter (content t1 ++ punc) (lang t1)
                                                 in newT1 : assignPunct m (t2 : rest)
                              _ -> t1 : assignPunct m (Punct punc : t2 : rest)
                          assignPunct m (t:rest) = t : assignPunct m rest
                      
                          -- mergeBlocks פשוט ממזג טוקנים עוקבים לשרשרת אחת (מבוסס על content)
                          mergeBlocks :: [Token] -> [String]
                          mergeBlocks [] = []
                          mergeBlocks (t:ts) = let (grp, rest) = span (sameType t) ts
                                                   block = concatMap content (t:grp)
                                               in block : mergeBlocks rest
                            where
                              sameType :: Token -> Token -> Bool
                              sameType (Letter _ l1) (Letter _ l2) = l1 == l2
                              sameType (Punct _) (Punct _) = True
                              -- לא ממזג בין אות לפיסוק
                              sameType _ _ = False
                      
                      ------------------------------------------------------------
                      -- פונקציות עיבוד טקסט:
                      --
                      -- במצב all:
                      -- 1. הופכים את כל הטקסט (reverse)
                      -- 2. מפצלים לבלוקים בעזרת reassemble במצב SegEnglish
                      -- 3. בתוך הרשימה, בלוקים ששייכים לאנגלית (target במצב SegEnglish) חוזרים הפיכה כדי לשחזר את הסדר המקורי.
                      processAll :: String -> String
                      processAll s =
                        let revText = reverse s
                            toks = tokenize revText
                            blocks = reassemble SegEnglish toks
                            fixed = map (\blk -> if any isEnglish blk then reverse blk else blk) blocks
                        in concat fixed
                      
                      -- במצב blocks:
                      -- מפצלים לבלוקים בעזרת reassemble במצב SegHebrew
                      -- ואז הופכים רק את הבלוקים בהם מופיעות אותיות בעברית.
                      processBlocks :: String -> String
                      processBlocks s =
                        let toks = tokenize s
                            blocks = reassemble SegHebrew toks
                            fixed = map (\blk -> if any isHebrew blk then reverse blk else blk) blocks
                        in concat fixed
                      
                      -- Add helper function to remove invisible characters.
                      removeInvisible :: String -> String
                      removeInvisible = filter (\c -> c /= '\x200F' && c /= '\x202B')
                      
                      main :: IO ()
                      main = do
                        args <- getArgs
                        when (length args >= 2) $ do
                          let (flag:rest) = args
                              txt = removeInvisible $ unwords rest  -- remove invisible characters from input
                          case flag of
                            "-a" -> putStrLn $ processAll txt
                            "-b" -> putStrLn $ processBlocks txt
                            _ -> return ()
                      

                      מ מנותק
                      מ מנותק
                      מתלמד צעיר
                      כתב נערך לאחרונה על ידי
                      #10

                      @נ-נח זה ממש ממש מוצלח!
                      רק הצעה חשובה לשיפור
                      את ה-rev היה אפשר להכניס אחרי שורת פעולה לביצוע וכך תוצאת השורה היתה מודפסת כראוי

                      move "123.txt" "פנימי"  |rev
                      move "456.txt" "פנימי"  |hecho -b
                      

                      ייתן את התוצאה

                      C:\Users\user\Downloads>move "123.txt" "פנימי"    | rev
                      .devom )s(elif 1
                      
                      C:\Users\user\Downloads>move "456.txt" "פנימי"    | hecho -b
                      
                      
                      נ נחנ תגובה 1 תגובה אחרונה
                      2
                      • מ מתלמד צעיר

                        @נ-נח זה ממש ממש מוצלח!
                        רק הצעה חשובה לשיפור
                        את ה-rev היה אפשר להכניס אחרי שורת פעולה לביצוע וכך תוצאת השורה היתה מודפסת כראוי

                        move "123.txt" "פנימי"  |rev
                        move "456.txt" "פנימי"  |hecho -b
                        

                        ייתן את התוצאה

                        C:\Users\user\Downloads>move "123.txt" "פנימי"    | rev
                        .devom )s(elif 1
                        
                        C:\Users\user\Downloads>move "456.txt" "פנימי"    | hecho -b
                        
                        
                        נ נחנ מנותק
                        נ נחנ מנותק
                        נ נח
                        כתב נערך לאחרונה על ידי
                        #11

                        @מתלמד-צעיר עכשיו זה תומך בצינורות

                        hecho.exe

                        אבל אם זה טקסט עם כמה שורות אז זה לא עובד טוב..

                        מ תגובה 1 תגובה אחרונה
                        1
                        • נ נחנ נ נח

                          @מתלמד-צעיר עכשיו זה תומך בצינורות

                          hecho.exe

                          אבל אם זה טקסט עם כמה שורות אז זה לא עובד טוב..

                          מ מנותק
                          מ מנותק
                          מתלמד צעיר
                          כתב נערך לאחרונה על ידי מתלמד צעיר
                          #12

                          @נ-נח גוגל החל לזהות את זה כתוכנה חשודה
                          אתה יכול בבקשה להעלות את זה כארכיון (אולי אפי' עם סיסמא?)

                          עריכה: hecho.zip סיסמא 1234

                          נ נחנ תגובה 1 תגובה אחרונה
                          0
                          • מ מתלמד צעיר

                            @נ-נח גוגל החל לזהות את זה כתוכנה חשודה
                            אתה יכול בבקשה להעלות את זה כארכיון (אולי אפי' עם סיסמא?)

                            עריכה: hecho.zip סיסמא 1234

                            נ נחנ מנותק
                            נ נחנ מנותק
                            נ נח
                            כתב נערך לאחרונה על ידי
                            #13

                            @מתלמד-צעיר כתב בבירור | תגובה: איך לעשות שCMD יכתוב בעברית:

                            @נ-נח גוגל החל לזהות את זה כתוכנה חשודה

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

                            type file.txt | hecho -a
                            

                            hecho.rar סיסמא: 123
                            אתה יכול כמובן לשנות את השם של התוכנה לrev אם אתה מעדיף

                            הקוד

                            import System.Environment (getArgs)
                            import Control.Monad (when)
                            import Data.Char (isAlpha, isAsciiLower, isAsciiUpper, isSpace, isPrint)
                            import Data.Maybe (fromMaybe)
                            
                            -- הגדרות לסיווג תו לפי שפה
                            isHebrew :: Char -> Bool
                            isHebrew c = c >= 'א' && c <= 'ת'
                            
                            isEnglish :: Char -> Bool
                            isEnglish c = isAsciiLower c || isAsciiUpper c
                            
                            -- מחזירה Just "Hebrew" או Just "English" עבור אות, או Nothing עבור סימן פיסוק/רווח
                            charLang :: Char -> Maybe String
                            charLang c
                              | isHebrew c  = Just "Hebrew"
                              | isEnglish c = Just "English"
                              | otherwise   = Nothing
                            
                            ------------------------------------------------------------
                            -- טיפוסי טוקנים: טוקן אות – כולל מחרוזת ותווית שפה;
                            -- טוקן פיסוק/רווח
                            data Token = Letter { content :: String, lang :: String }
                                       | Punct  { content :: String }
                                       deriving (Show)
                            
                            -- פונקציה שמפצלת מחרוזת לרשימת טוקנים:
                            -- קבוצות רציפות של אותיות (אותן מסווגים לפי charLang) או קבוצות של סימני פיסוק/רווח
                            tokenize :: String -> [Token]
                            tokenize "" = []
                            tokenize s@(c:_)
                              | isAlpha c =
                                  let (letters, rest) = span (\ch -> isAlpha ch && charLang ch == charLang c) s
                                  in Letter letters (fromMaybe "" (charLang c)) : tokenize rest
                              | otherwise =
                                  let (punct, rest) = break isAlpha s
                                  in Punct punct : tokenize rest
                            
                            ------------------------------------------------------------
                            -- מצב סגמנטציה: בשיטה זו נבצע הקצאה מחדש של סימני פיסוק בגבולות בלוקים.
                            -- במצב SegHebrew – target היא "Hebrew"
                            -- במצב SegEnglish – target היא "English"
                            data SegMode = SegHebrew | SegEnglish deriving (Eq, Show)
                            
                            -- עוזרת: האם שפה נתונה היא target בהתאם למצב הסגמנטציה
                            isTarget :: SegMode -> String -> Bool
                            isTarget SegHebrew l = l == "Hebrew"
                            isTarget SegEnglish l = l == "English"
                            
                            -- נרצה לאסוף טוקנים לכדי בלוקים (מחרוזות) כך שהטוקנים המקוריים לא ישתנו,
                            -- אך סימני הפיסוק שבגבולות יועברו בהתאם לכלל הבא:
                            --
                            -- נניח שיש לנו גבול בין טוקן אות (T_prev) לטוקן אות (T_next) עם טוקני פיסוק ביניהם (PunctSeq).
                            -- אז:
                            -- • אם T_prev ו–T_next שונות בשייכות target, נחלק את PunctSeq לשניים:
                            --   - במצב SegHebrew (target = Hebrew): אם T_prev הוא target (Hebrew) ו–T_next אינו, נרצה שהתוצאה תהיה:
                            --         בלוק target: T_prev בלבד,
                            --         בלוק non-target: (PunctSeq עם הסימן האחרון מופיע בסופו) <> T_next...
                            --   - במצב SegEnglish (target = English): אם T_prev אינו target וה–T_next הוא target, אזי
                            --         בלוק non-target: T_prev <> (PunctSeq עם הסימן הראשון בסופו),
                            --         בלוק target: T_next...
                            -- • במקרים בהם שני הטוקנים הם מאותה קטגוריה – פשוט מצרפים את הפיסוק לטוקן הקודם.
                            --
                            -- בפועל, נממש פונקציה שמסכמת את רשימת הטוקנים ומעבירה את סימני הפיסוק בהתאם.
                            reassemble :: SegMode -> [Token] -> [String]
                            reassemble mode toks = mergeBlocks (assignPunct mode toks)
                              where
                                -- assignPunct מעבירה סימני פיסוק בגבולות לפי הכלל הפשוט הבא:
                                assignPunct :: SegMode -> [Token] -> [Token]
                                assignPunct _ [] = []
                                assignPunct _ [t] = [t]
                                assignPunct m (t1 : Punct punc : t2 : rest) =
                                  case (t1, t2) of
                                    (Letter _ l1, Letter _ l2) 
                                      | isTarget m l1 || isTarget m l2 ->
                                          -- במקרה של גבול target–non-target
                                          if isTarget m l1 && not (isTarget m l2)
                                             then -- במצב SegHebrew: אם הטוקן השמאלי הוא target, העבר את כל הפיסוק לבלוק הימני
                                                  t1 : assignPunct m (Letter punc l2 : t2 : rest)
                                             else if not (isTarget m l1) && isTarget m l2
                                                  then -- במצב SegEnglish: אם הטוקן הימני הוא target, העבר את כל הפיסוק לבלוק השמאלי
                                                       let newT1 = Letter (content t1 ++ punc) l1
                                                       in newT1 : assignPunct m (t2 : rest)
                                                  else
                                                       -- אם שני הצדדים target או שניהם non-target – צרף לפסיק ל-T_prev
                                                       let newT1 = Letter (content t1 ++ punc) (lang t1)
                                                       in newT1 : assignPunct m (t2 : rest)
                                    _ -> t1 : assignPunct m (Punct punc : t2 : rest)
                                assignPunct m (t:rest) = t : assignPunct m rest
                            
                                -- mergeBlocks פשוט ממזג טוקנים עוקבים לשרשרת אחת (מבוסס על content)
                                mergeBlocks :: [Token] -> [String]
                                mergeBlocks [] = []
                                mergeBlocks (t:ts) = let (grp, rest) = span (sameType t) ts
                                                         block = concatMap content (t:grp)
                                                     in block : mergeBlocks rest
                                  where
                                    sameType :: Token -> Token -> Bool
                                    sameType (Letter _ l1) (Letter _ l2) = l1 == l2
                                    sameType (Punct _) (Punct _) = True
                                    -- לא ממזג בין אות לפיסוק
                                    sameType _ _ = False
                            
                            ------------------------------------------------------------
                            -- פונקציות עיבוד טקסט:
                            --
                            -- במצב all:
                            -- 1. הופכים את כל הטקסט (reverse)
                            -- 2. מפצלים לבלוקים בעזרת reassemble במצב SegEnglish
                            -- 3. בתוך הרשימה, בלוקים ששייכים לאנגלית (target במצב SegEnglish) חוזרים הפיכה כדי לשחזר את הסדר המקורי.
                            processAll :: String -> String
                            processAll s =
                              let revText = reverse s
                                  toks = tokenize revText
                                  blocks = reassemble SegEnglish toks
                                  fixed = map (\blk -> if any isEnglish blk then reverse blk else blk) blocks
                              in concat fixed
                            
                            -- במצב blocks:
                            -- מפצלים לבלוקים בעזרת reassemble במצב SegHebrew
                            -- ואז הופכים רק את הבלוקים בהם מופיעות אותיות בעברית.
                            processBlocks :: String -> String
                            processBlocks s =
                              let toks = tokenize s
                                  blocks = reassemble SegHebrew toks
                                  fixed = map (\blk -> if any isHebrew blk then reverse blk else blk) blocks
                              in concat fixed
                            
                            -- Add helper function to remove invisible characters.
                            removeInvisible :: String -> String
                            removeInvisible = filter (\c -> isPrint c || isSpace c)
                            
                            -- Add helper function to trim whitespace.
                            trim :: String -> String
                            trim = f . f
                              where f = reverse . dropWhile isSpace
                            
                            main :: IO ()
                            main = do
                              args <- getArgs
                              input <- if length args < 2
                                          then getContents  -- use piped input if no text argument is provided
                                          else return $ unwords $ tail args
                              let txt = trim $ removeInvisible input  -- remove invisible characters then trim whitespace
                                  flag = if null args then "" else head args
                              case flag of
                                "-a" -> putStr $ unlines $ map processAll $ lines txt
                                "-b" -> putStr $ unlines $ map processBlocks $ lines txt
                                _ -> return ()
                            

                            מ 2 תגובות תגובה אחרונה
                            2
                            • נ נחנ נ נח

                              @מתלמד-צעיר כתב בבירור | תגובה: איך לעשות שCMD יכתוב בעברית:

                              @נ-נח גוגל החל לזהות את זה כתוכנה חשודה

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

                              type file.txt | hecho -a
                              

                              hecho.rar סיסמא: 123
                              אתה יכול כמובן לשנות את השם של התוכנה לrev אם אתה מעדיף

                              הקוד

                              import System.Environment (getArgs)
                              import Control.Monad (when)
                              import Data.Char (isAlpha, isAsciiLower, isAsciiUpper, isSpace, isPrint)
                              import Data.Maybe (fromMaybe)
                              
                              -- הגדרות לסיווג תו לפי שפה
                              isHebrew :: Char -> Bool
                              isHebrew c = c >= 'א' && c <= 'ת'
                              
                              isEnglish :: Char -> Bool
                              isEnglish c = isAsciiLower c || isAsciiUpper c
                              
                              -- מחזירה Just "Hebrew" או Just "English" עבור אות, או Nothing עבור סימן פיסוק/רווח
                              charLang :: Char -> Maybe String
                              charLang c
                                | isHebrew c  = Just "Hebrew"
                                | isEnglish c = Just "English"
                                | otherwise   = Nothing
                              
                              ------------------------------------------------------------
                              -- טיפוסי טוקנים: טוקן אות – כולל מחרוזת ותווית שפה;
                              -- טוקן פיסוק/רווח
                              data Token = Letter { content :: String, lang :: String }
                                         | Punct  { content :: String }
                                         deriving (Show)
                              
                              -- פונקציה שמפצלת מחרוזת לרשימת טוקנים:
                              -- קבוצות רציפות של אותיות (אותן מסווגים לפי charLang) או קבוצות של סימני פיסוק/רווח
                              tokenize :: String -> [Token]
                              tokenize "" = []
                              tokenize s@(c:_)
                                | isAlpha c =
                                    let (letters, rest) = span (\ch -> isAlpha ch && charLang ch == charLang c) s
                                    in Letter letters (fromMaybe "" (charLang c)) : tokenize rest
                                | otherwise =
                                    let (punct, rest) = break isAlpha s
                                    in Punct punct : tokenize rest
                              
                              ------------------------------------------------------------
                              -- מצב סגמנטציה: בשיטה זו נבצע הקצאה מחדש של סימני פיסוק בגבולות בלוקים.
                              -- במצב SegHebrew – target היא "Hebrew"
                              -- במצב SegEnglish – target היא "English"
                              data SegMode = SegHebrew | SegEnglish deriving (Eq, Show)
                              
                              -- עוזרת: האם שפה נתונה היא target בהתאם למצב הסגמנטציה
                              isTarget :: SegMode -> String -> Bool
                              isTarget SegHebrew l = l == "Hebrew"
                              isTarget SegEnglish l = l == "English"
                              
                              -- נרצה לאסוף טוקנים לכדי בלוקים (מחרוזות) כך שהטוקנים המקוריים לא ישתנו,
                              -- אך סימני הפיסוק שבגבולות יועברו בהתאם לכלל הבא:
                              --
                              -- נניח שיש לנו גבול בין טוקן אות (T_prev) לטוקן אות (T_next) עם טוקני פיסוק ביניהם (PunctSeq).
                              -- אז:
                              -- • אם T_prev ו–T_next שונות בשייכות target, נחלק את PunctSeq לשניים:
                              --   - במצב SegHebrew (target = Hebrew): אם T_prev הוא target (Hebrew) ו–T_next אינו, נרצה שהתוצאה תהיה:
                              --         בלוק target: T_prev בלבד,
                              --         בלוק non-target: (PunctSeq עם הסימן האחרון מופיע בסופו) <> T_next...
                              --   - במצב SegEnglish (target = English): אם T_prev אינו target וה–T_next הוא target, אזי
                              --         בלוק non-target: T_prev <> (PunctSeq עם הסימן הראשון בסופו),
                              --         בלוק target: T_next...
                              -- • במקרים בהם שני הטוקנים הם מאותה קטגוריה – פשוט מצרפים את הפיסוק לטוקן הקודם.
                              --
                              -- בפועל, נממש פונקציה שמסכמת את רשימת הטוקנים ומעבירה את סימני הפיסוק בהתאם.
                              reassemble :: SegMode -> [Token] -> [String]
                              reassemble mode toks = mergeBlocks (assignPunct mode toks)
                                where
                                  -- assignPunct מעבירה סימני פיסוק בגבולות לפי הכלל הפשוט הבא:
                                  assignPunct :: SegMode -> [Token] -> [Token]
                                  assignPunct _ [] = []
                                  assignPunct _ [t] = [t]
                                  assignPunct m (t1 : Punct punc : t2 : rest) =
                                    case (t1, t2) of
                                      (Letter _ l1, Letter _ l2) 
                                        | isTarget m l1 || isTarget m l2 ->
                                            -- במקרה של גבול target–non-target
                                            if isTarget m l1 && not (isTarget m l2)
                                               then -- במצב SegHebrew: אם הטוקן השמאלי הוא target, העבר את כל הפיסוק לבלוק הימני
                                                    t1 : assignPunct m (Letter punc l2 : t2 : rest)
                                               else if not (isTarget m l1) && isTarget m l2
                                                    then -- במצב SegEnglish: אם הטוקן הימני הוא target, העבר את כל הפיסוק לבלוק השמאלי
                                                         let newT1 = Letter (content t1 ++ punc) l1
                                                         in newT1 : assignPunct m (t2 : rest)
                                                    else
                                                         -- אם שני הצדדים target או שניהם non-target – צרף לפסיק ל-T_prev
                                                         let newT1 = Letter (content t1 ++ punc) (lang t1)
                                                         in newT1 : assignPunct m (t2 : rest)
                                      _ -> t1 : assignPunct m (Punct punc : t2 : rest)
                                  assignPunct m (t:rest) = t : assignPunct m rest
                              
                                  -- mergeBlocks פשוט ממזג טוקנים עוקבים לשרשרת אחת (מבוסס על content)
                                  mergeBlocks :: [Token] -> [String]
                                  mergeBlocks [] = []
                                  mergeBlocks (t:ts) = let (grp, rest) = span (sameType t) ts
                                                           block = concatMap content (t:grp)
                                                       in block : mergeBlocks rest
                                    where
                                      sameType :: Token -> Token -> Bool
                                      sameType (Letter _ l1) (Letter _ l2) = l1 == l2
                                      sameType (Punct _) (Punct _) = True
                                      -- לא ממזג בין אות לפיסוק
                                      sameType _ _ = False
                              
                              ------------------------------------------------------------
                              -- פונקציות עיבוד טקסט:
                              --
                              -- במצב all:
                              -- 1. הופכים את כל הטקסט (reverse)
                              -- 2. מפצלים לבלוקים בעזרת reassemble במצב SegEnglish
                              -- 3. בתוך הרשימה, בלוקים ששייכים לאנגלית (target במצב SegEnglish) חוזרים הפיכה כדי לשחזר את הסדר המקורי.
                              processAll :: String -> String
                              processAll s =
                                let revText = reverse s
                                    toks = tokenize revText
                                    blocks = reassemble SegEnglish toks
                                    fixed = map (\blk -> if any isEnglish blk then reverse blk else blk) blocks
                                in concat fixed
                              
                              -- במצב blocks:
                              -- מפצלים לבלוקים בעזרת reassemble במצב SegHebrew
                              -- ואז הופכים רק את הבלוקים בהם מופיעות אותיות בעברית.
                              processBlocks :: String -> String
                              processBlocks s =
                                let toks = tokenize s
                                    blocks = reassemble SegHebrew toks
                                    fixed = map (\blk -> if any isHebrew blk then reverse blk else blk) blocks
                                in concat fixed
                              
                              -- Add helper function to remove invisible characters.
                              removeInvisible :: String -> String
                              removeInvisible = filter (\c -> isPrint c || isSpace c)
                              
                              -- Add helper function to trim whitespace.
                              trim :: String -> String
                              trim = f . f
                                where f = reverse . dropWhile isSpace
                              
                              main :: IO ()
                              main = do
                                args <- getArgs
                                input <- if length args < 2
                                            then getContents  -- use piped input if no text argument is provided
                                            else return $ unwords $ tail args
                                let txt = trim $ removeInvisible input  -- remove invisible characters then trim whitespace
                                    flag = if null args then "" else head args
                                case flag of
                                  "-a" -> putStr $ unlines $ map processAll $ lines txt
                                  "-b" -> putStr $ unlines $ map processBlocks $ lines txt
                                  _ -> return ()
                              

                              מ מנותק
                              מ מנותק
                              מתלמד צעיר
                              כתב נערך לאחרונה על ידי
                              #14

                              @נ-נח תודה ענקית!
                              כזה דבר עוד לא ראיתי
                              40f45bff-2047-409f-9b52-9a75c378d031-image.png
                              ואז
                              a55e7771-e76b-4e2c-983b-24833ac6521a-image.png
                              אחרי שהזנתי את הסיסמא הקובץ ירד חלק...

                              תגובה 1 תגובה אחרונה
                              1
                              • נ נחנ נ נח

                                @מתלמד-צעיר כתב בבירור | תגובה: איך לעשות שCMD יכתוב בעברית:

                                @נ-נח גוגל החל לזהות את זה כתוכנה חשודה

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

                                type file.txt | hecho -a
                                

                                hecho.rar סיסמא: 123
                                אתה יכול כמובן לשנות את השם של התוכנה לrev אם אתה מעדיף

                                הקוד

                                import System.Environment (getArgs)
                                import Control.Monad (when)
                                import Data.Char (isAlpha, isAsciiLower, isAsciiUpper, isSpace, isPrint)
                                import Data.Maybe (fromMaybe)
                                
                                -- הגדרות לסיווג תו לפי שפה
                                isHebrew :: Char -> Bool
                                isHebrew c = c >= 'א' && c <= 'ת'
                                
                                isEnglish :: Char -> Bool
                                isEnglish c = isAsciiLower c || isAsciiUpper c
                                
                                -- מחזירה Just "Hebrew" או Just "English" עבור אות, או Nothing עבור סימן פיסוק/רווח
                                charLang :: Char -> Maybe String
                                charLang c
                                  | isHebrew c  = Just "Hebrew"
                                  | isEnglish c = Just "English"
                                  | otherwise   = Nothing
                                
                                ------------------------------------------------------------
                                -- טיפוסי טוקנים: טוקן אות – כולל מחרוזת ותווית שפה;
                                -- טוקן פיסוק/רווח
                                data Token = Letter { content :: String, lang :: String }
                                           | Punct  { content :: String }
                                           deriving (Show)
                                
                                -- פונקציה שמפצלת מחרוזת לרשימת טוקנים:
                                -- קבוצות רציפות של אותיות (אותן מסווגים לפי charLang) או קבוצות של סימני פיסוק/רווח
                                tokenize :: String -> [Token]
                                tokenize "" = []
                                tokenize s@(c:_)
                                  | isAlpha c =
                                      let (letters, rest) = span (\ch -> isAlpha ch && charLang ch == charLang c) s
                                      in Letter letters (fromMaybe "" (charLang c)) : tokenize rest
                                  | otherwise =
                                      let (punct, rest) = break isAlpha s
                                      in Punct punct : tokenize rest
                                
                                ------------------------------------------------------------
                                -- מצב סגמנטציה: בשיטה זו נבצע הקצאה מחדש של סימני פיסוק בגבולות בלוקים.
                                -- במצב SegHebrew – target היא "Hebrew"
                                -- במצב SegEnglish – target היא "English"
                                data SegMode = SegHebrew | SegEnglish deriving (Eq, Show)
                                
                                -- עוזרת: האם שפה נתונה היא target בהתאם למצב הסגמנטציה
                                isTarget :: SegMode -> String -> Bool
                                isTarget SegHebrew l = l == "Hebrew"
                                isTarget SegEnglish l = l == "English"
                                
                                -- נרצה לאסוף טוקנים לכדי בלוקים (מחרוזות) כך שהטוקנים המקוריים לא ישתנו,
                                -- אך סימני הפיסוק שבגבולות יועברו בהתאם לכלל הבא:
                                --
                                -- נניח שיש לנו גבול בין טוקן אות (T_prev) לטוקן אות (T_next) עם טוקני פיסוק ביניהם (PunctSeq).
                                -- אז:
                                -- • אם T_prev ו–T_next שונות בשייכות target, נחלק את PunctSeq לשניים:
                                --   - במצב SegHebrew (target = Hebrew): אם T_prev הוא target (Hebrew) ו–T_next אינו, נרצה שהתוצאה תהיה:
                                --         בלוק target: T_prev בלבד,
                                --         בלוק non-target: (PunctSeq עם הסימן האחרון מופיע בסופו) <> T_next...
                                --   - במצב SegEnglish (target = English): אם T_prev אינו target וה–T_next הוא target, אזי
                                --         בלוק non-target: T_prev <> (PunctSeq עם הסימן הראשון בסופו),
                                --         בלוק target: T_next...
                                -- • במקרים בהם שני הטוקנים הם מאותה קטגוריה – פשוט מצרפים את הפיסוק לטוקן הקודם.
                                --
                                -- בפועל, נממש פונקציה שמסכמת את רשימת הטוקנים ומעבירה את סימני הפיסוק בהתאם.
                                reassemble :: SegMode -> [Token] -> [String]
                                reassemble mode toks = mergeBlocks (assignPunct mode toks)
                                  where
                                    -- assignPunct מעבירה סימני פיסוק בגבולות לפי הכלל הפשוט הבא:
                                    assignPunct :: SegMode -> [Token] -> [Token]
                                    assignPunct _ [] = []
                                    assignPunct _ [t] = [t]
                                    assignPunct m (t1 : Punct punc : t2 : rest) =
                                      case (t1, t2) of
                                        (Letter _ l1, Letter _ l2) 
                                          | isTarget m l1 || isTarget m l2 ->
                                              -- במקרה של גבול target–non-target
                                              if isTarget m l1 && not (isTarget m l2)
                                                 then -- במצב SegHebrew: אם הטוקן השמאלי הוא target, העבר את כל הפיסוק לבלוק הימני
                                                      t1 : assignPunct m (Letter punc l2 : t2 : rest)
                                                 else if not (isTarget m l1) && isTarget m l2
                                                      then -- במצב SegEnglish: אם הטוקן הימני הוא target, העבר את כל הפיסוק לבלוק השמאלי
                                                           let newT1 = Letter (content t1 ++ punc) l1
                                                           in newT1 : assignPunct m (t2 : rest)
                                                      else
                                                           -- אם שני הצדדים target או שניהם non-target – צרף לפסיק ל-T_prev
                                                           let newT1 = Letter (content t1 ++ punc) (lang t1)
                                                           in newT1 : assignPunct m (t2 : rest)
                                        _ -> t1 : assignPunct m (Punct punc : t2 : rest)
                                    assignPunct m (t:rest) = t : assignPunct m rest
                                
                                    -- mergeBlocks פשוט ממזג טוקנים עוקבים לשרשרת אחת (מבוסס על content)
                                    mergeBlocks :: [Token] -> [String]
                                    mergeBlocks [] = []
                                    mergeBlocks (t:ts) = let (grp, rest) = span (sameType t) ts
                                                             block = concatMap content (t:grp)
                                                         in block : mergeBlocks rest
                                      where
                                        sameType :: Token -> Token -> Bool
                                        sameType (Letter _ l1) (Letter _ l2) = l1 == l2
                                        sameType (Punct _) (Punct _) = True
                                        -- לא ממזג בין אות לפיסוק
                                        sameType _ _ = False
                                
                                ------------------------------------------------------------
                                -- פונקציות עיבוד טקסט:
                                --
                                -- במצב all:
                                -- 1. הופכים את כל הטקסט (reverse)
                                -- 2. מפצלים לבלוקים בעזרת reassemble במצב SegEnglish
                                -- 3. בתוך הרשימה, בלוקים ששייכים לאנגלית (target במצב SegEnglish) חוזרים הפיכה כדי לשחזר את הסדר המקורי.
                                processAll :: String -> String
                                processAll s =
                                  let revText = reverse s
                                      toks = tokenize revText
                                      blocks = reassemble SegEnglish toks
                                      fixed = map (\blk -> if any isEnglish blk then reverse blk else blk) blocks
                                  in concat fixed
                                
                                -- במצב blocks:
                                -- מפצלים לבלוקים בעזרת reassemble במצב SegHebrew
                                -- ואז הופכים רק את הבלוקים בהם מופיעות אותיות בעברית.
                                processBlocks :: String -> String
                                processBlocks s =
                                  let toks = tokenize s
                                      blocks = reassemble SegHebrew toks
                                      fixed = map (\blk -> if any isHebrew blk then reverse blk else blk) blocks
                                  in concat fixed
                                
                                -- Add helper function to remove invisible characters.
                                removeInvisible :: String -> String
                                removeInvisible = filter (\c -> isPrint c || isSpace c)
                                
                                -- Add helper function to trim whitespace.
                                trim :: String -> String
                                trim = f . f
                                  where f = reverse . dropWhile isSpace
                                
                                main :: IO ()
                                main = do
                                  args <- getArgs
                                  input <- if length args < 2
                                              then getContents  -- use piped input if no text argument is provided
                                              else return $ unwords $ tail args
                                  let txt = trim $ removeInvisible input  -- remove invisible characters then trim whitespace
                                      flag = if null args then "" else head args
                                  case flag of
                                    "-a" -> putStr $ unlines $ map processAll $ lines txt
                                    "-b" -> putStr $ unlines $ map processBlocks $ lines txt
                                    _ -> return ()
                                

                                מ מנותק
                                מ מנותק
                                מתלמד צעיר
                                כתב נערך לאחרונה על ידי
                                #15

                                @נ-נח ישנה עוד בעיה שאי אפשר להדפיס מקובץ PowerShell משא"כ ב-rev

                                powershell -ExecutionPolicy Bypass -File "script.ps1"    |rev
                                powershell -ExecutionPolicy Bypass -File "script.ps1"    |hecho
                                

                                השורה הראשונה תדפיס היטב והשניה לא תדפיס כלל

                                נ נחנ תגובה 1 תגובה אחרונה
                                0
                                • מ מתלמד צעיר

                                  @נ-נח ישנה עוד בעיה שאי אפשר להדפיס מקובץ PowerShell משא"כ ב-rev

                                  powershell -ExecutionPolicy Bypass -File "script.ps1"    |rev
                                  powershell -ExecutionPolicy Bypass -File "script.ps1"    |hecho
                                  

                                  השורה הראשונה תדפיס היטב והשניה לא תדפיס כלל

                                  נ נחנ מנותק
                                  נ נחנ מנותק
                                  נ נח
                                  כתב נערך לאחרונה על ידי
                                  #16

                                  @מתלמד-צעיר תנסה עם ארגומנט:

                                  powershell -ExecutionPolicy Bypass -File "script.ps1"    |hecho -a
                                  

                                  או

                                  powershell -ExecutionPolicy Bypass -File "script.ps1"    |hecho -b
                                  
                                  מ תגובה 1 תגובה אחרונה
                                  1
                                  • נ נחנ נ נח

                                    @מתלמד-צעיר תנסה עם ארגומנט:

                                    powershell -ExecutionPolicy Bypass -File "script.ps1"    |hecho -a
                                    

                                    או

                                    powershell -ExecutionPolicy Bypass -File "script.ps1"    |hecho -b
                                    
                                    מ מנותק
                                    מ מנותק
                                    מתלמד צעיר
                                    כתב נערך לאחרונה על ידי
                                    #17

                                    @נ-נח צודק טעות שלי
                                    אפשר להציע לך עוד שיפור?

                                    נ נחנ תגובה 1 תגובה אחרונה
                                    0
                                    • מ מתלמד צעיר

                                      @נ-נח צודק טעות שלי
                                      אפשר להציע לך עוד שיפור?

                                      נ נחנ מנותק
                                      נ נחנ מנותק
                                      נ נח
                                      כתב נערך לאחרונה על ידי
                                      #18

                                      @מתלמד-צעיר בוודאי!

                                      מ תגובה 1 תגובה אחרונה
                                      1
                                      • נ נחנ נ נח

                                        @מתלמד-צעיר בוודאי!

                                        מ מנותק
                                        מ מנותק
                                        מתלמד צעיר
                                        כתב נערך לאחרונה על ידי
                                        #19

                                        @נ-נח הקוד מדפיס ככה
                                        f447e03a-5c28-489f-94bf-4ccb5b8b06e1-image.png
                                        זה קריא וברור אבל...😉

                                        נ נחנ תגובה 1 תגובה אחרונה
                                        0
                                        • מ מתלמד צעיר

                                          @נ-נח הקוד מדפיס ככה
                                          f447e03a-5c28-489f-94bf-4ccb5b8b06e1-image.png
                                          זה קריא וברור אבל...😉

                                          נ נחנ מנותק
                                          נ נחנ מנותק
                                          נ נח
                                          כתב נערך לאחרונה על ידי
                                          #20

                                          @מתלמד-צעיר מה היה הקלט?
                                          ובאיזה ארגומנט השתמשת, -a או -b?
                                          הבעיה היא רק הגרשיים?

                                          מ תגובה 1 תגובה אחרונה
                                          0

                                          • התחברות

                                          • אין לך חשבון עדיין? הרשמה

                                          • התחברו או הירשמו כדי לחפש.
                                          • פוסט ראשון
                                            פוסט אחרון
                                          0
                                          • חוקי הפורום
                                          • לא נפתר
                                          • משתמשים
                                          • חיפוש גוגל בפורום
                                          • צור קשר