Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
use flake
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
------

Expand Down
7 changes: 4 additions & 3 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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
];
};
};
Expand Down
36 changes: 20 additions & 16 deletions lib/Patat/Presentation/Display.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not use already existing themeLinkTarget? I see the text would need both styles themeLink and themeLinkTarget merged, but that might be complicated.

| otherwise = doc
21 changes: 11 additions & 10 deletions lib/Patat/Presentation/Display/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
}


Expand Down
27 changes: 23 additions & 4 deletions lib/Patat/Presentation/Settings.hs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ module Patat.Presentation.Settings

, TransitionSettings (..)

, LinkPlacement (..)
, LinkSettings (..)

, parseSlideSettings
Expand Down Expand Up @@ -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
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps fail if lsOSC == false && lsPlacement == "drop"?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good idea, I'll add a validation.

_ -> 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"


--------------------------------------------------------------------------------
Expand Down
5 changes: 4 additions & 1 deletion lib/Patat/Theme.hs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ data Theme = Theme
, themeCode :: !(Maybe Style)
, themeLinkText :: !(Maybe Style)
, themeLinkTarget :: !(Maybe Style)
, themeLinkOSC8 :: !(Maybe Style) -- Undocumented
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to use diffrent style than themeLinkTarget?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think of this as just extra formatting that gets applied if text gets linked using OSC8, I'm using it to always underline in that case.

, themeStrikeout :: !(Maybe Style)
, themeQuoted :: !(Maybe Style)
, themeMath :: !(Maybe Style)
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
36 changes: 36 additions & 0 deletions tests/golden/dump.in/links.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,39 @@ Some more links:
Some more advanced stuff:

[a **bold**, _italic_, `code` link](http://example.com#fmt)

---

<!--config:
links:
osc8: true
placement: drop
-->

With `placement: drop`:

1. An automatic one: <http://example.com#1>
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'

---

<!--config:
theme:
linkOSC8: []
links:
osc8: true
placement: drop
-->

For the weird usecase you would want to turn of underlining OSC8 links?

[not underlined](http://example.com#fmt)

---
50 changes: 36 additions & 14 deletions tests/golden/dump.out/links.md.dump
Original file line number Diff line number Diff line change
Expand Up @@ -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 
Loading