Hello community,
here is the log from the commit of package ghc-jira-wiki-markup for
openSUSE:Factory checked in at 2020-07-09 13:19:23
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ghc-jira-wiki-markup (Old)
and /work/SRC/openSUSE:Factory/.ghc-jira-wiki-markup.new.3060 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ghc-jira-wiki-markup"
Thu Jul 9 13:19:23 2020 rev:4 rq:819580 version:1.3.2
Changes:
--------
---
/work/SRC/openSUSE:Factory/ghc-jira-wiki-markup/ghc-jira-wiki-markup.changes
2020-06-19 17:14:15.334313147 +0200
+++
/work/SRC/openSUSE:Factory/.ghc-jira-wiki-markup.new.3060/ghc-jira-wiki-markup.changes
2020-07-09 13:19:46.441346687 +0200
@@ -1,0 +2,69 @@
+Wed Jul 8 14:05:19 UTC 2020 - [email protected]
+
+- Update jira-wiki-markup to version 1.3.2.
+
+ * Braces are now always escaped when printing; Jira treats braces
+ specially, regardless of context.
+
+ * Added support for links to anchors.
+
+ * Styled text may not wrap across multiple lines; linebreaks in
+ marked-up text are now forbidden.
+
+ * Module Text.Jira.Parser.Core: new function `many1Till` which
+ behaves like `manyTill`, but requires at least on element to be
+ parsed.
+
+ * Ensured the package works with GHC 8.10.
+
+ * Support was added for additional syntax constructs:
+
+ - citation markup (`??citation??`),
+ - links to attachments (`[title^attachment.ext]`), and
+ - user links (`[~username]`).
+
+ * Changes to module `Text.Jira.Markup`:
+
+ * A new data type `LinkType` is exported from the module.
+
+ * Changes to type `Inline`:
+
+ - a new constructor `Citation` has been added;
+ - the `Link` constructor now takes an additional
+ parameter of type `LinkType`.
+
+ * Fixed rendering of image attributes: image attributes are
+ separated by commas instead of pipes; the latter are used in
+ block parameters.
+
+ * Fixed parsing of blockquotes which are not preceeded by blank
+ lines.
+
+ * Ensure parsing of single-line blockquotes is possible even if
+ there is no space between `bq.` marker and contents.
+
+ * Fixed parsing of colors: parsing no longer fails for hexcolors
+ which contain non-decimal digits.
+
+ * Changes to module `Text.Jira.Parser.Shared`:
+
+ - New parsing function `colorName` which parses a color
+ descriptor, i.e. either a name or a hexcolor.
+
+ * Added check that a closing markup char is not preceeded by a
+ whitespace character. Previously, plain text was still
+ incorrectly treated as markup. E.g., the dashes in `-> step ->`
+ used to be interpreted as delimiters marking deleted text.
+
+ * Allows empty table cells; table parsing failed if one of the
+ cells did not contain any content.
+
+ * Changes to module `Text.Jira.Parser.Core`:
+
+ - A field `stateLastSpcPos` was added to data type
+ `ParserState` to keep track of spaces.
+ - Function `updateLastSpcPos` was added to update the
+ aforementioned field.
+ - Function `afterSpace` was added to test the field.
+
+-------------------------------------------------------------------
@@ -10,4 +79,29 @@
- Upstream has edited the change log file since the last release in
- a non-trivial way, i.e. they did more than just add a new entry
- at the top. You can review the file at:
- http://hackage.haskell.org/package/jira-wiki-markup-1.1.4/src/CHANGELOG.md
+
+ * Fixed parsing of image parameters. Thumbnails and images with
+ parameters were previously not recognized as images.
+
+ * Fixed table detection in endOfParagraph parser: Tables were
+ expected to have a space between the leading pipe(s) and the
+ cell content. Lines like `||Name|` were erroneously not
+ recognized as the beginning of a new block.
+
+ * Don't escape colon/semicolon unless necessary: it is necessary
+ to escape colons or semicolons only if they could otherwise
+ become part of a smiley.
+
+ * Colon `:` and semicolon `;` are now parsed as special
+ characters, since they can be the first characters of an emoji.
+
+ * Fixed parsing of words which contain non-special symbol
+ characters: word boundaries were not set correctly if a word
+ contained a dot `.` or similar chars.
+
+ * Fixed incorrect emphasis parsing: digits were erroneously allows
+ as the first characters after closing emphasis characters.
+
+ * Lists are now allowed to be indented; i.e., lists are still
+ recognized if list markers are preceded by spaces.
+
+ * Support for colored inlines has been added.
+
+ * New constructor `ColorInline` for type `Inline` (API change).
@@ -19 +112,0 @@
-
Old:
----
jira-wiki-markup-1.1.4.tar.gz
New:
----
jira-wiki-markup-1.3.2.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ ghc-jira-wiki-markup.spec ++++++
--- /var/tmp/diff_new_pack.b6ybL6/_old 2020-07-09 13:19:47.989351580 +0200
+++ /var/tmp/diff_new_pack.b6ybL6/_new 2020-07-09 13:19:47.989351580 +0200
@@ -19,7 +19,7 @@
%global pkg_name jira-wiki-markup
%bcond_with tests
Name: ghc-%{pkg_name}
-Version: 1.1.4
+Version: 1.3.2
Release: 0
Summary: Handle Jira wiki markup
License: MIT
++++++ jira-wiki-markup-1.1.4.tar.gz -> jira-wiki-markup-1.3.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/jira-wiki-markup-1.1.4/CHANGELOG.md
new/jira-wiki-markup-1.3.2/CHANGELOG.md
--- old/jira-wiki-markup-1.1.4/CHANGELOG.md 2001-09-09 03:46:40.000000000
+0200
+++ new/jira-wiki-markup-1.3.2/CHANGELOG.md 2001-09-09 03:46:40.000000000
+0200
@@ -4,12 +4,101 @@
`jira-wiki-markup` uses [PVP Versioning][1].
The changelog is available [on GitHub][2].
+1.3.2
+-----
+
+Released 2020-06-22.
+
+* Braces are now always escaped when printing; Jira treats braces
+ specially, regardless of context.
+
+1.3.1
+-----
+
+Released 2020-06-14
+
+* Added support for links to anchors.
+
+* Styled text may not wrap across multiple lines; linebreaks in
+ marked-up text are now forbidden.
+
+* Module Text.Jira.Parser.Core: new function `many1Till` which
+ behaves like `manyTill`, but requires at least on element to be
+ parsed.
+
+* Ensured the package works with GHC 8.10.
+
+1.3.0
+-----
+
+Released 2020-04-04
+
+* Support was added for additional syntax constructs:
+
+ - citation markup (`??citation??`),
+ - links to attachments (`[title^attachment.ext]`), and
+ - user links (`[~username]`).
+
+* Changes to module `Text.Jira.Markup`:
+
+ * A new data type `LinkType` is exported from the module.
+
+ * Changes to type `Inline`:
+
+ - a new constructor `Citation` has been added;
+ - the `Link` constructor now takes an additional
+ parameter of type `LinkType`.
+
+1.2.1
+-----
+
+Released 2020-04-02
+
+* Fixed rendering of image attributes: image attributes are
+ separated by commas instead of pipes; the latter are used in
+ block parameters.
+
+* Fixed parsing of blockquotes which are not preceeded by blank
+ lines.
+
+* Ensure parsing of single-line blockquotes is possible even if
+ there is no space between `bq.` marker and contents.
+
+* Fixed parsing of colors: parsing no longer fails for hexcolors
+ which contain non-decimal digits.
+
+* Changes to module `Text.Jira.Parser.Shared`:
+
+ - New parsing function `colorName` which parses a color
+ descriptor, i.e. either a name or a hexcolor.
+
+1.2.0
+-----
+
+Released 2020-03-28
+
+* Added check that a closing markup char is not preceeded by a
+ whitespace character. Previously, plain text was still
+ incorrectly treated as markup. E.g., the dashes in `-> step ->`
+ used to be interpreted as delimiters marking deleted text.
+
+* Allows empty table cells; table parsing failed if one of the
+ cells did not contain any content.
+
+* Changes to module `Text.Jira.Parser.Core`:
+
+ - A field `stateLastSpcPos` was added to data type
+ `ParserState` to keep track of spaces.
+ - Function `updateLastSpcPos` was added to update the
+ aforementioned field.
+ - Function `afterSpace` was added to test the field.
+
1.1.4
-----
Released 2020-03-27
-* Fix parsing of image parameters. Thumbnails and images with
+* Fixed parsing of image parameters. Thumbnails and images with
parameters were previously not recognized as images.
1.1.3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/jira-wiki-markup-1.1.4/README.md
new/jira-wiki-markup-1.3.2/README.md
--- old/jira-wiki-markup-1.1.4/README.md 2001-09-09 03:46:40.000000000
+0200
+++ new/jira-wiki-markup-1.3.2/README.md 2001-09-09 03:46:40.000000000
+0200
@@ -1,16 +1,21 @@
# jira-wiki-markup
[](https://hackage.haskell.org/package/jira-wiki-markup)
-[](LICENSE)
-[](http://stackage.org/lts/package/jira-wiki-markup)
-[](http://stackage.org/nightly/package/jira-wiki-markup)
-[](https://travis-ci.com/tarleb/jira-wiki-markup)
-[](https://ci.appveyor.com/project/tarleb/jira-wiki-markup)
+[![MIT license][License badge]](LICENSE)
+[![Stackage Lts][Stackage Lts
badge]](http://stackage.org/lts/package/jira-wiki-markup)
+[![Stackage Nightly][Stackage Nightly
badge]](http://stackage.org/nightly/package/jira-wiki-markup)
+[![Build status][Travis badge]](https://travis-ci.com/tarleb/jira-wiki-markup)
+[![Windows build status][AppVeyor
badge]](https://ci.appveyor.com/project/tarleb/jira-wiki-markup)
This package provides a parser and printer for [Jira wiki markup]. It
converts the raw text into an abstract syntax tree. The tree is easy to
handle and to translate into different output formats.
+[License badge]: https://img.shields.io/badge/license-MIT-blue.svg
+[Stackage Lts badge]: http://stackage.org/package/jira-wiki-markup/badge/lts
+[Stackage Nightly badge]:
http://stackage.org/package/jira-wiki-markup/badge/nightly
+[Travis badge]: https://travis-ci.com/tarleb/jira-wiki-markup.svg?branch=master
+[AppVeyor badge]:
https://ci.appveyor.com/api/projects/status/github/tarleb/jira-wiki-markup?branch=master&svg=true
[Jira wiki markup]:
https://jira.atlassian.com/secure/WikiRendererHelpAction.jspa?section=all
# License
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/jira-wiki-markup-1.1.4/jira-wiki-markup.cabal
new/jira-wiki-markup-1.3.2/jira-wiki-markup.cabal
--- old/jira-wiki-markup-1.1.4/jira-wiki-markup.cabal 2001-09-09
03:46:40.000000000 +0200
+++ new/jira-wiki-markup-1.3.2/jira-wiki-markup.cabal 2001-09-09
03:46:40.000000000 +0200
@@ -1,6 +1,6 @@
cabal-version: 2.0
name: jira-wiki-markup
-version: 1.1.4
+version: 1.3.2
synopsis: Handle Jira wiki markup
description: Parse jira wiki text into an abstract syntax tree for easy
transformation to other formats.
@@ -20,6 +20,7 @@
, GHC == 8.4.4
, GHC == 8.6.5
, GHC == 8.8.3
+ , GHC == 8.10.1
source-repository head
type: git
@@ -47,6 +48,8 @@
-Wcompat
-Widentities
-Wredundant-constraints
+ if impl(ghc >= 8.4)
+ ghc-options: -fhide-source-paths
default-language: Haskell2010
default-extensions: OverloadedStrings
@@ -68,6 +71,8 @@
-Wcompat
-Widentities
-Wredundant-constraints
+ if impl(ghc >= 8.4)
+ ghc-options: -fhide-source-paths
default-language: Haskell2010
default-extensions: OverloadedStrings
@@ -97,6 +102,8 @@
-Wcompat
-Widentities
-Wredundant-constraints
+ if impl(ghc >= 8.4)
+ ghc-options: -fhide-source-paths
default-language: Haskell2010
default-extensions: OverloadedStrings
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/jira-wiki-markup-1.1.4/src/Text/Jira/Markup.hs
new/jira-wiki-markup-1.3.2/src/Text/Jira/Markup.hs
--- old/jira-wiki-markup-1.1.4/src/Text/Jira/Markup.hs 2001-09-09
03:46:40.000000000 +0200
+++ new/jira-wiki-markup-1.3.2/src/Text/Jira/Markup.hs 2001-09-09
03:46:40.000000000 +0200
@@ -15,6 +15,7 @@
, Block (..)
, Inline (..)
, InlineStyle (..)
+ , LinkType (..)
, ListStyle (..)
, URL (..)
, ColorName (..)
@@ -37,12 +38,13 @@
data Inline
= Anchor Text -- ^ anchor for internal links
| AutoLink URL -- ^ URL which is also a link
+ | Citation [Inline] -- ^ source of a citation
| ColorInline ColorName [Inline] -- ^ colored inline text
| Emoji Icon -- ^ emoticon
| Entity Text -- ^ named or numeric HTML entity
| Image [Parameter] URL -- ^ an image
| Linebreak -- ^ hard linebreak
- | Link [Inline] URL -- ^ hyperlink with alias
+ | Link LinkType [Inline] URL -- ^ hyperlink with alias
| Monospaced [Inline] -- ^ text rendered with monospaced font
| Space -- ^ space between words
| SpecialChar Char -- ^ single char with special meaning
@@ -60,6 +62,14 @@
| Superscript -- ^ superscript text
deriving (Eq, Ord, Show)
+-- | Type of a link.
+data LinkType
+ = Attachment -- ^ link to an attachment
+ | Email -- ^ link to an email address
+ | External -- ^ external resource, like a website
+ | User -- ^ link to a user
+ deriving (Eq, Ord, Show)
+
-- | Blocks of text.
data Block
= Code Language [Parameter] Text -- ^ Code block with panel parameters
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/jira-wiki-markup-1.1.4/src/Text/Jira/Parser/Block.hs
new/jira-wiki-markup-1.3.2/src/Text/Jira/Parser/Block.hs
--- old/jira-wiki-markup-1.1.4/src/Text/Jira/Parser/Block.hs 2001-09-09
03:46:40.000000000 +0200
+++ new/jira-wiki-markup-1.3.2/src/Text/Jira/Parser/Block.hs 2001-09-09
03:46:40.000000000 +0200
@@ -30,6 +30,7 @@
import Text.Jira.Markup
import Text.Jira.Parser.Core
import Text.Jira.Parser.Inline
+import Text.Jira.Parser.Shared (colorName)
import Text.Parsec
-- | Parses any block element.
@@ -138,7 +139,7 @@
cell :: JiraParser Cell
cell = try $ do
mkCell <- cellStart
- bs <- many1 block
+ bs <- many block
return $ mkCell bs
-- | Parses the beginning of a table cell and returns a function which
@@ -166,7 +167,7 @@
blockQuote = try $ singleLineBq <|> multiLineBq
where
singleLineBq = BlockQuote . (:[]) . Para <$>
- (string "bq. " *> skipMany (char ' ') *>
+ (string "bq." *> skipMany (char ' ') *>
inline `manyTill` (void newline <|> eof))
multiLineBq = BlockQuote <$>
(string "{quote}" *> optional blankline *>
@@ -194,12 +195,9 @@
-- | Parses colored text into a @'Color'@ element.
color :: JiraParser Block
color= try $ do
- name <- string "{color:" *> (colorName <|> colorCode) <* char '}'
+ name <- string "{color:" *> colorName <* char '}'
content <- block `manyTill` try (string "{color}" *> blankline)
return $ Color (ColorName $ pack name) content
- where
- colorName = many letter
- colorCode = optional (char '#') *> count 6 digit
-- | Skip whitespace till we reach the next block
skipWhitespace :: JiraParser ()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/jira-wiki-markup-1.1.4/src/Text/Jira/Parser/Core.hs
new/jira-wiki-markup-1.3.2/src/Text/Jira/Parser/Core.hs
--- old/jira-wiki-markup-1.1.4/src/Text/Jira/Parser/Core.hs 2001-09-09
03:46:40.000000000 +0200
+++ new/jira-wiki-markup-1.3.2/src/Text/Jira/Parser/Core.hs 2001-09-09
03:46:40.000000000 +0200
@@ -19,10 +19,14 @@
, withStateFlag
-- * String position tracking
, updateLastStrPos
+ , updateLastSpcPos
, notAfterString
+ , afterString
+ , afterSpace
-- * Parsing helpers
, endOfPara
, notFollowedBy'
+ , many1Till
, blankline
, skipSpaces
, blockNames
@@ -41,7 +45,9 @@
data ParserState = ParserState
{ stateInLink :: Bool -- ^ whether the parser is within a
link
, stateInList :: Bool -- ^ whether the parser is within a
list
+ , stateInMarkup :: Bool -- ^ whether the parser is within
markup
, stateInTable :: Bool -- ^ whether the parser is within a
table
+ , stateLastSpcPos :: Maybe SourcePos -- ^ most recent space char position
, stateLastStrPos :: Maybe SourcePos -- ^ position at which the last string
-- ended
}
@@ -51,7 +57,9 @@
defaultState = ParserState
{ stateInLink = False
, stateInList = False
+ , stateInMarkup = False
, stateInTable = False
+ , stateLastSpcPos = Nothing
, stateLastStrPos = Nothing
}
@@ -71,12 +79,35 @@
pos <- getPosition
modifyState $ \st -> st { stateLastStrPos = Just pos }
--- | Checks whether the parser is directly after a string.
-notAfterString :: JiraParser Bool
-notAfterString = do
+-- | Updates the state, marking the current input position as the end of a
+-- string.
+updateLastSpcPos :: JiraParser ()
+updateLastSpcPos = do
+ pos <- getPosition
+ modifyState $ \st -> st { stateLastSpcPos = Just pos }
+
+-- | Returns @'True'@ if the current parser position is directly
+-- after a word/string. Returns @'False'@ if the parser is
+-- looking at the first character of the input.
+afterString :: JiraParser Bool
+afterString = do
curPos <- getPosition
prevPos <- stateLastStrPos <$> getState
- return (Just curPos /= prevPos)
+ return (Just curPos == prevPos)
+
+-- | Returns true when the current parser position is either at
+-- the beginning of the document or if the preceding characters
+-- did not belong to a string.
+notAfterString :: JiraParser Bool
+notAfterString = not <$> afterString
+
+-- | Returns @'True'@ iff the character before the current parser
+-- position was a space.
+afterSpace :: JiraParser Bool
+afterSpace = do
+ curPos <- getPosition
+ lastSpacePos <- stateLastSpcPos <$> getState
+ return (Just curPos == lastSpacePos)
-- | Parses a string with the given Jira parser.
parseJira :: JiraParser a -> Text -> Either ParseError a
@@ -103,17 +134,30 @@
value = pack <$> many1 (noneOf "\"'\n\r|{}=")
language = key <* (pipe <|> lookAhead (char '}'))
+-- | Like @manyTill@, but reads at least one item.
+many1Till :: (Show end)
+ => JiraParser a
+ -> JiraParser end
+ -> JiraParser [a]
+many1Till p end = do
+ notFollowedBy' end
+ first <- p
+ rest <- manyTill p end
+ return (first:rest)
+
-- | Succeeds if the parser is looking at the end of a paragraph.
endOfPara :: JiraParser ()
endOfPara = eof
<|> lookAhead blankline
<|> lookAhead headerStart
+ <|> lookAhead quoteStart
<|> lookAhead horizontalRule
<|> lookAhead listItemStart
<|> lookAhead tableStart
<|> lookAhead panelStart
where
headerStart = void $ char 'h' *> oneOf "123456" <* char '.'
+ quoteStart = void $ string "bq."
listItemStart = void $ skipSpaces *> many1 (oneOf "#*-") <* char ' '
tableStart = void $ skipSpaces *> many1 (char '|')
panelStart = void $ char '{' *> choice (map (try . string) blockNames)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jira-wiki-markup-1.1.4/src/Text/Jira/Parser/Inline.hs
new/jira-wiki-markup-1.3.2/src/Text/Jira/Parser/Inline.hs
--- old/jira-wiki-markup-1.1.4/src/Text/Jira/Parser/Inline.hs 2001-09-09
03:46:40.000000000 +0200
+++ new/jira-wiki-markup-1.3.2/src/Text/Jira/Parser/Inline.hs 2001-09-09
03:46:40.000000000 +0200
@@ -1,5 +1,6 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE TupleSections #-}
{-|
Module : Text.Jira.Parser.Inline
Copyright : © 2019–2020 Albert Krewinkel
@@ -16,6 +17,7 @@
-- * Inline component parsers
, anchor
, autolink
+ , citation
, colorInline
, dash
, emoji
@@ -60,6 +62,7 @@
, colorInline
, monospaced
, anchor
+ , citation
, entity
, specialChar
] <?> "inline"
@@ -68,20 +71,23 @@
-- | Characters which, depending on context, can have a special meaning.
specialChars :: String
-specialChars = "_+-*^~|[]{}(!&\\:;"
+specialChars = "_+-*^~|[]{}(?!&\\:;"
-- | Parses an in-paragraph newline as a @Linebreak@ element. Both newline
-- characters and double-backslash are recognized as line-breaks.
linebreak :: JiraParser Inline
-linebreak = Linebreak <$ try (
+linebreak = (<?> "linebreak") . try $ do
+ guard . not . stateInMarkup =<< getState
choice [ void $ newline <* notFollowedBy' endOfPara
, void $ string "\\\\" <* notFollowedBy' (char '\\')
]
- ) <?> "linebreak"
+ updateLastSpcPos
+ return Linebreak
-- | Parses whitespace and return a @Space@ element.
whitespace :: JiraParser Inline
-whitespace = Space <$ skipMany1 (char ' ') <?> "whitespace"
+whitespace = Space <$ skipMany1 (char ' ') <* updateLastSpcPos
+ <?> "whitespace"
-- | Parses a simple, markup-less string into a @Str@ element.
str :: JiraParser Inline
@@ -128,7 +134,7 @@
return $ if b then All . (/= '|') else mempty
inLinkPred <- do
b <- stateInLink <$> getState
- return $ if b then All . (`notElem` ("]|\n" :: String)) else mempty
+ return $ if b then All . (`notElem` ("]^|\n" :: String)) else mempty
oneOf $ filter (getAll . (inTablePred <> inLinkPred)) specialChars
@@ -162,13 +168,20 @@
guard . not . stateInLink =<< getState
withStateFlag (\b st -> st { stateInLink = b }) $ do
_ <- char '['
- alias <- option [] $ try (many inline <* char '|')
- linkUrl <- email <|> url
+ (alias, sep) <- option ([], '|') . try $ (,) <$> many inline <*> oneOf "^|"
+ (linkType, linkURL) <- if sep == '|'
+ then (Email,) <$> email <|>
+ (External,) <$> url <|>
+ (External,) <$> anchorLink <|>
+ (User,) <$> userLink
+ else (Attachment,) . URL . pack <$> many1 urlChar
_ <- char ']'
- return $ Link alias linkUrl
+ return $ Link linkType alias linkURL
+-- | Parse a plain URL or mail address as @'AutoLink'@ element.
autolink :: JiraParser Inline
-autolink = AutoLink <$> (email <|> url) <?> "email or other URL"
+autolink = AutoLink <$> (email' <|> url) <?> "email or other URL"
+ where email' = (\(URL e) -> URL ("mailto:" <> e)) <$> email
-- | Parse a URL with scheme @file@, @ftp@, @http@, @https@, @irc@, @nntp@, or
-- @news@.
@@ -188,10 +201,17 @@
'n' -> ("nntp" <$ string "ntp") <|> ("news" <$ string "ews")
_ -> fail "not looking at a known scheme"
--- | Parses an E-mail URL.
+-- | Parses an email URI, returns the mail address without schema.
email :: JiraParser URL
-email = URL . pack <$> try
- ((++) <$> string "mailto:" <*> many1 urlChar)
+email = URL . pack <$> try (string "mailto:" *> many1 urlChar)
+
+-- | Parses the link to an anchor name.
+anchorLink :: JiraParser URL
+anchorLink = URL . pack <$> ((:) <$> char '#' <*> many1 urlChar)
+
+-- | Parses a user-identifying resource name
+userLink :: JiraParser URL
+userLink = URL . pack <$> (char '~' *> many (noneOf "|]\n\r"))
-- | Parses a character which is allowed in URLs
urlChar :: JiraParser Char
@@ -205,12 +225,9 @@
-- | Text in a different color.
colorInline :: JiraParser Inline
colorInline = try $ do
- name <- string "{color:" *> (colorName <|> colorCode) <* char '}'
+ name <- string "{color:" *> colorName <* char '}'
content <- inline `manyTill` try (string "{color}")
return $ ColorInline (ColorName $ pack name) content
- where
- colorName = many1 letter
- colorCode = (:) <$> option '#' (char '#') <*> count 6 digit
--
-- Markup
@@ -222,7 +239,7 @@
where
simpleStyled = try $ do
styleChar <- lookAhead $ oneOf "-_+*~^"
- content <- styleChar `delimitingMany` inline
+ content <- noNewlines $ styleChar `delimitingMany` inline
let style = delimiterStyle styleChar
return $ Styled style content
@@ -230,9 +247,14 @@
styleChar <- char '{' *> oneOf "-_+*~^" <* char '}'
let closing = try $ string ['{', styleChar, '}']
let style = delimiterStyle styleChar
- content <- manyTill inline closing
+ content <- noNewlines $ manyTill inline closing
return $ Styled style content
+-- | Makes sure that the wrapped parser does not parse inline
+-- linebreaks.
+noNewlines :: JiraParser a -> JiraParser a
+noNewlines = withStateFlag (\b st -> st { stateInMarkup = b })
+
-- | Returns the markup kind from the delimiting markup character.
delimiterStyle :: Char -> InlineStyle
delimiterStyle = \case
@@ -250,6 +272,11 @@
<$> enclosed (try $ string "{{") (try $ string "}}") inline
<?> "monospaced"
+citation :: JiraParser Inline
+citation = Citation
+ <$> enclosed (try $ string "??") (try $ string "??") inline
+ <?> "citation"
+
--
-- Helpers
--
@@ -258,12 +285,15 @@
delimitingMany :: Char -> JiraParser a -> JiraParser [a]
delimitingMany c = enclosed (char c) (char c)
-enclosed :: JiraParser opening -> JiraParser closing
+enclosed :: Show closing
+ => JiraParser opening -> JiraParser closing
-> JiraParser a
-> JiraParser [a]
enclosed opening closing parser = try $ do
guard =<< notAfterString
- opening *> notFollowedBy space *> manyTill parser closing'
+ opening *> notFollowedBy space *> many1Till parser closing'
where
- closing' = try $ closing <* lookAhead wordBoundary
+ closing' = try $ do
+ guard . not =<< afterSpace
+ closing <* lookAhead wordBoundary
wordBoundary = void (satisfy (not . isAlphaNum)) <|> eof
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jira-wiki-markup-1.1.4/src/Text/Jira/Parser/Shared.hs
new/jira-wiki-markup-1.3.2/src/Text/Jira/Parser/Shared.hs
--- old/jira-wiki-markup-1.1.4/src/Text/Jira/Parser/Shared.hs 2001-09-09
03:46:40.000000000 +0200
+++ new/jira-wiki-markup-1.3.2/src/Text/Jira/Parser/Shared.hs 2001-09-09
03:46:40.000000000 +0200
@@ -12,6 +12,7 @@
-}
module Text.Jira.Parser.Shared
( icon
+ , colorName
) where
import Data.Char (isLetter)
@@ -60,3 +61,8 @@
"flag" -> pure IconFlag
"flagoff" -> pure IconFlagOff
_ -> fail ("not a known emoji" ++ name)
+
+colorName :: Parsec Text u String
+colorName = many1 letter <|> hexColor
+ where
+ hexColor = (:) <$> option '#' (char '#') <*> count 6 hexDigit
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/jira-wiki-markup-1.1.4/src/Text/Jira/Printer.hs
new/jira-wiki-markup-1.3.2/src/Text/Jira/Printer.hs
--- old/jira-wiki-markup-1.1.4/src/Text/Jira/Printer.hs 2001-09-09
03:46:40.000000000 +0200
+++ new/jira-wiki-markup-1.3.2/src/Text/Jira/Printer.hs 2001-09-09
03:46:40.000000000 +0200
@@ -50,11 +50,13 @@
renderInline s <> renderStyledSafely style inlns <> prettyInlines rest
Styled style inlns : s@(Str t) : rest | startsWithAlphaNum t ->
renderStyledSafely style inlns <> renderInline s <> prettyInlines rest
- s@Str{} : SpecialChar c : rest@(Str {}:_) ->
+ -- Most special chars don't need escaping when surrounded by spaces or within
+ -- a word. Braces are the exception, they should always be escaped.
+ s@Str{} : SpecialChar c : rest@(Str {}:_) | not (isBrace c) ->
(renderInline s `T.snoc` c) <> prettyInlines rest
- s@Space : SpecialChar c : rest@(Space {}:_) ->
+ s@Space : SpecialChar c : rest@(Space {}:_) | not (isBrace c) ->
(renderInline s `T.snoc` c) <> prettyInlines rest
- s@Linebreak : SpecialChar c : rest@(Space {}:_) ->
+ s@Linebreak : SpecialChar c : rest@(Space {}:_) | not (isBrace c) ->
(renderInline s `T.snoc` c) <> prettyInlines rest
-- Colon and semicolon only need escaping if they could otherwise
-- become part of a smiley.
@@ -62,10 +64,18 @@
T.singleton c <> prettyInlines rest
[SpecialChar c] | c `elem` [':', ';'] ->
T.singleton c
+ -- Questionmarks don't have to be escaped unless in groups of two
+ SpecialChar '?' : rest | not (startsWithQuestionMark rest) ->
+ "?" <> prettyInlines rest
(x:xs) ->
renderInline x <> prettyInlines xs
where
+ isBrace = \case
+ '{' -> True
+ '}' -> True
+ _ -> False
+
startsWithAlphaNum t = case T.uncons t of
Just (c, _) -> isAlphaNum c
_ -> False
@@ -73,6 +83,10 @@
Str x | x `elem` ["D", ")", "(", "P"] -> True
_ -> False
+ startsWithQuestionMark = \case
+ SpecialChar '?' : _ -> True
+ _ -> False
+
-- | Internal state used by the printer.
data PrinterState = PrinterState
{ stateInTable :: Bool
@@ -221,17 +235,15 @@
renderInline :: Inline -> Text
renderInline = \case
Anchor name -> "{anchor:" <> name <> "}"
- AutoLink url -> urlText url
+ AutoLink url -> fromURL url
+ Citation ils -> "??" <> prettyInlines ils <> "??"
ColorInline color ils -> "{color:" <> colorText color <> "}" <>
prettyInlines ils <> "{color}"
Emoji icon -> iconText icon
Entity entity -> "&" <> entity <> ";"
- Image params url -> "!" <> urlText url <>
- if null params
- then "!"
- else "|" <> renderParams params <> "!"
+ Image ps url -> "!" <> fromURL url <> renderImageParams ps <> "!"
Linebreak -> "\n"
- Link inlines (URL url) -> "[" <> prettyInlines inlines <> "|" <> url <> "]"
+ Link lt ils url -> renderLink lt ils url
Monospaced inlines -> "{{" <> prettyInlines inlines <> "}}"
Space -> " "
SpecialChar c -> case c of
@@ -246,6 +258,17 @@
let delim = T.pack ['{', delimiterChar style, '}']
in (delim <>) . (<> delim) . prettyInlines
+renderLink :: LinkType -> [Inline] -> URL -> Text
+renderLink linkType inlines url = case linkType of
+ Attachment -> "[" <> prettyInlines inlines <> "^" <> fromURL url <> "]"
+ Email -> link' $ "mailto:" <> fromURL url
+ External -> link' $ fromURL url
+ User -> link' $ "~" <> fromURL url
+ where
+ link' urlText = case inlines of
+ [] -> "[" <> urlText <> "]"
+ _ -> "[" <> prettyInlines inlines <> "|" <> urlText <> "]"
+
delimiterChar :: InlineStyle -> Char
delimiterChar = \case
Emphasis -> '_'
@@ -255,9 +278,12 @@
Subscript -> '~'
Superscript -> '^'
--- | Text rendering of an URL.
-urlText :: URL -> Text
-urlText (URL url) = url
+-- | Render image parameters (i.e., separate by comma).
+renderImageParams :: [Parameter] -> Text
+renderImageParams = \case
+ [] -> ""
+ ps | "thumbnail" `elem` map parameterKey ps -> "|thumbnail"
+ ps -> "|" <> T.intercalate ", " (map renderParam ps)
renderWrapped :: Char -> [Inline] -> Text
renderWrapped c = T.cons c . flip T.snoc c . prettyInlines
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jira-wiki-markup-1.1.4/test/Text/Jira/Parser/BlockTests.hs
new/jira-wiki-markup-1.3.2/test/Text/Jira/Parser/BlockTests.hs
--- old/jira-wiki-markup-1.1.4/test/Text/Jira/Parser/BlockTests.hs
2001-09-09 03:46:40.000000000 +0200
+++ new/jira-wiki-markup-1.3.2/test/Text/Jira/Parser/BlockTests.hs
2001-09-09 03:46:40.000000000 +0200
@@ -263,6 +263,18 @@
parseJira table "| * foo\n- bar\n" @?=
Right (Table [Row [BodyCell [ List CircleBullets [[Para [Str "foo"]]]
, List SquareBullets [[Para [Str
"bar"]]]]]])
+
+ , testCase "empty cell in row" $
+ parseJira table (Text.unlines
+ [ "|a|b|"
+ , "| |b|"
+ , "|a| |"
+ ]) @?=
+ Right (Table
+ [ Row [BodyCell [Para [Str "a"]], BodyCell [Para [Str "b"]]]
+ , Row [BodyCell [], BodyCell [Para [Str "b"]]]
+ , Row [BodyCell [Para [Str "a"]], BodyCell []]
+ ])
]
, testGroup "code"
@@ -321,10 +333,16 @@
parseJira color "{color:red}This is red.\n{color}\n" @?=
Right (Color (ColorName "red")
[Para [Str "This", Space, Str "is", Space, Str "red."]])
+
+ , testCase "paragraph preceeded by newline" $
+ parseJira color "{color:#cccccc}\nThis is gray.\n{color}\n" @?=
+ Right (Color (ColorName "#cccccc")
+ [Para [ Linebreak, Str "This", Space
+ , Str "is", Space, Str "gray."]])
]
, testGroup "blockQuote"
- [ testCase "single line quite before eof" $
+ [ testCase "single line right before eof" $
parseJira blockQuote "bq. this text" @?=
Right (BlockQuote [Para [Str "this", Space, Str "text"]])
@@ -332,6 +350,10 @@
parseJira blockQuote "bq. this test\n" @?=
Right (BlockQuote [Para [Str "this", Space, Str "test"]])
+ , testCase "single line w\\o leading space" $
+ parseJira blockQuote "bq.another test\n" @?=
+ Right (BlockQuote [Para [Str "another", Space, Str "test"]])
+
, testCase "multi-paragraph block quote" $
parseJira blockQuote "{quote}\npara1\n\npara2\n{quote}\n" @?=
Right (BlockQuote [ Para [Str "para1"]
@@ -356,14 +378,24 @@
parseJira ((,) <$> block <*> block) "h2.header\nparagraph\n" @?=
Right (Header 2 [Str "header"], Para [Str "paragraph"])
- , testCase "para before horizontal rule " $
+ , testCase "para before horizontal rule" $
parseJira ((,) <$> block <*> return HorizontalRule) "paragraph\n----\n"
@?=
Right (Para [Str "paragraph"], HorizontalRule)
- , testCase "para after horizontal rule " $
+ , testCase "para after horizontal rule" $
parseJira ((,) <$> block <*> block) "----\nparagraph\n" @?=
Right (HorizontalRule, Para [Str "paragraph"])
+ , testCase "para before blockquote" $
+ parseJira ((,) <$> block <*> block) "before\nbq. a quote\n" @?=
+ Right ( Para [Str "before"]
+ , BlockQuote [Para [Str "a", Space, Str "quote"]])
+
+ , testCase "para after blockquote" $
+ parseJira ((,) <$> block <*> block) "bq. a quote\nafter\n" @?=
+ Right ( BlockQuote [Para [Str "a", Space, Str "quote"]]
+ , Para [Str "after"] )
+
, testCase "para after list" $
parseJira ((,) <$> block <*> block) "* foo\n\nbar\n" @?=
Right (List CircleBullets [[Para [Str "foo"]]], Para [Str "bar"])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jira-wiki-markup-1.1.4/test/Text/Jira/Parser/InlineTests.hs
new/jira-wiki-markup-1.3.2/test/Text/Jira/Parser/InlineTests.hs
--- old/jira-wiki-markup-1.1.4/test/Text/Jira/Parser/InlineTests.hs
2001-09-09 03:46:40.000000000 +0200
+++ new/jira-wiki-markup-1.3.2/test/Text/Jira/Parser/InlineTests.hs
2001-09-09 03:46:40.000000000 +0200
@@ -135,6 +135,10 @@
parseJira styled "-far-fetched-" @?=
Right (Styled Strikeout [Str "far", SpecialChar '-', Str "fetched"])
+ , testCase "symbol before closing char" $
+ parseJira styled "-backwards<-" @?=
+ Right (Styled Strikeout [Str "backwards<"])
+
, testGroup "emphasis"
[ testCase "single word" $
parseJira styled "_single_" @?= Right (Styled Emphasis [Str
"single"])
@@ -160,6 +164,9 @@
, testCase "require word boundary after closing underscore" $
isLeft (parseJira styled "_nope_nope") @? "no boundary after closing"
+ , testCase "disallow newline in markup" $
+ isLeft (parseJira styled "_eol\nnext line_") @? "newline in markup"
+
, testCase "zero with space as word boundary" $
parseJira ((,) <$> styled <*> str) "_yup_\8203next" @?=
Right (Styled Emphasis [Str "yup"], Str "\8203next")
@@ -224,24 +231,56 @@
Right (AutoLink (URL "mailto:[email protected]"))
]
+ , testGroup "citation"
+ [ testCase "name" $
+ parseJira citation "??John Doe??" @?=
+ Right (Citation [Str "John", Space, Str "Doe"])
+
+ , testCase "with markup" $
+ parseJira citation "??Jane *Example* Doe??" @?=
+ Right (Citation [ Str "Jane", Space, Styled Strong [Str "Example"]
+ , Space, Str "Doe"])
+ ]
+
, testGroup "link"
[ testCase "unaliased link" $
parseJira link "[https://example.org]" @?=
- Right (Link [] (URL "https://example.org"))
+ Right (Link External [] (URL "https://example.org"))
, testCase "aliased link" $
parseJira link "[Example|https://example.org]" @?=
- Right (Link [Str "Example"] (URL "https://example.org"))
+ Right (Link External [Str "Example"] (URL "https://example.org"))
, testCase "alias with emphasis" $
parseJira link "[_important_ example|https://example.org]" @?=
- Right (Link [Styled Emphasis [Str "important"], Space, Str "example"]
+ Right (Link External
+ [Styled Emphasis [Str "important"], Space, Str "example"]
(URL "https://example.org"))
+ , testCase "link to anchor" $
+ parseJira link "[see here|#there]" @?=
+ Right (Link External [Str "see", Space, Str "here"] (URL "#there"))
+
, testCase "mail address" $
parseJira link "[send mail|mailto:[email protected]]" @?=
- Right (Link [Str "send", Space, Str "mail"]
- (URL "mailto:[email protected]"))
+ Right (Link Email [Str "send", Space, Str "mail"]
+ (URL "[email protected]"))
+
+ , testCase "attachment link" $
+ parseJira link "[testing^test.xml]" @?=
+ Right (Link Attachment [Str "testing"] (URL "test.xml"))
+
+ , testCase "attachment without description" $
+ parseJira link "[^results.txt]" @?=
+ Right (Link Attachment [] (URL "results.txt"))
+
+ , testCase "user link" $
+ parseJira link "[testing|~account-id:something]" @?=
+ Right (Link User [Str "testing"] (URL "account-id:something"))
+
+ , testCase "user without description" $
+ parseJira link "[~username]" @?=
+ Right (Link User [] (URL "username"))
]
, testGroup "image"
@@ -275,8 +314,8 @@
Right (ColorInline (ColorName "#526487") [Str "blueish"])
, testCase "hex color without hash" $
- parseJira colorInline "{color:526487}blueish{color}" @?=
- Right (ColorInline (ColorName "#526487") [Str "blueish"])
+ parseJira colorInline "{color:526Ab7}blueish{color}" @?=
+ Right (ColorInline (ColorName "#526Ab7") [Str "blueish"])
]
]
@@ -339,5 +378,17 @@
, SpecialChar '-', Str "3"
]
+ , testCase "ascii arrows" $
+ -- the hypens used to be treated as deletion markers.
+ parseJira (many1 inline) "-> step ->" @?=
+ Right [ SpecialChar '-', Str ">" , Space, Str "step", Space
+ , SpecialChar '-', Str ">"
+ ]
+
+ , testCase "long ascii arrow" $
+ parseJira (many1 inline) "click --> done" @?=
+ Right [ Str "click", Space, SpecialChar '-', SpecialChar '-'
+ , Str ">", Space, Str "done"]
+
]
]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jira-wiki-markup-1.1.4/test/Text/Jira/PrinterTests.hs
new/jira-wiki-markup-1.3.2/test/Text/Jira/PrinterTests.hs
--- old/jira-wiki-markup-1.1.4/test/Text/Jira/PrinterTests.hs 2001-09-09
03:46:40.000000000 +0200
+++ new/jira-wiki-markup-1.3.2/test/Text/Jira/PrinterTests.hs 2001-09-09
03:46:40.000000000 +0200
@@ -1,3 +1,4 @@
+{-# OPTIONS_GHC -fno-warn-orphans #-}
{-|
Module : Text.Jira.PrinterTests
Copyright : © 2019–2020 Albert Krewinkel
@@ -12,7 +13,8 @@
module Text.Jira.PrinterTests (tests) where
import Prelude hiding (unlines)
-import Data.Text (Text, unlines)
+import Data.String (IsString (fromString))
+import Data.Text (Text, pack, unlines)
import Test.Tasty (TestTree, testGroup)
import Test.Tasty.HUnit (testCase, (@?=))
import Text.Jira.Markup
@@ -116,9 +118,44 @@
renderInline (AutoLink (URL "https://example.org")) @?=
"https://example.org"
+ , testCase "citation" $
+ renderInline (Citation [Str "John", Space, Str "Doe"]) @?=
+ "??John Doe??"
+
, testCase "Emoji" $
renderInline (Emoji IconSmiling) @?= ":D"
+ , testCase "thumbnail" $
+ renderInline (Image [Parameter "thumbnail" ""] (URL "example.jpg")) @?=
+ "!example.jpg|thumbnail!"
+
+ , testCase "image attributes" $
+ let params = [Parameter "align" "right", Parameter "vspace" "4"]
+ in renderInline (Image params (URL "example.jpg")) @?=
+ "!example.jpg|align=right, vspace=4!"
+
+ , testGroup "link"
+ [ testCase "external link" $
+ renderInline (Link External [Str "example"] "https://example.org") @?=
+ "[example|https://example.org]"
+
+ , testCase "email link" $
+ renderInline (Link Email [Str "example"] "[email protected]") @?=
+ "[example|mailto:[email protected]]"
+
+ , testCase "attachment" $
+ renderInline (Link Attachment [Str "a", Space, Str "b"] "test.txt") @?=
+ "[a b^test.txt]"
+
+ , testCase "attachment without description" $
+ renderInline (Link Attachment [] "something.txt") @?=
+ "[^something.txt]"
+
+ , testCase "user" $
+ renderInline (Link User [Str "John", Space, Str "Doe"] "ab34-cdef") @?=
+ "[John Doe|~ab34-cdef]"
+ ]
+
, testCase "Styled Emphasis" $
renderInline (Styled Emphasis [Str "Hello,", Space, Str "World!"]) @?=
"_Hello, World!_"
@@ -134,7 +171,11 @@
]
, testGroup "combined inlines"
- [ testCase "special char between words" $
+ [ testCase "opening brace between words" $
+ prettyInlines [Str "a", SpecialChar '{', Str "b"] @?=
+ "a\\{b"
+
+ , testCase "other special char between words" $
prettyInlines [Str "easy", SpecialChar '-', Str "peasy"] @?=
"easy-peasy"
@@ -163,12 +204,29 @@
prettyInlines [SpecialChar ':', Space, Str "end"] @?=
": end"
+ , testCase "closing brace between spaces" $
+ prettyInlines [Space, SpecialChar '}', Space] @?=
+ " \\} "
+
, testCase "colon not escaped before opening paren" $
-- escaping the paren is enough
prettyInlines [SpecialChar ':', SpecialChar '('] @?=
":\\("
+
+ , testGroup "question marks"
+ [ testCase "escaped if followed by question mark" $
+ prettyInlines [SpecialChar '?', SpecialChar '?'] @?=
+ "\\??"
+
+ , testCase "unescaped before space" $
+ prettyInlines [SpecialChar '?', Space, Str "foo"] @?=
+ "? foo"
+ ]
]
]
renderBlock' :: Block -> Text
renderBlock' = withDefault . renderBlock
+
+instance IsString URL where
+ fromString = URL . pack