packages feed

patat 0.14.2.0 → 0.15.0.0

raw patch · 10 files changed

+211/−53 lines, 10 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Patat.Presentation: [psLinks] :: PresentationSettings -> !Maybe LinkSettings
+ Patat.Presentation.Display.Internal: [dsOSC8] :: DisplaySettings -> !Bool
+ Patat.Presentation.Internal: [psLinks] :: PresentationSettings -> !Maybe LinkSettings
+ Patat.Presentation.Settings: LinkSettings :: !Maybe Bool -> LinkSettings
+ Patat.Presentation.Settings: [lsOSC8] :: LinkSettings -> !Maybe Bool
+ Patat.Presentation.Settings: [psLinks] :: PresentationSettings -> !Maybe LinkSettings
+ Patat.Presentation.Settings: data LinkSettings
+ Patat.Presentation.Settings: instance Data.Aeson.Types.FromJSON.FromJSON Patat.Presentation.Settings.LinkSettings
+ Patat.Presentation.Settings: instance GHC.Base.Semigroup Patat.Presentation.Settings.LinkSettings
+ Patat.Presentation.Settings: instance GHC.Classes.Eq Patat.Presentation.Settings.LinkSettings
+ Patat.Presentation.Settings: instance GHC.Show.Show Patat.Presentation.Settings.LinkSettings
+ Patat.PrettyPrint: hyperlink :: String -> Doc -> Doc
+ Patat.PrettyPrint.Internal: Hyperlink :: String -> d -> DocE d
+ Patat.PrettyPrint.Internal: HyperlinkChunk :: HyperlinkID -> [SGR] -> String -> String -> Chunk
- Patat.Presentation: PresentationSettings :: !Maybe (FlexibleNum Int) -> !Maybe (FlexibleNum Int) -> !Maybe MarginSettings -> !Maybe Wrap -> !Maybe (FlexibleNum Int) -> !Maybe Theme -> !Maybe Bool -> !Maybe (FlexibleNum Int) -> !Maybe Int -> !Maybe ExtensionList -> !Maybe ImageSettings -> !Maybe Bool -> !Maybe EvalSettingsMap -> !Maybe Bool -> !Maybe [FilePath] -> !Maybe SpeakerNotesSettings -> !Maybe TransitionSettings -> PresentationSettings
+ Patat.Presentation: PresentationSettings :: !Maybe (FlexibleNum Int) -> !Maybe (FlexibleNum Int) -> !Maybe MarginSettings -> !Maybe Wrap -> !Maybe (FlexibleNum Int) -> !Maybe Theme -> !Maybe Bool -> !Maybe (FlexibleNum Int) -> !Maybe Int -> !Maybe ExtensionList -> !Maybe ImageSettings -> !Maybe Bool -> !Maybe EvalSettingsMap -> !Maybe Bool -> !Maybe [FilePath] -> !Maybe SpeakerNotesSettings -> !Maybe TransitionSettings -> !Maybe LinkSettings -> PresentationSettings
- Patat.Presentation.Display.Internal: DisplaySettings :: !Size -> !Wrap -> !Int -> !Margins -> !Theme -> !SyntaxMap -> !Var -> [Block] -> !RevealState -> DisplaySettings
+ Patat.Presentation.Display.Internal: DisplaySettings :: !Size -> !Wrap -> !Int -> !Margins -> !Bool -> !Theme -> !SyntaxMap -> !Var -> [Block] -> !RevealState -> DisplaySettings
- Patat.Presentation.Internal: PresentationSettings :: !Maybe (FlexibleNum Int) -> !Maybe (FlexibleNum Int) -> !Maybe MarginSettings -> !Maybe Wrap -> !Maybe (FlexibleNum Int) -> !Maybe Theme -> !Maybe Bool -> !Maybe (FlexibleNum Int) -> !Maybe Int -> !Maybe ExtensionList -> !Maybe ImageSettings -> !Maybe Bool -> !Maybe EvalSettingsMap -> !Maybe Bool -> !Maybe [FilePath] -> !Maybe SpeakerNotesSettings -> !Maybe TransitionSettings -> PresentationSettings
+ Patat.Presentation.Internal: PresentationSettings :: !Maybe (FlexibleNum Int) -> !Maybe (FlexibleNum Int) -> !Maybe MarginSettings -> !Maybe Wrap -> !Maybe (FlexibleNum Int) -> !Maybe Theme -> !Maybe Bool -> !Maybe (FlexibleNum Int) -> !Maybe Int -> !Maybe ExtensionList -> !Maybe ImageSettings -> !Maybe Bool -> !Maybe EvalSettingsMap -> !Maybe Bool -> !Maybe [FilePath] -> !Maybe SpeakerNotesSettings -> !Maybe TransitionSettings -> !Maybe LinkSettings -> PresentationSettings
- Patat.Presentation.Settings: PresentationSettings :: !Maybe (FlexibleNum Int) -> !Maybe (FlexibleNum Int) -> !Maybe MarginSettings -> !Maybe Wrap -> !Maybe (FlexibleNum Int) -> !Maybe Theme -> !Maybe Bool -> !Maybe (FlexibleNum Int) -> !Maybe Int -> !Maybe ExtensionList -> !Maybe ImageSettings -> !Maybe Bool -> !Maybe EvalSettingsMap -> !Maybe Bool -> !Maybe [FilePath] -> !Maybe SpeakerNotesSettings -> !Maybe TransitionSettings -> PresentationSettings
+ Patat.Presentation.Settings: PresentationSettings :: !Maybe (FlexibleNum Int) -> !Maybe (FlexibleNum Int) -> !Maybe MarginSettings -> !Maybe Wrap -> !Maybe (FlexibleNum Int) -> !Maybe Theme -> !Maybe Bool -> !Maybe (FlexibleNum Int) -> !Maybe Int -> !Maybe ExtensionList -> !Maybe ImageSettings -> !Maybe Bool -> !Maybe EvalSettingsMap -> !Maybe Bool -> !Maybe [FilePath] -> !Maybe SpeakerNotesSettings -> !Maybe TransitionSettings -> !Maybe LinkSettings -> PresentationSettings

Files

CHANGELOG.md view
@@ -1,5 +1,50 @@ # Changelog +## 0.15.0.0 (2025-04-05)++ *  Add [OSC8] support for hyperlinks (#185).  This makes hyperlinks clickable+    in many terminal emulators (see [OSC8 adoption]).++    There is currently no way to detect if a terminal supports this feature,+    so for now this needs to be explicitly turned on in the configuration:++    ```yaml+    patat:+      links:+        osc8: true+    ```++ *  Enable `shortcut_reference_links` by default.  These are reference links+    without the second pair of brackets, e.g.:++    ```markdown+    See [my website].++    [my website]: http://example.com+    ```++ *  Validate settings on slide (#186).++    This validation was present since the introduction of slide settings, but it+    was accidentally removed in v0.14.++ *  Improve reference link rendering.++    This changes the way references are rendered from:++        [example](http://example.com/)+        [example with title](http://example.com/ "title")++    To:++        [example]: http://example.com/+        [example with title]: http://example.com/ title++    This easier to read and more coherent with Pandoc markdown.++[OSC8]: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda+[OSC8 adoption]: https://github.com/Alhadis/OSC8-Adoption+ ## 0.14.2.0 (2024-03-10)   *  Fix WezTerm image rendering when using panes (#182).
README.md view
@@ -56,6 +56,7 @@     -   [Evaluating code](#evaluating-code)     -   [Speaker notes](#speaker-notes)     -   [Transitions](#transitions)+    -   [Links](#links) -   [Trivia](#trivia)  Installation@@ -884,6 +885,23 @@ You can optionally set `items` to a non-empty list of transition effects to randomly sample from.  If `items` is not set, `patat` will simply sample from all transition effects using their respective default settings.++### Links++Version 0.15.0.0 and later support [OSC8] for hyperlinks.  This makes hyperlinks+clickable in many terminal emulators (see [OSC8 adoption]).++There is currently no way to detect if a terminal supports this feature, so you+need to explicitly turn this on in the configuration:++```yaml+patat:+  links:+    osc8: true+```++[OSC8]: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda+[OSC8 adoption]: https://github.com/Alhadis/OSC8-Adoption  Trivia ------
lib/Patat/Presentation/Display.hs view
@@ -67,6 +67,7 @@         , dsMargins       = margins settings         , dsWrap          = fromMaybe NoWrap $ psWrap settings         , dsTabStop       = maybe 4 A.unFlexibleNum $ psTabStop settings+        , dsOSC8          = fromMaybe False (psLinks settings >>= lsOSC8)         , dsTheme         = fromMaybe Theme.defaultTheme (psTheme settings)         , dsSyntaxMap     = pSyntaxMap         , dsResolve       = \var -> fromMaybe [] $ HMS.lookup var pVars@@ -410,9 +411,10 @@  prettyInline ds link@(Link _attrs _text (target, _title))     | Just (text, _, _) <- toReferenceLink link =-        "[" <> themed ds themeLinkText (prettyInlines ds text) <> "]"+        let doc = Just $ prettyInlines ds text in+        "[" <> themed ds themeLinkText (hyperlink ds target doc) <> "]"     | otherwise =-        "<" <> themed ds themeLinkTarget (PP.text target) <> ">"+        "<" <> themed ds themeLinkTarget (hyperlink ds target Nothing) <> ">"  prettyInline _ds SoftBreak = PP.softline @@ -469,12 +471,11 @@         "[" <>         themed ds themeLinkText             (prettyInlines ds $ newlineToSpace text) <>-        "](" <>+        "]: " <>         themed ds themeLinkTarget (PP.text target) <>         (if T.null title             then mempty-            else PP.space <> "\"" <> PP.text title <> "\"")-        <> ")"+            else PP.space <> PP.text title)      newlineToSpace :: [Inline] -> [Inline]     newlineToSpace = runIdentity . dftInlines (pure . pure) work@@ -490,3 +491,13 @@ toReferenceLink (Link _attrs text (target, title))     | [Str target] /= text = Just (text, target, title) toReferenceLink _ = Nothing+++--------------------------------------------------------------------------------+hyperlink :: DisplaySettings -> T.Text -> Maybe PP.Doc -> PP.Doc+hyperlink ds url Nothing+    | dsOSC8 ds = PP.hyperlink (T.unpack url) (PP.text url)+    | otherwise = PP.text url+hyperlink ds url (Just doc)+    | dsOSC8 ds = PP.hyperlink (T.unpack url) doc+    | otherwise = doc
lib/Patat/Presentation/Display/Internal.hs view
@@ -21,6 +21,7 @@     , dsWrap        :: !Wrap     , dsTabStop     :: !Int     , dsMargins     :: !Margins+    , dsOSC8        :: !Bool     , dsTheme       :: !Theme.Theme     , dsSyntaxMap   :: !Skylighting.SyntaxMap     , dsResolve     :: !(Var -> [Block])
lib/Patat/Presentation/Settings.hs view
@@ -24,6 +24,8 @@      , TransitionSettings (..) +    , LinkSettings (..)+     , parseSlideSettings     ) where @@ -65,6 +67,7 @@     , psSyntaxDefinitions :: !(Maybe [FilePath])     , psSpeakerNotes      :: !(Maybe SpeakerNotesSettings)     , psTransition        :: !(Maybe TransitionSettings)+    , psLinks             :: !(Maybe LinkSettings)     } deriving (Eq, Show)  @@ -88,6 +91,7 @@         , psSyntaxDefinitions = on (<>)  psSyntaxDefinitions l r         , psSpeakerNotes      = on mplus psSpeakerNotes      l r         , psTransition        = on mplus psTransition        l r+        , psLinks             = on (<>)  psLinks             l r         }  @@ -97,7 +101,7 @@     mempty  = PresentationSettings                 Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing                 Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing-                Nothing+                Nothing Nothing   --------------------------------------------------------------------------------@@ -204,6 +208,7 @@     , Pandoc.Ext_strikeout     , Pandoc.Ext_superscript     , Pandoc.Ext_subscript+    , Pandoc.Ext_shortcut_reference_links     ]  @@ -293,6 +298,25 @@ instance A.FromJSON TransitionSettings where     parseJSON = A.withObject "FromJSON TransitionSettings" $ \o ->         TransitionSettings <$> o A..: "type" <*> pure o+++--------------------------------------------------------------------------------+data LinkSettings = LinkSettings+    { lsOSC8 :: !(Maybe Bool)+    } deriving (Eq, Show)+++--------------------------------------------------------------------------------+instance Semigroup LinkSettings where+    l <> r = LinkSettings+        { lsOSC8 = on mplus lsOSC8 l r+        }+++--------------------------------------------------------------------------------+instance A.FromJSON LinkSettings where+    parseJSON = A.withObject "FromJSON LinkSettings" $ \o ->+        LinkSettings <$> o A..:? "osc8"   --------------------------------------------------------------------------------
lib/Patat/Presentation/Syntax.hs view
@@ -48,7 +48,8 @@ import qualified Data.Text.Encoding          as T import           Data.Traversable            (for) import qualified Data.Yaml                   as Yaml-import           Patat.Presentation.Settings (PresentationSettings)+import           Patat.Presentation.Settings (PresentationSettings,+                                              parseSlideSettings) import           Patat.Unique import qualified Text.Pandoc                 as Pandoc import qualified Text.Pandoc.Writers.Shared  as Pandoc@@ -201,7 +202,7 @@     , Just t2 <- T.stripSuffix "-->" t1 = pure $ Config $         case Yaml.decodeEither' (T.encodeUtf8 t2) of             Left err  -> Left (show err)-            Right obj -> Right obj+            Right obj -> parseSlideSettings obj     -- Parse other comments.     | Just t1 <- T.stripPrefix "<!--" body     , Just t2 <- T.stripSuffix "-->" t1 = pure $ SpeakerNote $ T.strip t2@@ -296,13 +297,13 @@ -- items become visible. data RevealSequence a = RevealSequence     { -- The ID used for this sequence.-      rsID :: RevealID+      rsID      :: RevealID     , -- These reveals should be advanced in this order.       -- Reveal IDs will be included multiple times if needed.       --       -- This should (only) contain the ID of this counter, and IDs of counters       -- nested inside the children fields.-      rsOrder :: [RevealID]+      rsOrder   :: [RevealID]     , -- For each piece of content in this sequence, we store a set of ints.       -- When the current counter state is included in this set, the item is       -- visible.
lib/Patat/PrettyPrint.hs view
@@ -29,6 +29,7 @@     , deindent      , ansi+    , hyperlink      , (<+>)     , (<$$>)@@ -126,6 +127,11 @@ -------------------------------------------------------------------------------- ansi :: [Ansi.SGR] -> Doc -> Doc ansi codes =  mkDoc . Ansi (codes ++)+++--------------------------------------------------------------------------------+hyperlink :: String -> Doc -> Doc+hyperlink url =  mkDoc . Hyperlink url   --------------------------------------------------------------------------------
lib/Patat/PrettyPrint/Internal.hs view
@@ -34,7 +34,7 @@ -------------------------------------------------------------------------------- import           Control.Monad.Reader       (asks, local) import           Control.Monad.RWS          (RWS, runRWS)-import           Control.Monad.State        (get, modify)+import           Control.Monad.State        (get, modify, state) import           Control.Monad.Writer       (tell) import           Data.Char.WCWidth.Extended (wcstrwidth) import qualified Data.List                  as L@@ -53,9 +53,16 @@   --------------------------------------------------------------------------------+-- | Hyperlinks can be printed in multiple parts when formatting is used.  The+-- ID is used to tell which ones belong to the same link.+type HyperlinkID = Int+++-------------------------------------------------------------------------------- -- | A simple chunk of text.  All ANSI codes are "reset" after printing. data Chunk     = StringChunk [Ansi.SGR] String+    | HyperlinkChunk HyperlinkID [Ansi.SGR] String String -- Codes, title, URL     | NewlineChunk     | ControlChunk Control     deriving (Eq, Show)@@ -72,6 +79,10 @@     Ansi.hSetSGR h (reverse codes)     IO.hPutStr h str     Ansi.hSetSGR h [Ansi.Reset]+hPutChunk h (HyperlinkChunk hid codes str url) = do+    Ansi.hSetSGR h (reverse codes)+    Ansi.hHyperlinkWithId h (show hid) url str+    Ansi.hSetSGR h [Ansi.Reset] hPutChunk h (ControlChunk ctrl) = case ctrl of     ClearScreenControl -> Ansi.hClearScreen h     GoToLineControl l  -> Ansi.hSetCursorPosition h l 0@@ -79,21 +90,29 @@  -------------------------------------------------------------------------------- chunkToString :: Chunk -> String-chunkToString NewlineChunk        = "\n"-chunkToString (StringChunk _ str) = str-chunkToString (ControlChunk _)    = ""+chunkToString NewlineChunk               = "\n"+chunkToString (StringChunk _ str)        = str+chunkToString (HyperlinkChunk _ _ str _) = str+chunkToString (ControlChunk _)           = ""   -------------------------------------------------------------------------------- -- | If two neighboring chunks have the same set of ANSI codes, we can group -- them together. optimizeChunks :: Chunks -> Chunks-optimizeChunks (StringChunk c1 s1 : StringChunk c2 s2 : chunks)-    | c1 == c2  = optimizeChunks (StringChunk c1 (s1 <> s2) : chunks)-    | otherwise =-        StringChunk c1 s1 : optimizeChunks (StringChunk c2 s2 : chunks)-optimizeChunks (x : chunks) = x : optimizeChunks chunks-optimizeChunks [] = []+optimizeChunks chunks = case chunks of+    (StringChunk c1 s1 : StringChunk c2 s2 : t)+        | c1 == c2 -> optimizeChunks (StringChunk c1 (s1 <> s2) : t)+        | otherwise ->+            StringChunk c1 s1 : optimizeChunks (StringChunk c2 s2 : t)+    (HyperlinkChunk i1 c1 s1 u1 : HyperlinkChunk i2 c2 s2 u2 : t)+        | i1 == i2 && c1 == c2 && u1 == u2 -> optimizeChunks $+            HyperlinkChunk i1 c1 (s1 <> s2) u1 : t+        | otherwise ->+            HyperlinkChunk i1 c1 s1 u1 :+            optimizeChunks (HyperlinkChunk i2 c2 s2 u2 : t)+    x : t -> x : optimizeChunks t+    [] -> []   --------------------------------------------------------------------------------@@ -123,15 +142,19 @@         , indentOtherLines :: Indentation [Chunk]         , indentDoc        :: d         }+    | Hyperlink String d     | Control Control     deriving (Functor)   -------------------------------------------------------------------------------- chunkToDocE :: Chunk -> DocE Doc-chunkToDocE NewlineChunk         = Hardline-chunkToDocE (StringChunk c1 str) = Ansi (\c0 -> c1 ++ c0) (Doc [String str])-chunkToDocE (ControlChunk ctrl)  = Control ctrl+chunkToDocE chunk = case chunk of+    NewlineChunk              -> Hardline+    ControlChunk ctrl         -> Control ctrl+    StringChunk c1 s          -> Ansi (\c0 -> c1 ++ c0) $ Doc [String s]+    HyperlinkChunk _ c1 s url -> Ansi (\c0 -> c1 ++ c0) $ Doc+        [Hyperlink url $ Doc [String s]]   --------------------------------------------------------------------------------@@ -151,17 +174,29 @@  -------------------------------------------------------------------------------- data DocEnv = DocEnv-    { deCodes  :: [Ansi.SGR]             -- ^ Most recent ones first in the list-    , deIndent :: [Indentation [Chunk]]  -- ^ No need to store first-line indent-    , deWrap   :: Maybe Int              -- ^ Wrap at columns+    { -- | Most recent ones first+      deCodes     :: [Ansi.SGR]+    , -- | First-line indent not included+      deIndent    :: [Indentation [Chunk]]+    , -- | Wrap at columns+      deWrap      :: Maybe Int+    , -- | Hyperlink context+      deHyperlink :: Maybe (HyperlinkID, String)     }   ---------------------------------------------------------------------------------type DocM = RWS DocEnv Chunks LineBuffer+data DocState = DocState+    { dsLineBuffer  :: LineBuffer+    , dsHyperlinkID :: Int+    }   --------------------------------------------------------------------------------+type DocM = RWS DocEnv Chunks DocState+++-------------------------------------------------------------------------------- -- | Note that the lists here are reversed so we have fast append. -- We also store the current length to avoid having to recompute it. data LineBuffer = LineBuffer Int [Indentation [Chunk]] [Chunk]@@ -203,9 +238,10 @@ -------------------------------------------------------------------------------- docToChunks :: Doc -> Chunks docToChunks doc0 =-    let env0        = DocEnv [] [] Nothing-        ((), b, cs) = runRWS (go $ unDoc doc0) env0 emptyLineBuffer in-    optimizeChunks (cs <> bufferToChunks b)+    let env0        = DocEnv [] [] Nothing Nothing+        state0      = DocState emptyLineBuffer 0+        ((), finalState, cs) = runRWS (go $ unDoc doc0) env0 state0 in+    optimizeChunks (cs <> bufferToChunks (dsLineBuffer finalState))   where     go :: [DocE Doc] -> DocM () @@ -216,6 +252,12 @@         appendChunk chunk         go docs +    go (Hyperlink url doc : docs) = do+        hid <- state $ \s ->+            let hid = dsHyperlinkID s in (hid, s {dsHyperlinkID = hid + 1})+        local (\env -> env {deHyperlink = Just (hid, url)}) (go $ unDoc doc)+        go docs+     go (Softspace : docs) = do         hard <- softConversion Softspace docs         go (hard : docs)@@ -230,12 +272,13 @@         go (hard : docs)      go (Hardline : docs) = do-        buffer <- get+        buffer <- dsLineBuffer <$> get         tell $ bufferToChunks buffer <> [NewlineChunk]         ind <- asks deIndent-        modify $ \_ -> case docs of-            []    -> emptyLineBuffer-            _ : _ -> LineBuffer (sum $ map indentationWidth ind) ind []+        let indw = sum $ map indentationWidth ind+        modify $ \s -> case docs of+            []    -> s {dsLineBuffer = emptyLineBuffer}+            _ : _ -> s {dsLineBuffer = LineBuffer indw ind []}         go docs      go (WrapAt {..} : docs) = do@@ -250,8 +293,10 @@      go (Indent {..} : docs) = do         local (\e -> e {deIndent = indentOtherLines : deIndent e}) $ do-            modify $ \(LineBuffer w i c) -> LineBuffer-                (w + indentationWidth indentFirstLine) (indentFirstLine : i) c+            modify $ \s ->+                let LineBuffer w i c = dsLineBuffer s+                    w' = w + indentationWidth indentFirstLine in+                s {dsLineBuffer = LineBuffer w' (indentFirstLine : i) c}             go (unDoc indentDoc)         go docs @@ -259,15 +304,19 @@         tell [ControlChunk ctrl]         go docs -     makeChunk :: String -> DocM Chunk     makeChunk str = do         codes <- asks deCodes-        return $ StringChunk codes str+        mbHyperlink <- asks deHyperlink+        return $ case mbHyperlink of+            Just (hid, url) -> HyperlinkChunk hid codes str url+            Nothing         -> StringChunk codes str      appendChunk :: Chunk -> DocM ()-    appendChunk c = modify $ \(LineBuffer w i cs) ->-        LineBuffer (w + wcstrwidth (chunkToString c)) i (c : cs)+    appendChunk c = modify $ \s ->+        let LineBuffer w i cs = dsLineBuffer s+            w' = w + wcstrwidth (chunkToString c) in+        s {dsLineBuffer = LineBuffer w' i (c : cs)}      -- Convert 'Softspace' or 'Softline' to 'Hardspace' or 'Hardline'     softConversion :: DocE Doc -> [DocE Doc] -> DocM (DocE Doc)@@ -276,7 +325,7 @@         case mbWrapCol of             Nothing     -> return hard             Just maxCol -> do-                LineBuffer currentCol _ _ <- get+                LineBuffer currentCol _ _ <- dsLineBuffer <$> get                 case nextWordLength docs of                     Nothing                            -> return hard                     Just l@@ -289,18 +338,19 @@             _         -> soft      nextWordLength :: [DocE Doc] -> Maybe Int-    nextWordLength []                 = Nothing+    nextWordLength []                  = Nothing     nextWordLength (String x : xs)-        | L.null x                    = nextWordLength xs-        | otherwise                   = Just (wcstrwidth x)-    nextWordLength (Softspace : xs)   = nextWordLength xs-    nextWordLength (Hardspace : xs)   = nextWordLength xs-    nextWordLength (Softline : xs)    = nextWordLength xs-    nextWordLength (Hardline : _)     = Nothing-    nextWordLength (WrapAt {..} : xs) = nextWordLength (unDoc wrapDoc   ++ xs)-    nextWordLength (Ansi   {..} : xs) = nextWordLength (unDoc ansiDoc   ++ xs)-    nextWordLength (Indent {..} : xs) = nextWordLength (unDoc indentDoc ++ xs)-    nextWordLength (Control _ : _)    = Nothing+        | L.null x                     = nextWordLength xs+        | otherwise                    = Just (wcstrwidth x)+    nextWordLength (Hyperlink t _ : _) = Just (wcstrwidth t)+    nextWordLength (Softspace : xs)    = nextWordLength xs+    nextWordLength (Hardspace : xs)    = nextWordLength xs+    nextWordLength (Softline : xs)     = nextWordLength xs+    nextWordLength (Hardline : _)      = Nothing+    nextWordLength (WrapAt {..} : xs)  = nextWordLength (unDoc wrapDoc   ++ xs)+    nextWordLength (Ansi   {..} : xs)  = nextWordLength (unDoc ansiDoc   ++ xs)+    nextWordLength (Indent {..} : xs)  = nextWordLength (unDoc indentDoc ++ xs)+    nextWordLength (Control _ : _)     = Nothing   --------------------------------------------------------------------------------
lib/Patat/PrettyPrint/Matrix.hs view
@@ -46,6 +46,8 @@     go r y _ (NewlineChunk : cs)                     = go r (y + 1) 0 cs     go r y x (ControlChunk ClearScreenControl  : cs) = go r y x cs  -- ?     go r _ x (ControlChunk (GoToLineControl y) : cs) = go r y x cs+    go r y x (HyperlinkChunk _ codes str _ : cs)       =+        go r y x (StringChunk codes str : cs)  --  Links are erased     go r y x chunks@(StringChunk codes (z : zs) : cs)         | x + w > cols = go r (y + 1) 0 chunks         | otherwise    = do
patat.cabal view
@@ -1,5 +1,5 @@ Name:          patat-Version:       0.14.2.0+Version:       0.15.0.0 Synopsis:      Terminal-based presentations using Pandoc Description:   Terminal-based presentations using Pandoc. License:       GPL-2