qm-interpolated-string

Implementation of interpolated multiline strings

https://github.com/unclechu/haskell-qm-interpolated-string

Version on this page:0.2.1.0
LTS Haskell 22.14:0.3.1.0
Stackage Nightly 2023-12-26:0.3.1.0
Latest on Hackage:0.3.1.0

See all snapshots qm-interpolated-string appears in

LicenseRef-PublicDomain licensed by Viacheslav Lotsmanov
Maintained by Viacheslav Lotsmanov
This version can be pinned in stack with:qm-interpolated-string-0.2.1.0@sha256:1c9fb6a9693cfaa806273dee858d0500ce1cecf198d399e1acc739d27ec4e2aa,2384

Module documentation for 0.2.1.0

[qm|interpolated-string|]

Hackage Build Status

Implementation of interpolated multiline string QuasiQuoter that ignores indentation and trailing whitespaces.

Actually it’s modification of interpolatedstring-perl6 package. I’ve forked it to implemenent my own strings I really like.

This implementation based on qc from interpolatedstring-perl6 package but ignores any indentation, line breaks (except explicitly written using \n char) and trailing whitespaces.

  • ‘m’ in qm means ‘Multiline’.
  • ‘n’ in qn means ‘No interpolation’.
  • ‘b’ in qmb/qnb means ‘line Breaks’.
  • ‘s’ in qms/qns means ‘Spaces’.

Write a decoratively formatted string and your decorative indentation and line breaks wont go to result string, but when you really need it, you could just escape it using backslash.

Usage example

{-# LANGUAGE QuasiQuotes #-}

import Text.InterpolatedString.QM

main :: IO ()
main = do
  -- Hello, world! Pi is 3.14…
  putStrLn [qms| Hello,
                 world!
                 Pi is {floor pi}.{floor $ (pi - 3) * 100}… |]

  -- Some examples with HTML below to demonstrate the difference
  -- between all of the quasi-quoters.

  let title = "Testing"
      text  = "Some testing text"

  -- <article><h1>Testing</h1><p>Some testing text</p></article>
  putStrLn [qm|
    <article>
      <h1>{title}</h1>
      <p>{text}</p>
    </article>
  |]

  -- <article><h1>{title}</h1><p>{text}</p></article>
  putStrLn [qn|
    <article>
      <h1>{title}</h1>
      <p>{text}</p>
    </article>
  |]

  -- <article> <h1>Testing</h1> <p>Some testing text</p> </article>
  putStrLn [qms|
    <article>
      <h1>{title}</h1>
      <p>{text}</p>
    </article>
  |]

  -- <article> <h1>{title}</h1> <p>{text}</p> </article>
  putStrLn [qns|
    <article>
      <h1>{title}</h1>
      <p>{text}</p>
    </article>
  |]

  -- <article>
  -- <h1>Testing</h1>
  -- <p>Some testing text</p>
  -- </article>
  putStrLn [qmb|
    <article>
      <h1>{title}</h1>
      <p>{text}</p>
    </article>
  |]

  -- <article>
  -- <h1>{title}</h1>
  -- <p>{text}</p>
  -- </article>
  putStrLn [qnb|
    <article>
      <h1>{title}</h1>
      <p>{text}</p>
    </article>
  |]

Tables

All QuasiQuoters

| QuasiQuoter | Interpolation | Indentation | Line breaks          | Trailing whitespaces |
|-------------|---------------|-------------|----------------------|----------------------|
| qm          | ✓             | Removed     | Removed              | Removed              |
| qn          | ✗             | Removed     | Removed              | Removed              |
| qmb         | ✓             | Removed     | Kept                 | Removed              |
| qnb         | ✗             | Removed     | Kept                 | Removed              |
| qms         | ✓             | Removed     | Replaced with spaces | Removed              |
| qns         | ✗             | Removed     | Replaced with spaces | Removed              |

About naming logic

| Contains in its name | What means                       | QuasiQuoters |
|----------------------|----------------------------------|--------------|
| m                    | Resolves interpolation blocks    | qm, qmb, qms |
| n                    | Without interpolation            | qn, qnb, qns |
| b                    | Keeps line breaks                | qmb, qnb     |
| s                    | Replaces line breaks with spaces | qms, qns     |

About escaping

Symbols that can be escaped

Backslash is used for escaping these:

  1. \n - line break
  2. - space (space is supposed to be escaped when you’re going to keep some part of indentation)
  3. \↵ - backslash just before end of line cuts off line break (makes sense for qmb, qnb, qms and qns)
  4. \{ - opening bracket of interpolation block (only for qm, qmb and qms, to prevent interpolation and interpret this block as plain text)
  5. \t or \‣ (where is real tab symbol) - tab (escaping it to keep some part of indentation, or if you need tab symbol for some reason, escaping real tabs makes sense only for keeping some part of indentation)
  6. \\ - backslash itself (for situations when you don’t want to escape other symbols but just want backslash symbol, \\t, \\n, \\↵, \\{, etc., if backslash doesn’t come with any of symbols from this list it is interpreted just as backslash symbol, keep in mind that \\\ (without any of symbols from this list after) and \\\\ are producing same result - \\)

Escaping examples

[qm| foo\nbar  |] -- "foo\nbar"
[qm| foo\\nbar |] -- "foo\\nbar"
[qm| foo\tbar  |] -- "foo\tbar"
[qm| foo\\tbar |] -- "foo\\tbar"
[qm| foo\‣bar  |] -- "foo\tbar"   (`‣` is real tab symbol)
[qm| foo\\‣bar |] -- "foo\\\tbar" (`‣` is real tab symbol)
[qm| foo\ bar  |] -- "foo bar"
[qm| foo\\ bar |] -- "foo\\ bar"

[qm| foo\
     bar  |] -- "foobar"
[qm| foo\\
     bar  |] -- "foo\\bar"

[qmb| foo\
      bar  |] -- "foobar"
[qmb| foo\\
      bar  |] -- "foo\\\nbar"

[qm| foo\bar    |] -- "foo\\bar"
[qm| foo\\bar   |] -- "foo\\bar"
[qm| foo\\\bar  |] -- "foo\\\\bar"
[qm| foo\\\\bar |] -- "foo\\\\bar"

More examples

[qm|   you can escape spaces
     \ when you need them    |]
-- Result: "you can escape spaces when you need them"
[qm|
        indentation and li
  ne bre
   aks are i
       gno
     red
|]
-- Result: "indentation and line breaks are ignored"
[qm|  \  You can escape indentation or\n
         line breaks when you need them! \  |]
-- Result: "  You can escape indentation or\nline breaks when you need them!  "
[qm| Interpolation blocks can be escaped too: {1+2} \{3+4} |]
-- Result: "Interpolation blocks can be escaped too: 3 {3+4}"

If you don’t need interpolation - just replace m to n in quasi-quoter name:

[qm| foo {1+2} |] -- Result: "foo 3"
[qn| foo {1+2} |] -- Result: "foo {1+2}"

[qms| foo {1+2} |] -- Result: "foo 3"
[qns| foo {1+2} |] -- Result: "foo {1+2}"

[qmb| foo {1+2} |] -- Result: "foo 3"
[qnb| foo {1+2} |] -- Result: "foo {1+2}"

Author

Viacheslav Lotsmanov

License

The Unlicense

Changes

0.2.1.0

  • Support GHC 7.4.1
  • Internal modules moved to other-modules section

0.2.0.0

  • Added tab (\t) symbol escaping (breaks backward compatibility with v0.1.1.0)
  • Support new LTS Haskell 9.0 (ghc-8.0.2) (updated upper version of haskell-src-meta from 0.7.x to 0.8.x)
  • Added qmb QuasiQuoter, it’s qm + b (line-Breaks), it works just as qm but keeps line breaks (still ignores indendation)
  • Added qnb QuasiQuoter (qmb without interpolation), it’s qn + b (line-Breaks), it works just as qn but keeps line breaks (still ignores indendation)
  • Added qms QuasiQuoter, it’s qm + s (Spaces), it works just as qmb but kept line breaks replaced with spaces
  • Added qns QuasiQuoter (qms without interpolation), it’s qn + s (Spaces), it works just as qnb but kept line breaks replaced with spaces
  • More docs and tests

0.1.1.0

  • Added qn QuasiQuoter as alternative to qm but without interpolation
  • Some code refactoring
  • More docs and tests