Commit 44a52151 authored by Nicolas Lenz's avatar Nicolas Lenz ❄️ Committed by Gitea
Browse files

Merge branch 'new-masking' of software/mock into master

parents 72ae5bf3 fca2bae6
Loading
Loading
Loading
Loading
+4 −5
Original line number Diff line number Diff line
@@ -9,8 +9,7 @@ There is a **Telegram bot** for Mock available as [@truemockbot](https://t.me/tr
Just clone this repository or download a [release](https://git.eisfunke.com/software/mock/releases) and call

```
$> stack setup
$> stack install
$ stack install
```

inside the folder. This will install Mock into `~/.local/bin`, which should be added to `$PATH`.
@@ -29,17 +28,17 @@ If no text or "-" is given, input is read from `stdin`.
### Examples

```
$> mock random This is a great program.
$ mock random This is a great program.
ThIs Is A greaT PROgrAM.

$> mock space This is a great program.
$ mock space This is a great program.
T h i s   i s   a   g r e a t   p r o g r a m.
```

Mock calls can of course be concatenated with pipes:

```
$> mock space This is a great program. | mock random
$ mock space This is a great program. | mock random
T h I S   i S   A   G R e A t   P R o g r a m .
```

+3 −6
Original line number Diff line number Diff line
{-# LANGUAGE OverloadedStrings #-}

module Main where

import Mock (styles)
import Mock.Help (styleHelp)
import Text.Mock
import Text.Mock.Help
import qualified Data.Text as T
import qualified Data.Text.IO as T
import Data.Char
import Data.Maybe
import System.Environment


-- |Main function.
main :: IO ()
main = do
@@ -35,7 +32,7 @@ handle style = fromMaybe (const help) (lookup style styles) . T.dropWhileEnd isS
help :: T.Text
help = T.unlines [
    " ╔════════════════════╗",
    " ║     Mock 3.5.0     ║",
    " ║     Mock " <> version <> "     ║",
    " ╚════════════════════╝",
    "",
    "A Great PrOgrAM tO TRANsFoRM TEXt, wRiTten iN HaSKeLL.",
+27 −24
Original line number Diff line number Diff line
name: mock
version: 3.5.0
license: WTFPL
git:                 "https://git.eisfunke.com/software/mock"
author:              "Nicolas Lenz"
maintainer:          "nicolas@eisfunke.com"
copyright:           "2018 Nicolas Lenz"

extra-source-files:
- README.md
git: https://git.eisfunke.com/software/mock
author: Nicolas Lenz
maintainer: nicolas@eisfunke.com
copyright: 2018-2019 Nicolas Lenz

synopsis: GrEAt HAskeLL PrOGRaM to trANsForm tEXT
category:            String
description:         Please see the README at <https://git.eisfunke.com/software/mock#readme>
category: Text
description: Please see the README at <https://git.eisfunke.com/software/mock#readme>.

dependencies:
  - base
  - text
  - random
  - hashable
- text

extra-doc-files:
  - README.md

library:
  source-dirs: src
  ghc-options:
    - -Wall

executables:
  mock:
    main:                Main.hs
    source-dirs: app
    main: main.hs
    dependencies:
      - mock
    ghc-options:
      - -Wall
      - -threaded
      - -rtsopts
      - -with-rtsopts=-N
    dependencies:
    - mock
+54 −42
Original line number Diff line number Diff line
{-# LANGUAGE OverloadedStrings, LambdaCase #-}

module Mock (styles, mockAlternate, mockRandom, letterspace, toDouble, toSubSuper) where
module Text.Mock (styles, version) where

import qualified Data.Text as T
import Data.Text (Text)
import qualified Data.Text as T
import Data.Char
import Data.List
import Data.Hashable
import System.Random

-- |Version string
version :: Text
version = "3.5.0"

-- |List of possible mock style names and their functions.
-- | List of all mock styles as tuples of the name and the transformation function.
styles :: [(Text, Text -> Text)]
styles = [
    ("random", mockRandom),
@@ -26,6 +29,8 @@ styles = [
    ("subsuper", mockSubSuper),
    ("cc", mockCC),
    ("b", mockB),
    ("pray", T.unwords . intersperse "🙏" . T.words),
    ("clap", T.unwords . intersperse "👏" . T.words),
    ("space", letterspace 1),
    ("space2", letterspace 2),
    ("space3", letterspace 3),
@@ -33,26 +38,30 @@ styles = [
    ("wordlines", T.concat . intersperse "\n" . T.words),
    ("square", mockSquare)]

-- |Transforms a String into uppercase where the corresponding list is True. For False the String isn't changed.
toUpperBy :: [Bool] -> T.Text -> T.Text
toUpperBy bs = T.pack . zipWith f bs . T.unpack where
    f :: Bool -> Char -> Char
    f True c = toUpper c
    f False c = c

-- |Transforms every other of the Chars of a String into uppercase. The other Chars aren't changed.
mockAlternate :: T.Text -> T.Text
mockAlternate = toUpperBy $ intersperse True $ repeat False

-- |Tansforms random (that is, random per input String) Chars of a String into uppercase.
mockRandom :: T.Text -> T.Text
-- | Transforms characters of a string into uppercase where the corresponding element of the bool list is true. On encountering a letter that already is uppercase the mask is reversed.
toUpperBy :: [Bool] -> Text -> Text
toUpperBy mask' = fst . T.foldl f ("", mask') where
    f :: (Text, [Bool]) -> Char -> (Text, [Bool])
    f (txt, bit:mask) char
        | isUpper char = (txt `T.snoc` char, map not mask)
        | isSpace char = (txt `T.snoc` char, bit:mask)
    f (txt, True:mask) char = (txt `T.snoc` toUpper char, mask)
    f (txt, False:mask) char = (txt `T.snoc` char, mask)
    f (txt, []) char = (txt `T.snoc` char, [])  -- If the mask is empty, treat is as all false

-- | Transforms every other of the characters of a string into uppercase. The other characters aren't changed.
mockAlternate :: Text -> Text
mockAlternate = toUpperBy (intersperse True $ repeat False)

-- | Tansforms random (that is, pseudo-random per input) characters of a string into uppercase.
mockRandom :: Text -> Text
mockRandom txt = toUpperBy (randoms $ mkStdGen (hash txt)) txt

-- |Letterspaces a String with the given number of blanks between the Chars.
letterspace :: Int -> T.Text -> T.Text
-- | Letterspaces a String with the given number of blanks between each character.
letterspace :: Int -> Text -> Text
letterspace n = T.pack . intercalate (replicate n ' ') . map (:[]) . T.unpack

-- |Transforms a character into its double-struck variant (if it is alphanumeric, else it is left unchanged).
-- | Transforms characters into their double-struck variant if available.
toDouble :: Char -> Char
toDouble 'C' = chr 8450
toDouble 'H' = chr 8461
@@ -67,11 +76,29 @@ toDouble c
    | 97 <= ord c && ord c <= 122 = chr $ ord c - 97 + 120146  -- Lowercase letter
toDouble c = c

-- | Transforms double-struck characters back into their normal variant.
fromDouble :: Char -> Char
fromDouble c = case ord c of
    8450 -> 'C'
    8461 -> 'H'
    8469 -> 'N'
    8473 -> 'P'
    8474 -> 'Q'
    8477 -> 'R'
    8484 -> 'Z'
    code
        | 120792 <= code && code <= 120801 -> chr $ code - 120792 + 48
        | 120120 <= code && code <= 120145 -> chr $ code - 120120 + 65
        | 120146 <= code && code <= 120171 -> chr $ code - 120146 + 97
    code -> chr code

-- | Transforms characters into sub- and superscript alternatingly.
mockSubSuper :: Text -> Text
mockSubSuper txt = T.pack $ zipWith toSubSuper (intersperse True $ repeat False) (T.unpack txt)

-- | Transforms a character into a unicode sub- or superscript variant. If true is given and a subscript version is available, that is used. If none is available or false is given, a superscript version is used. If none is available, the character is left unchanged.
toSubSuper :: Bool -> Char -> Char
toSubSuper sub c = case (sub, c) of
toSubSuper = curry $ \case
    (_, 'A') -> chr 7468
    (_, 'B') -> chr 7470
    (_, 'D') -> chr 7472
@@ -135,23 +162,7 @@ toSubSuper sub c = case (sub, c) of
    (_, 'z') -> 'ᶻ'
    (_, c) -> c

-- |Transforms double-struck characters back into their normal variant.
fromDouble :: Char -> Char
fromDouble c = case ord c of
    8450 -> 'C'
    8461 -> 'H'
    8469 -> 'N'
    8473 -> 'P'
    8474 -> 'Q'
    8477 -> 'R'
    8484 -> 'Z'
    code
        | 120792 <= code && code <= 120801 -> chr $ code - 120792 + 48
        | 120120 <= code && code <= 120145 -> chr $ code - 120120 + 65
        | 120146 <= code && code <= 120171 -> chr $ code - 120146 + 97
    code -> chr code

-- |Transforms lowercase characters into their unicode small capital variant
-- | Transforms lowercase characters into their unicode small capital variants.
toSmallCap :: Char -> Char
toSmallCap = \case
    'a' -> chr 7424
@@ -181,6 +192,7 @@ toSmallCap = \case
    'z' -> chr 7458
    c -> c

-- | Replaces some characters with cyrillic ones *looking* similarly.
toCyrillic :: Char -> Char
toCyrillic = \case
    'A' -> 'Д'
@@ -205,19 +217,19 @@ toCyrillic = \case
    'y' -> 'џ'
    c -> c

-- |Replaces all occurences of lowercase "ck" and "k" in a string with "cc"s.
mockCC :: T.Text -> T.Text
-- | Replaces all occurences of *lowercase* "g", "ck" and "k" in a string with "cc".
mockCC :: Text -> Text
mockCC = T.replace "k" "cc" . T.replace "ck" "cc"

-- |Repaclaces all occurences of "b" and "B" with B button emojis.
-- | Replaces all occurences of "b", "B", "p" and "P" with B button emojis.
mockB :: Text -> Text
mockB = T.replace "b" "🅱️" . T.replace "B" "🅱️"

-- |Makes a square from a string.
-- | Makes a square of a string by putting it with spaces in the first line and then all characters except the first in single lines after that first line.
mockSquare :: Text -> Text
mockSquare text = T.concat [T.intersperse ' ' text, "\n", T.intercalate "\n" (T.chunksOf 1 $ T.tail text)]

-- |Uses Unicode U+0336 to let a text look struck through.
-- | Uses unicode U+0336 to let a text look struck through.
strikethrough :: Text -> Text
strikethrough text
    | text == T.empty = T.empty
+15 −14
Original line number Diff line number Diff line
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE OverloadedStrings, LambdaCase #-}

module Mock.Help (styleHelp) where
module Text.Mock.Help (styleHelp) where

import qualified Data.Text as T
import Data.Text (Text)

styleHelp :: Text -> Text
styleHelp styleName = case styleName of
styleHelp = \case
    "random" -> "Flips lowercase characters pseudo-randomly into uppercase letters."
    "alternate" -> "Flips every second letter into an uppercase one, starting with the second character."
    "alternate2" -> "Like alternate, but ignores case in the input. Equivalent to lower|alternate."
    "space" -> "Inserts a  s p a c e  between every two characters."
    "space2" -> "Inserts two   s  p  a  c  e  s   between every two characters."
    "space3" -> "Inserts three    s   p   a   c   e   s    between every two characters."
    "lines" -> "Puts each character on a single line."
    "wordlines" -> "Puts each word on a single line."
    "upper" -> "Turns all characters into UPPERCASE ones."
    "lower" -> "Turns all characters into lowercase ones."
    "cyrillic" -> "Turns the text into a stereotypical fake russian looking variant."
    "subsuper" -> "Alternatingly put letters into sub- and superscript, where possible."
    "strike" -> "Turns the input into strikethrough using Unicode combinators (e̶x̶a̶m̶p̶l̶e̶)."
    "double" -> "Turns characters (latin letters and numbers) into their double-struck variants (𝕖𝕩𝕒𝕞𝕡𝕝𝕖). Also known as blackboard bold."
    "dedouble" -> "Turns double-struck characters (like from the \"double\" style) back into normal ones."
    "smallcaps" -> "Turns lowercase letters into small capitals."
    "lower" -> "Turns all characters into lowercase ones."
    "upper" -> "Turns all characters into UPPERCASE ones."
    "cyrillic" -> "Turns the text into a stereotypical fake russian looking variant."
    "subsuper" -> "Alternatingly put letters into sub- and superscript, where possible."
    "cc" -> "Replaces all occurences of lowercase \"c\", \"ck\" and \"k\" with \"cc\"."
    "b" -> "Replaces all occurences of Bs (lower- and uppercase) with B-button emojis (🅱)."
    "pray" -> "Puts pray emojis (🙏) between all words."
    "clap" -> "Puts clap emojis (👏) between all words."
    "space" -> "Inserts a  s p a c e  between every two characters."
    "space2" -> "Inserts two   s  p  a  c  e  s   between every two characters."
    "space3" -> "Inserts three    s   p   a   c   e   s    between every two characters."
    "lines" -> "Puts each character on a single line."
    "wordlines" -> "Puts each word on a single line."
    "square" -> "Shows the input spaced in the first line and the tail of the input lined afterwards."
    "strike" -> "Turns the input into strikethrough using Unicode combinators (e̶x̶a̶m̶p̶l̶e̶)."
    _ -> "No documentation available."
Loading