packages feed

commonmark-extensions 0.2.3.5 → 0.2.3.6

raw patch · 6 files changed

+121/−46 lines, 6 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

changelog.md view
@@ -1,5 +1,19 @@ # Changelog for commonmark-extensions +## 0.2.3.6++  * Fix pipe table parser so that `|`s don't interfere with+    other block structures (Michael Howell, #111, fixing #52 and+    #95). This parser is structured as a system that parses the+    *second* line first, then parses the first line. That is, if+    it detects a delimiter row as the second line of a+    paragraph, it converts the paragraph into a table. This+    seems counterintuitive, but it works better than trying to+    convert a table into a paragraph, since it might need to be+    something else.++  * Improve parsing of inline math (#110).+ ## 0.2.3.5    - Resolve entities inside wikilinks (#105, Michał Kukieła).
commonmark-extensions.cabal view
@@ -1,5 +1,5 @@ name:           commonmark-extensions-version:        0.2.3.5+version:        0.2.3.6 synopsis:       Pure Haskell commonmark parser. description:    This library provides some useful extensions to core commonmark
src/Commonmark/Extensions/Math.hs view
@@ -41,9 +41,10 @@   symbol '$'   display <- (True <$ symbol '$') <|> (False <$ notFollowedBy whitespace)   contents <- try $ untokenize <$> pDollarsMath 0+  let isWs c = c == ' ' || c == '\t' || c == '\r' || c == '\n'   if display      then displayMath contents <$ symbol '$'-     else if T.all (==' ') (T.takeEnd 1 contents)+     else if T.null contents || isWs (T.last contents)              -- don't allow math to end with SPACE + $              then mzero              else return $ inlineMath contents
src/Commonmark/Extensions/PipeTable.hs view
@@ -12,7 +12,8 @@  ) where -import Control.Monad (guard)+import Control.Monad (guard, void, mzero)+import Control.Monad.Trans.Class (lift) import Commonmark.Syntax import Commonmark.Types import Commonmark.Tokens@@ -137,30 +138,55 @@   { syntaxBlockSpecs = [pipeTableBlockSpec]   } +-- This parser is structured as a system that parses the *second* line first,+-- then parses the first line. That is, if it detects a delimiter row as the+-- second line of a paragraph, it converts the paragraph into a table. This seems+-- counterintuitive, but it works better than trying to convert a table into+-- a paragraph, since it might need to be something else.+--+-- See GH-52 and GH-95 pipeTableBlockSpec :: (Monad m, IsBlock il bl, IsInline il,                        HasPipeTable il bl)                    => BlockSpec m il bl pipeTableBlockSpec = BlockSpec      { blockType           = "PipeTable" -- :: Text      , blockStart          = try $ do -- :: BlockParser m il bl ()-         interruptsParagraph >>= guard . not-         nonindentSpaces-         notFollowedBy whitespace-         pos <- getPosition-         (cells, toks) <- withRaw pCells-         nl <- lookAhead lineEnd-         let tabledata = PipeTableData-              { pipeTableAlignments = []-              , pipeTableHeaders    = cells-              , pipeTableRows       = []-              }-         addNodeToStack $-               Node (defBlockData pipeTableBlockSpec){-                         blockStartPos = [pos]-                       , blockData = toDyn tabledata-                       , blockLines = [toks ++ [nl]]-                       } []-         return BlockStartMatch+             (cur:rest) <- nodeStack <$> getState+             guard $ blockParagraph (bspec cur)+             nonindentSpaces+             pos <- getPosition+             aligns <- pDividers+             skipWhile (hasType Spaces)+             lookAhead (eof <|> void lineEnd)++             st <- getState++             let headerLine =+                   case blockLines $ rootLabel cur of+                      [onlyLine] -> onlyLine+                      _ -> []++             cellsR <- lift $ runParserT pCells st "" headerLine+             case cellsR of+                Right cells ->+                   if length cells /= length aligns+                      then mzero -- parse fail: not a table+                      else do+                         updateState $ \st' -> st'{ nodeStack = rest }+                         let tabledata = PipeTableData+                               { pipeTableAlignments = aligns+                               , pipeTableHeaders    = cells+                               , pipeTableRows       = []+                               }+                         addNodeToStack $+                            Node (defBlockData pipeTableBlockSpec){+                                    blockStartPos = blockStartPos (rootLabel cur) ++ [pos]+                                  , blockData = toDyn tabledata+                                  , blockAttributes = blockAttributes (rootLabel cur)+                                  } []+                _ ->+                   mzero -- parse fail: not a table+             return BlockStartMatch      , blockCanContain     = \_ -> False -- :: BlockSpec m il bl -> Bool      , blockContainsLines  = False -- :: Bool      , blockParagraph      = False -- :: Bool@@ -173,26 +199,11 @@                              , pipeTableHeaders = []                              , pipeTableRows = [] }          pos <- getPosition-         if null (blockLines ndata)-           then do-             cells <- pCells-             let tabledata' = tabledata{ pipeTableRows =-                                 cells : pipeTableRows tabledata }-             return $! (pos, Node ndata{ blockData =-                                   toDyn tabledata' } children)-           else-             -- last line was first; check for separators-             -- and if not found, convert to paragraph:-             try (do aligns <- pDividers-                     guard $ length aligns ==-                             length (pipeTableHeaders tabledata)-                     let tabledata' = tabledata{ pipeTableAlignments = aligns }-                     return $! (pos, Node ndata{-                                              blockLines = []-                                            , blockData = toDyn tabledata'-                                            } children))-             <|> (return $! (pos, Node ndata{-                                   blockSpec = paraSpec } children))+         cells <- pCells+         let tabledata' = tabledata{ pipeTableRows =+                             cells : pipeTableRows tabledata }+         return $! (pos, Node ndata{ blockData =+                               toDyn tabledata' } children)      , blockConstructor    = \(Node ndata _) -> do          let tabledata = fromDyn                 (blockData ndata)@@ -206,8 +217,5 @@                     (reverse $ pipeTableRows tabledata)          return $! (pipeTable aligns headers rows)      , blockFinalize       = \(Node ndata children) parent ->-         defaultFinalizer-           (if null (blockLines ndata)-               then Node ndata children-               else Node ndata{ blockSpec = paraSpec } children) parent+         defaultFinalizer (Node ndata children) parent      }
test/math.md view
@@ -18,9 +18,13 @@ ```````````````````````````````` example This is not math: 2000$. And neither is this $ 4 $.+Or this $4+$. . <p>This is not math: 2000$.-And neither is this $ 4 $.</p>+And neither is this $ 4 $.+Or this $4+$.</p> ````````````````````````````````  Display math delimiters can be surrounded by whitespace:
test/pipe_tables.md view
@@ -264,3 +264,51 @@ </code></pre> ```````````````````````````````` ++Pipe tables have exactly one header row, and do not interrupt paragraphs.++```````````````````````````````` example+| Too much table | to be considered table |+| Too much table | to be considered table |+|----------------|------------------------|+| Too much table | to be considered table |+.+<p>| Too much table | to be considered table |+| Too much table | to be considered table |+|----------------|------------------------|+| Too much table | to be considered table |</p>+````````````````````````````````+++Other block structures, like headers, have higher priority than tables.+Tables can be nested in other elements, but don't benefit from laziness.++```````````````````````````````` example+# abc | def+------|-----+++> abc | def+> ----|-----+++> abc | def+----|-----+.+<h1>abc | def</h1>+<p>------|-----</p>+<blockquote>+<table>+<thead>+<tr>+<th>abc</th>+<th>def</th>+</tr>+</thead>+</table>+</blockquote>+<blockquote>+<p>abc | def+----|-----</p>+</blockquote>+````````````````````````````````