diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/README.md b/README.md index 205ecc2..a232a2d 100644 --- a/README.md +++ b/README.md @@ -937,7 +937,9 @@ all transition effects using their respective default settings. ### Links -Version 0.15.0.0 and later support [OSC8] for hyperlinks. This makes hyperlinks +#### OSC8 + +Version 0.15 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 @@ -952,6 +954,24 @@ patat: [OSC8]: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda [OSC8 adoption]: https://github.com/Alhadis/OSC8-Adoption +#### Placement + +Version 0.16 and later support link placement. + + - `reference` (default): show URLs reference-style at the bottom of each + slide. + - `drop`: Do not show the URLs at all (this only makes sense if [OSC8](#OSC8) + is turned on). + +For example: + +```yaml +patat: + links: + osc8: true + placement: drop +``` + Trivia ------ diff --git a/flake.nix b/flake.nix index feaf49f..0831a1d 100644 --- a/flake.nix +++ b/flake.nix @@ -18,12 +18,13 @@ devShells = { default = pkgs.mkShell { packages = [ + haskell.ghc + haskell.goldplate + haskell.stylish-haskell pkgs.cabal-install pkgs.entr pkgs.wezterm - haskell.goldplate - haskell.stylish-haskell - (haskell.ghc.withPackages (p: inputs.self.packages.${system}.default.buildInputs)) + pkgs.zlib ]; }; }; diff --git a/lib/Patat/Presentation/Display.hs b/lib/Patat/Presentation/Display.hs index a7be8e3..cdf9417 100644 --- a/lib/Patat/Presentation/Display.hs +++ b/lib/Patat/Presentation/Display.hs @@ -59,16 +59,17 @@ displayWithBorders (Size rows columns) pres@Presentation {..} f = borders (PP.space <> PP.string author <> middleSpaces <> PP.string active <> PP.space) <> PP.hardline where - -- Get terminal width/title - settings = activeSettings pres + settings@PresentationSettings {..} = activeSettings pres + (sidx, _) = pActiveFragment ds = DisplaySettings { dsSize = canvasSize , 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) + , dsWrap = fromMaybe NoWrap psWrap + , dsTabStop = maybe 4 A.unFlexibleNum psTabStop + , dsOSC8 = fromMaybe False (psLinks >>= lsOSC8) + , dsLinkPlacement = fromMaybe ReferenceLinkPlacement (psLinks >>= lsPlacement) + , dsTheme = fromMaybe Theme.defaultTheme psTheme , dsSyntaxMap = pSyntaxMap , dsResolve = \var -> fromMaybe [] $ HMS.lookup var pVars , dsRevealState = revealState @@ -87,9 +88,9 @@ displayWithBorders (Size rows columns) pres@Presentation {..} f = , s <- [" > ", PP.toString b] ] title - | not . fromMaybe True $ psBreadcrumbs settings = plainTitle - | wcstrwidth breadTitle > columns = plainTitle - | otherwise = breadTitle + | not . fromMaybe True $ psBreadcrumbs = plainTitle + | wcstrwidth breadTitle > columns = plainTitle + | otherwise = breadTitle -- Dimensions of title. titleWidth = wcstrwidth title @@ -101,8 +102,8 @@ displayWithBorders (Size rows columns) pres@Presentation {..} f = -- Compute footer. active - | fromMaybe True $ psSlideNumber settings = show (sidx + 1) ++ " / " ++ show (length pSlides) - | otherwise = "" + | fromMaybe True psSlideNumber = show (sidx + 1) ++ " / " ++ show (length pSlides) + | otherwise = "" activeWidth = wcstrwidth active author = PP.toString (prettyInlines ds pAuthor) authorWidth = wcstrwidth author @@ -187,6 +188,7 @@ prettyMargins :: DisplaySettings -> [Block] -> PP.Doc prettyMargins ds blocks = vertical $ map horizontal blocks ++ case prettyReferences ds blocks of + _ | DropLinkPlacement <- dsLinkPlacement ds -> [] [] -> [] refs -> let doc0 = PP.vcat refs @@ -497,10 +499,11 @@ prettyReferences ds = prettyReference :: Reference -> PP.Doc prettyReference (text, target, title) = "[" <> - themed ds themeLinkText - (prettyInlines ds $ newlineToSpace text) <> + (themed ds themeLinkText $ + hyperlink ds target $ Just $ + prettyInlines ds $ newlineToSpace text) <> "]: " <> - themed ds themeLinkTarget (PP.text target) <> + (themed ds themeLinkTarget $ hyperlink ds target Nothing) <> (if T.null title then mempty else PP.space <> PP.text title) @@ -524,8 +527,9 @@ 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) + | dsOSC8 ds = themed ds themeLinkOSC8 $ + 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 + | dsOSC8 ds = themed ds themeLinkOSC8 $ PP.hyperlink (T.unpack url) doc | otherwise = doc diff --git a/lib/Patat/Presentation/Display/Internal.hs b/lib/Patat/Presentation/Display/Internal.hs index 17c26f2..b958dfb 100644 --- a/lib/Patat/Presentation/Display/Internal.hs +++ b/lib/Patat/Presentation/Display/Internal.hs @@ -7,7 +7,7 @@ module Patat.Presentation.Display.Internal -------------------------------------------------------------------------------- import Patat.Presentation.Internal (Margins) -import Patat.Presentation.Settings (Wrap) +import Patat.Presentation.Settings (Wrap, LinkPlacement) import Patat.Presentation.Syntax (Block, RevealState, Var) import qualified Patat.PrettyPrint as PP import Patat.Size (Size) @@ -17,15 +17,16 @@ import qualified Skylighting as Skylighting -------------------------------------------------------------------------------- data DisplaySettings = DisplaySettings - { dsSize :: !Size - , dsWrap :: !Wrap - , dsTabStop :: !Int - , dsMargins :: !Margins - , dsOSC8 :: !Bool - , dsTheme :: !Theme.Theme - , dsSyntaxMap :: !Skylighting.SyntaxMap - , dsResolve :: !(Var -> [Block]) - , dsRevealState :: !RevealState + { dsSize :: !Size + , dsWrap :: !Wrap + , dsTabStop :: !Int + , dsMargins :: !Margins + , dsOSC8 :: !Bool + , dsLinkPlacement :: !LinkPlacement + , dsTheme :: !Theme.Theme + , dsSyntaxMap :: !Skylighting.SyntaxMap + , dsResolve :: !(Var -> [Block]) + , dsRevealState :: !RevealState } diff --git a/lib/Patat/Presentation/Settings.hs b/lib/Patat/Presentation/Settings.hs index 9189702..ef10113 100644 --- a/lib/Patat/Presentation/Settings.hs +++ b/lib/Patat/Presentation/Settings.hs @@ -25,6 +25,7 @@ module Patat.Presentation.Settings , TransitionSettings (..) + , LinkPlacement (..) , LinkSettings (..) , parseSlideSettings @@ -313,23 +314,41 @@ instance A.FromJSON TransitionSettings where TransitionSettings <$> o A..: "type" <*> pure o +-------------------------------------------------------------------------------- +data LinkPlacement + = ReferenceLinkPlacement + | DropLinkPlacement + deriving (Eq, Show) + + +-------------------------------------------------------------------------------- +instance A.FromJSON LinkPlacement where + parseJSON = A.withText "FromJSON LinkPlacement" $ \t -> case t of + "reference" -> pure ReferenceLinkPlacement + "drop" -> pure DropLinkPlacement + _ -> fail $ "unknown placement: " <> show t + + -------------------------------------------------------------------------------- data LinkSettings = LinkSettings - { lsOSC8 :: !(Maybe Bool) + { lsOSC8 :: !(Maybe Bool) + , lsPlacement :: !(Maybe LinkPlacement) } deriving (Eq, Show) -------------------------------------------------------------------------------- instance Semigroup LinkSettings where l <> r = LinkSettings - { lsOSC8 = on mplus lsOSC8 l r + { lsOSC8 = on mplus lsOSC8 l r + , lsPlacement = on mplus lsPlacement l r } -------------------------------------------------------------------------------- instance A.FromJSON LinkSettings where - parseJSON = A.withObject "FromJSON LinkSettings" $ \o -> - LinkSettings <$> o A..:? "osc8" + parseJSON = A.withObject "FromJSON LinkSettings" $ \o -> LinkSettings + <$> o A..:? "osc8" + <*> o A..:? "placement" -------------------------------------------------------------------------------- diff --git a/lib/Patat/Theme.hs b/lib/Patat/Theme.hs index abf1f4c..6045ea2 100644 --- a/lib/Patat/Theme.hs +++ b/lib/Patat/Theme.hs @@ -234,6 +234,7 @@ data Theme = Theme , themeCode :: !(Maybe Style) , themeLinkText :: !(Maybe Style) , themeLinkTarget :: !(Maybe Style) + , themeLinkOSC8 :: !(Maybe Style) -- Undocumented , themeStrikeout :: !(Maybe Style) , themeQuoted :: !(Maybe Style) , themeMath :: !(Maybe Style) @@ -265,6 +266,7 @@ instance Semigroup Theme where , themeCode = mplusOn themeCode , themeLinkText = mplusOn themeLinkText , themeLinkTarget = mplusOn themeLinkTarget + , themeLinkOSC8 = mplusOn themeLinkOSC8 , themeStrikeout = mplusOn themeStrikeout , themeQuoted = mplusOn themeQuoted , themeMath = mplusOn themeMath @@ -283,7 +285,7 @@ instance Monoid Theme where mempty = Theme Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing - Nothing Nothing Nothing Nothing Nothing Nothing Nothing + Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing -------------------------------------------------------------------------------- defaultTheme :: Theme @@ -310,6 +312,7 @@ defaultTheme = Theme , themeCode = dull Ansi.White `mappend` ondull Ansi.Black , themeLinkText = dull Ansi.Green , themeLinkTarget = dull Ansi.Cyan `mappend` underline + , themeLinkOSC8 = underline , themeStrikeout = ondull Ansi.Red , themeQuoted = dull Ansi.Green , themeMath = dull Ansi.Green diff --git a/tests/golden/dump.in/links.md b/tests/golden/dump.in/links.md index 2f37b41..8a2f6fe 100644 --- a/tests/golden/dump.in/links.md +++ b/tests/golden/dump.in/links.md @@ -36,3 +36,39 @@ Some more links: Some more advanced stuff: [a **bold**, _italic_, `code` link](http://example.com#fmt) + +--- + + + +With `placement: drop`: + +1. An automatic one: +2. An [inline one](http://example.com#2) +3. A [reference][ref] link +4. A [shortcut reference] link +5. A [titled] link + +[ref]: http://example.com#3 +[shortcut reference]: http://example.com#4 +[titled]: http://example.com#5 'The title' + +--- + + + +For the weird usecase you would want to turn of underlining OSC8 links? + +[not underlined](http://example.com#fmt) + +--- diff --git a/tests/golden/dump.out/links.md.dump b/tests/golden/dump.out/links.md.dump index bcb4c9d..51b939c 100644 --- a/tests/golden/dump.out/links.md.dump +++ b/tests/golden/dump.out/links.md.dump @@ -10,31 +10,53 @@ [inline link]: /url [one with a title]: http://fsf.org click here for a good time! [foo]: http://foo.com/ - 1 / 3  + 1 / 5  {slide}  links.md  Some more links: -1. An automatic one: <]8;id=0;http://example.com#1\http://example.com#1]8;;\> -2. An []8;id=1;http://example.com#2\inline one]8;;\] -3. A []8;id=2;http://example.com#3\reference]8;;\] link -4. A []8;id=3;http://example.com#4\shortcut reference]8;;\] link -5. A []8;id=4;http://example.com#5\titled]8;;\] link +1. An automatic one: <]8;id=0;http://example.com#1\http://example.com#1]8;;\> +2. An []8;id=1;http://example.com#2\inline one]8;;\] +3. A []8;id=2;http://example.com#3\reference]8;;\] link +4. A []8;id=3;http://example.com#4\shortcut reference]8;;\] link +5. A []8;id=4;http://example.com#5\titled]8;;\] link -[inline one]: http://example.com#2 -[reference]: http://example.com#3 -[shortcut reference]: http://example.com#4 -[titled]: http://example.com#5 The title - 2 / 3  +[]8;id=5;http://example.com#2\inline one]8;;\]: ]8;id=6;http://example.com#2\http://example.com#2]8;;\ +[]8;id=7;http://example.com#3\reference]8;;\]: ]8;id=8;http://example.com#3\http://example.com#3]8;;\ +[]8;id=9;http://example.com#4\shortcut reference]8;;\]: ]8;id=10;http://example.com#4\http://example.com#4]8;;\ +[]8;id=11;http://example.com#5\titled]8;;\]: ]8;id=12;http://example.com#5\http://example.com#5]8;;\ The title + 2 / 5  {slide}  links.md  Some more advanced stuff: -[]8;id=5;http://example.com#fmt\a ]8;;\]8;id=5;http://example.com#fmt\bold]8;;\]8;id=5;http://example.com#fmt\, ]8;;\]8;id=5;http://example.com#fmt\italic]8;;\]8;id=5;http://example.com#fmt\, ]8;;\]8;id=5;http://example.com#fmt\ code ]8;;\]8;id=5;http://example.com#fmt\ link]8;;\] +[]8;id=13;http://example.com#fmt\a ]8;;\]8;id=13;http://example.com#fmt\bold]8;;\]8;id=13;http://example.com#fmt\, ]8;;\]8;id=13;http://example.com#fmt\italic]8;;\]8;id=13;http://example.com#fmt\, ]8;;\]8;id=13;http://example.com#fmt\ code ]8;;\]8;id=13;http://example.com#fmt\ link]8;;\] -[a bold, italic,  code  link]: http://example.com#fmt - 3 / 3  +[]8;id=14;http://example.com#fmt\a ]8;;\]8;id=14;http://example.com#fmt\bold]8;;\]8;id=14;http://example.com#fmt\, ]8;;\]8;id=14;http://example.com#fmt\italic]8;;\]8;id=14;http://example.com#fmt\, ]8;;\]8;id=14;http://example.com#fmt\ code ]8;;\]8;id=14;http://example.com#fmt\ link]8;;\]: ]8;id=15;http://example.com#fmt\http://example.com#fmt]8;;\ + 3 / 5  + +{slide} + links.md  + +With  placement: drop : + +1. An automatic one: <]8;id=16;http://example.com#1\http://example.com#1]8;;\> +2. An []8;id=17;http://example.com#2\inline one]8;;\] +3. A []8;id=18;http://example.com#3\reference]8;;\] link +4. A []8;id=19;http://example.com#4\shortcut reference]8;;\] link +5. A []8;id=20;http://example.com#5\titled]8;;\] link + + 4 / 5  + +{slide} + links.md  + +For the weird usecase you would want to turn of underlining OSC8 links? + +[]8;id=21;http://example.com#fmt\not underlined]8;;\] + + 5 / 5