Commit 44a52151 authored by Nicolas Lenz's avatar Nicolas Lenz Committed by Gitea

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

parents 72ae5bf3 fca2bae6
......@@ -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 .
```
......
{-# 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.",
......
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"
name: mock
version: 3.5.0
license: WTFPL
git: https://git.eisfunke.com/software/mock
author: Nicolas Lenz
maintainer: nicolas@eisfunke.com
copyright: 2018-2019 Nicolas Lenz
extra-source-files:
- README.md
synopsis: GrEAt HAskeLL PrOGRaM to trANsForm tEXT
category: String
description: Please see the README at <https://git.eisfunke.com/software/mock#readme>
synopsis: GrEAt HAskeLL PrOGRaM to trANsForm tEXT
category: Text
description: Please see the README at <https://git.eisfunke.com/software/mock#readme>.
dependencies:
- base
- random
- hashable
- text
- base
- text
- random
- hashable
extra-doc-files:
- README.md
library:
source-dirs: src
ghc-options:
- -Wall
executables:
mock:
main: Main.hs
source-dirs: app
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
source-dirs: app
main: main.hs
dependencies:
- mock
- mock
ghc-options:
- -Wall
- -threaded
- -rtsopts
- -with-rtsopts=-N
{-# 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
......
{-# 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."
resolver: lts-13.25
resolver: lts-13.26
packages:
- .
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment