gemmula 1.0.1 → 1.1.0
raw patch · 5 files changed
+61/−50 lines, 5 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- ChangeLog.md +5/−0
- README.md +4/−3
- gemmula.cabal +1/−1
- src/Text/Gemini.hs +14/−11
- test/Main.hs +37/−35
ChangeLog.md view
@@ -1,6 +1,11 @@ # `gemmula` Change Log +## 1.1.0 (January 13, 2024)+* Normalize the links with spaces while encoding.+* Ignore the empty lists while encoding.+* Clean up more documentations.+ ## 1.0.1 (January 08, 2024) * Improve code readability and quality. * Clean up some documentations.
README.md view
@@ -4,9 +4,10 @@ A tiny and functional Gemtext (`text/gemini`) parser from and back to Text. Check the Section 5 of the [Gemini Protocol specification](https://geminiprotocol.net/docs/specification.gmi)-for more about the `text/gemini` filetype. -You can also check the [Gemini Protocol](https://geminiprotocol.net) capsule for more about the Gemini itself.+for more about the `text/gemini` filetype. You can also check the [Gemini Protocol](https://geminiprotocol.net)+capsule for more about the Gemini itself. -The documentation is available at [Hackage](https://hackage.haskell.org/package/gemmula/docs/Text-Gemini.html). +The documentation is available at [Hackage](https://hackage.haskell.org/package/gemmula/docs/Text-Gemini.html).+ You can find more information and related modules at the [Codeberg repository](https://codeberg.org/sena/gemmula).
gemmula.cabal view
@@ -1,5 +1,5 @@ name: gemmula-version: 1.0.1+version: 1.1.0 synopsis: A tiny Gemtext parser description: gemmula is a tiny and functional Gemtext (unofficially text/gemini) parser that aims to parse a Gemtext document from and back to Text,
src/Text/Gemini.hs view
@@ -79,10 +79,7 @@ -- | Parse a /single/ Gemtext line as 'GemItem'. ----- Notes:------ * Isn't able to decode preformatted texts as they are strictly multiline.--- * 'GemList's are also obviously singleton.+-- The preformatted texts are regarded as 'GemText's as they are strictly multiline. decodeLine :: Text -> GemItem decodeLine line | line `hasValueOf` "=>" = let (link, desc) = T.break isSpace $ value 2 line@@ -102,22 +99,27 @@ -- | Encode parsed 'GemDocument' as a Gemtext file. -- The output 'Text' uses LF-endings. Uses the 'encodeItem' function below.+--+-- Valid prefixes are escaped before encoding.+--+-- Empty lists are ignored if given. encode :: GemDocument -> Text-encode = T.unlines . map encodeItem+encode = T.unlines . map encodeItem . filter (not . empty)+ where empty :: GemItem -> Bool+ empty (GemList list) = null list+ empty _ = False -- | Encode a /single/ parsed 'GemItem' as Gemtext text. -- The output 'Text' uses LF-endings and might be multiple lines. ----- /Beware/ that the output text never ends with a newline.+-- Valid prefixes are escaped before encoding. ----- Notes:+-- /Beware/ that the output text doesn't end with a newline. ----- * The text of the 'GemText' will follow a whitespace to escape the prefix--- at the beginning if the line starts with a valid one.--- * The link in the 'GemLink' should not have spaces.+-- The spaces in 'GemLink's are replaced with @%20@ to normalize them. encodeItem :: GemItem -> Text encodeItem (GemText line) = escapePrefixes line-encodeItem (GemLink link desc) = "=> " <> link <> maybe "" (" " <>) desc+encodeItem (GemLink link desc) = "=> " <> T.replace " " "%20" link <> maybe "" (" " <>) desc encodeItem (GemHeading level text) = T.replicate (min level 3) "#" <> " " <> text encodeItem (GemList list) = T.intercalate "\n" $ map ("* " <>) list encodeItem (GemQuote text) = "> " <> text@@ -131,6 +133,7 @@ any (hasValueOf line) ["=>", "* ", ">"] || (line `hasValueOf` "#" && let (_, text) = T.span (=='#') line in not (T.null $ T.strip text))+ -- @True@ if the the line has prefix /and/ a following value. hasValueOf :: Text -> Text -> Bool
test/Main.hs view
@@ -22,46 +22,16 @@ -- | Test the decoding of Gemtext documents. gemDecode :: Test-gemDecode = TestCase $ assertEqual "Comparing the expected result of Gemtext decoding," document $ G.decode raw+gemDecode = TestCase $ assertEqual "Comparing the expected result of Gemtext decoding,"+ document $ G.decode raw -- | Test the encoding of Gemtext documents. gemEncode :: Test-gemEncode = TestCase $ assertEqual "Comparing the expected result of Gemtext encoding," pretty $ G.encode document+gemEncode = TestCase $ assertEqual "Comparing the expected result of Gemtext encoding,"+ pretty $ G.encode document --- | The raw document to test decoding on.-raw :: Text-raw = [r| text!! -another text-=>link.gmi a link -=> gemini://geminiprotocol.net/index.gmi-=> -# heading -## sub-heading-### -###subsubheading but it works-#### same as level 3- -*text- * also text!-* list item-* another item-*-> quote-> -```alt -> preformat with alt-```-``` --* preformat without alt-```->qq -```empty-```ignored -|]---- | The expected encode output to compare against.+-- | The expected encoded file to compare against. pretty :: Text pretty = [r| text!! another text@@ -117,4 +87,36 @@ , GemQuote "qq" , GemPre [] (Just "empty") ]++-- | The raw file to try to decode.+raw :: Text+raw = [r| text!! +another text+=>link.gmi a link +=> gemini://geminiprotocol.net/index.gmi+=> +# heading +## sub-heading+### +###subsubheading but it works+#### same as level 3+ +*text+ * also text!+* list item+* another item+*+> quote+> +```alt +> preformat with alt+```+``` ++* preformat without alt+```+>qq +```empty+```ignored +|]