git.iko.soy/rowtype-yoga/psfp
on master help sign in
Highlighting works well enough
commita6f9596b603ef9a2aca40898ac82d8e2e0a7ef76 authorMark Eibes <mark.eibes@gmail.com> dateSun 12 Apr 2020, 21:45 (7 years ago) parent21527d8
14 files changed+487−87
components/src/React/SyntaxHighlighter/Component.js+136 components/src/React/SyntaxHighlighter/Component.purs+40 components/src/React/SyntaxHighlighter/Component.ts+149 components/src/Yoga/Button/Component.purs+5−9 components/src/Yoga/FillInTheGaps/Component.purs+12−8 components/src/Yoga/FillInTheGaps/Stories.purs+8−20 components/src/Yoga/Highlighter.purs−3 components/src/Yoga/Highlighter/Monaco.purs−24 components/src/Yoga/Highlighter/Types.purs−15 components/src/Yoga/Monaco/Editor.js+2 components/src/Yoga/Monaco/Editor.ts+2−2 components/src/Yoga/Theme.purs+5−5 components/src/Yoga/Theme/Default.purs+1−1 components/src/Yoga/Theme/Syntax.purs+127
components/src/React/SyntaxHighlighter/Component.jsnew file+136
@@ -0,0 +1,136 @@
1+"use strict";
2+Object.defineProperty(exports, "__esModule", { value: true });
3+var react_syntax_highlighter_1 = require("react-syntax-highlighter");
4+var purescript = function (hljs) {
5+ var COMMENT = {
6+ variants: [
7+ hljs.COMMENT("--", "$"),
8+ hljs.COMMENT("{-", "-}", {
9+ contains: ["self"],
10+ }),
11+ ],
12+ };
13+ var KEY = {
14+ className: "attribute",
15+ begin: '"?\\w+"?',
16+ relevance: 0,
17+ };
18+ var CONSTRUCTOR = {
19+ className: "type",
20+ begin: "\\b[A-Z][\\w']*",
21+ relevance: 0,
22+ };
23+ var LIST = {
24+ begin: "\\(",
25+ end: "\\)",
26+ illegal: '"',
27+ contains: [
28+ { className: "type", begin: "\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?" },
29+ hljs.inherit(hljs.TITLE_MODE, { begin: "[_a-z][\\w']*" }),
30+ COMMENT,
31+ ],
32+ };
33+ var RECORD = {
34+ begin: "{",
35+ end: "}",
36+ contains: LIST.contains,
37+ };
38+ return {
39+ name: "PureScript",
40+ aliases: ["purs", "purescript"],
41+ keywords: {
42+ keyword: "case " +
43+ "class " +
44+ "data " +
45+ "derive " +
46+ "ado " +
47+ "do " +
48+ "else " +
49+ "if " +
50+ "import " +
51+ "in " +
52+ "infix " +
53+ "infixl " +
54+ "infixr " +
55+ "instance " +
56+ "let " +
57+ "module " +
58+ "newtype " +
59+ "of " +
60+ "then " +
61+ "type " +
62+ "where " +
63+ ": " +
64+ "foreign " +
65+ "forall " +
66+ "∀",
67+ },
68+ contains: [
69+ // Top-level constructions.
70+ {
71+ beginKeywords: "module",
72+ end: "where",
73+ keywords: "module where",
74+ contains: [LIST, COMMENT],
75+ illegal: "\\W\\.|;",
76+ },
77+ {
78+ begin: "\\bimport\\b",
79+ end: "$",
80+ keywords: "import as hiding",
81+ contains: [LIST, COMMENT],
82+ illegal: "\\W\\.|;",
83+ },
84+ {
85+ className: "class",
86+ begin: "^(\\s*)?(class|instance)\\b",
87+ end: "where",
88+ keywords: "class instance where",
89+ contains: [CONSTRUCTOR, LIST, COMMENT],
90+ },
91+ {
92+ className: "class",
93+ begin: "\\b(data|(new)?type)\\b",
94+ end: "$",
95+ keywords: "data family type newtype derive",
96+ contains: [CONSTRUCTOR, LIST, RECORD, COMMENT],
97+ },
98+ {
99+ className: "symbol",
100+ begin: "<-|->|\\:\\:|\\\\|=>|<=|forall|∀|\\:|∷",
101+ },
102+ // {
103+ // begin: "[{,]\\s*",
104+ // end: "\\s*(?::{2}|∷)",
105+ // contains: [KEY],
106+ // },
107+ {
108+ beginKeywords: "default",
109+ end: "$",
110+ contains: [CONSTRUCTOR, LIST, COMMENT],
111+ },
112+ {
113+ beginKeywords: "infix infixl infixr",
114+ end: "$",
115+ contains: [hljs.C_NUMBER_MODE, COMMENT],
116+ },
117+ {
118+ begin: "\\bforeign\\b",
119+ end: "$",
120+ keywords: "foreign import",
121+ contains: [CONSTRUCTOR, hljs.QUOTE_STRING_MODE, COMMENT],
122+ },
123+ // "Whitespaces".
124+ // Literals and names.
125+ // TODO: characters.
126+ hljs.QUOTE_STRING_MODE,
127+ hljs.C_NUMBER_MODE,
128+ CONSTRUCTOR,
129+ hljs.inherit(hljs.TITLE_MODE, { begin: "^[_a-z][\\w']*" }),
130+ COMMENT,
131+ { begin: "->|<-" },
132+ ],
133+ };
134+};
135+react_syntax_highlighter_1.Light.registerLanguage("puresscript", purescript);
136+exports.syntaxHighlighterImpl = react_syntax_highlighter_1.Light;
components/src/React/SyntaxHighlighter/Component.pursnew file+40
@@ -0,0 +1,40 @@
1+module React.Basic.SyntaxHighlighter.Component where
2+
3+import React.Basic (ReactComponent)
4+import React.Basic.DOM (CSS)
5+
6+type HighlighterTheme
7+ = { hljs ∷ CSS
8+ , "hljs-addition" ∷ CSS
9+ , "hljs-attribute" ∷ CSS
10+ , "hljs-built_in" ∷ CSS
11+ , "hljs-bullet" ∷ CSS
12+ , "hljs-comment" ∷ CSS
13+ , "hljs-deletion" ∷ CSS
14+ , "hljs-doctag" ∷ CSS
15+ , "hljs-emphasis" ∷ CSS
16+ , "hljs-keyword" ∷ CSS
17+ , "hljs-link" ∷ CSS
18+ , "hljs-literal" ∷ CSS
19+ , "hljs-meta" ∷ CSS
20+ , "hljs-name" ∷ CSS
21+ , "hljs-quote" ∷ CSS
22+ , "hljs-section" ∷ CSS
23+ , "hljs-selector-tag" ∷ CSS
24+ , "hljs-string" ∷ CSS
25+ , "hljs-strong" ∷ CSS
26+ , "hljs-subst" ∷ CSS
27+ , "hljs-symbol" ∷ CSS
28+ , "hljs-template-tag" ∷ CSS
29+ , "hljs-template-variable" ∷ CSS
30+ , "hljs-title" ∷ CSS
31+ , "hljs-type" ∷ CSS
32+ , "hljs-variable" ∷ CSS
33+ }
34+
35+foreign import syntaxHighlighterImpl ∷
36+ ReactComponent
37+ { language ∷ String
38+ , style ∷ HighlighterTheme
39+ , children ∷ String
40+ }
components/src/React/SyntaxHighlighter/Component.tsnew file+149
@@ -0,0 +1,149 @@
1+import { Light as SyntaxHighlighter } from "react-syntax-highlighter";
2+
3+const purescript = (hljs) => {
4+ var COMMENT = {
5+ variants: [
6+ hljs.COMMENT("--", "$"),
7+ hljs.COMMENT("{-", "-}", {
8+ contains: ["self"],
9+ }),
10+ ],
11+ };
12+
13+ var KEY = {
14+ className: "attribute",
15+ begin: '"?\\w+"?',
16+ relevance: 0,
17+ };
18+
19+ var CONSTRUCTOR = {
20+ className: "type",
21+ begin: "\\b[A-Z][\\w']*", // TODO: other constructors (build-in, infix).
22+ relevance: 0,
23+ };
24+
25+ var LIST = {
26+ begin: "\\(",
27+ end: "\\)",
28+ illegal: '"',
29+ contains: [
30+ { className: "type", begin: "\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?" },
31+ hljs.inherit(hljs.TITLE_MODE, { begin: "[_a-z][\\w']*" }),
32+ COMMENT,
33+ ],
34+ };
35+
36+ var RECORD = {
37+ begin: "{",
38+ end: "}",
39+ contains: LIST.contains,
40+ };
41+
42+ return {
43+ name: "PureScript",
44+ aliases: ["purs", "purescript"],
45+ keywords: {
46+ keyword:
47+ "case " +
48+ "class " +
49+ "data " +
50+ "derive " +
51+ "ado " +
52+ "do " +
53+ "else " +
54+ "if " +
55+ "import " +
56+ "in " +
57+ "infix " +
58+ "infixl " +
59+ "infixr " +
60+ "instance " +
61+ "let " +
62+ "module " +
63+ "newtype " +
64+ "of " +
65+ "then " +
66+ "type " +
67+ "where " +
68+ ": " +
69+ "foreign " +
70+ "forall " +
71+ "∀",
72+ },
73+ contains: [
74+ // Top-level constructions.
75+
76+ {
77+ beginKeywords: "module",
78+ end: "where",
79+ keywords: "module where",
80+ contains: [LIST, COMMENT],
81+ illegal: "\\W\\.|;",
82+ },
83+ {
84+ begin: "\\bimport\\b",
85+ end: "$",
86+ keywords: "import as hiding",
87+ contains: [LIST, COMMENT],
88+ illegal: "\\W\\.|;",
89+ },
90+
91+ {
92+ className: "class",
93+ begin: "^(\\s*)?(class|instance)\\b",
94+ end: "where",
95+ keywords: "class instance where",
96+ contains: [CONSTRUCTOR, LIST, COMMENT],
97+ },
98+ {
99+ className: "class",
100+ begin: "\\b(data|(new)?type)\\b",
101+ end: "$",
102+ keywords: "data family type newtype derive",
103+ contains: [CONSTRUCTOR, LIST, RECORD, COMMENT],
104+ },
105+ {
106+ className: "symbol",
107+ begin: "<-|->|\\:\\:|\\\\|=>|<=|forall|∀|\\:|∷",
108+ },
109+ // {
110+ // begin: "[{,]\\s*",
111+ // end: "\\s*(?::{2}|∷)",
112+ // contains: [KEY],
113+ // },
114+ {
115+ beginKeywords: "default",
116+ end: "$",
117+ contains: [CONSTRUCTOR, LIST, COMMENT],
118+ },
119+ {
120+ beginKeywords: "infix infixl infixr",
121+ end: "$",
122+ contains: [hljs.C_NUMBER_MODE, COMMENT],
123+ },
124+ {
125+ begin: "\\bforeign\\b",
126+ end: "$",
127+ keywords: "foreign import",
128+ contains: [CONSTRUCTOR, hljs.QUOTE_STRING_MODE, COMMENT],
129+ },
130+
131+ // "Whitespaces".
132+
133+ // Literals and names.
134+
135+ // TODO: characters.
136+ hljs.QUOTE_STRING_MODE,
137+ hljs.C_NUMBER_MODE,
138+ CONSTRUCTOR,
139+ hljs.inherit(hljs.TITLE_MODE, { begin: "^[_a-z][\\w']*" }),
140+
141+ COMMENT,
142+
143+ { begin: "->|<-" }, // No markup, relevance booster
144+ ],
145+ };
146+};
147+
148+SyntaxHighlighter.registerLanguage("puresscript", purescript);
149+exports.syntaxHighlighterImpl = SyntaxHighlighter;
components/src/Yoga/Button/Component.purs+5−9
@@ -1,17 +1,13 @@
11module Yoga.Button.Component where
22
33import Prelude
4−import CSS (Color, ColorSpace(..), angular, black, cssStringRGBA, deg, desaturate, pct, saturate)
5−import CSS as C
4+import CSS (Color, ColorSpace(..), cssStringRGBA)
65import CSS as Color
7−import Color (mixCubehelix)
8−import Color.Scheme.Clrs (blue)
96import Data.Array.NonEmpty as NEA
107import Data.Foldable (intercalate)
118import Data.Interpolate (i)
129import Data.Maybe (Maybe)
1310import Data.Monoid (guard)
14−import Data.Tuple.Nested ((/\))
1511import Effect (Effect)
1612import JSS (JSSClasses, JSSElem, jssClasses)
1713import React.Basic (JSX)
@@ -110,16 +106,16 @@ styles =
110106 , backgroundClip: "border-box"
111107 , background:
112108 linearGradient (if theme.isLight then "180deg" else "0deg")
113− [ more 0.02 $ Color.mix HSL theme.backgroundColour theme.highlightColourRotatedBackwards 0.05 # (flip (Color.mix HSL theme.highlightColourRotatedForwards) (if theme.isLight then 0.94 else 0.85))
114− , less 0.03 $ Color.mix HSL theme.backgroundColour theme.highlightColourRotatedForwards 0.05 # (flip (Color.mix HSL theme.highlightColourRotatedBackwards) (if theme.isLight then 0.84 else 0.70))
109+ [ (if theme.isLight then Color.rotateHue 290.0 <<< Color.desaturate 0.33 else darken 0.16) $ more 0.08 $ Color.mix HSL theme.backgroundColour theme.highlightColourRotatedBackwards 0.05 # (flip (Color.mix HSL theme.highlightColourRotatedForwards) (if theme.isLight then 0.94 else 0.85))
110+ , (if theme.isLight then Color.rotateHue 290.0 <<< Color.desaturate 0.33 else darken 0.16) $ less 0.05 $ Color.mix HSL theme.backgroundColour theme.highlightColourRotatedForwards 0.05 # (flip (Color.mix HSL theme.highlightColourRotatedBackwards) (if theme.isLight then 0.84 else 0.70))
115111 ]
116112 , display: "inline-block"
117113 }
118114 , btn:
119115 { background:
120116 linearGradient "127deg"
121− [ theme.highlightColourRotatedBackwards # Color.rotateHue (-10.0)
122− , theme.highlightColourRotatedForwards # Color.rotateHue (10.0)
117+ [ (if theme.isLight then darken 0.1 else identity) $ theme.highlightColourRotatedBackwards
118+ , (if theme.isLight then darken 0.1 else identity) $ darken 0.2 $ theme.highlightColourRotatedForwards
123119 ]
124120 , boxShadow:
125121 "0 var(--s-5) var(--s-2)" <> (Color.cssStringRGBA $ withAlpha 0.1 Color.black)
components/src/Yoga/FillInTheGaps/Component.purs+12−8
@@ -30,17 +30,18 @@ import React.Basic.Helpers (jsx)
3030import React.Basic.Hooks (component, useState)
3131import React.Basic.Hooks as React
3232import React.Basic.Hooks.Spring (useTransition)
33+import React.Basic.SyntaxHighlighter.Component (HighlighterTheme, syntaxHighlighterImpl)
3334import Shared.Models.Body (CompileResult, RunResult)
34−import Type.Row (type (+))
3535import Yoga.Button.Component (ButtonType(..), mkButton)
3636import Yoga.ClickAway.Component as ClickAway
3737import Yoga.CloseIcon.Component as CloseIcon
3838import Yoga.Cluster.Component as Cluster
3939import Yoga.Compiler.Types (Compiler)
4040import Yoga.Helpers ((?||))
41−import Yoga.Highlighter.Types (Highlighter)
4241import Yoga.InlineCode.Component as InlineCode
4342import Yoga.Modal.Component as Modal
43+import Yoga.Theme.Styles (useTheme)
44+import Yoga.Theme.Syntax (mkHighlighterTheme)
4445
4546data Segment
4647 = ExpectedResult String
@@ -82,14 +83,14 @@ visibleRange arr = { start, end }
8283 start = A.findIndex (_ == [ Start ]) arr ?|| 0
8384 end = A.findIndex (_ == [ End ]) arr ?|| A.length arr
8485
85−renderSegments ∷ ReactComponent InlineCode.Props -> ((Array (Array Segment) -> Array (Array Segment)) -> Effect Unit) -> Array (Array Segment) -> JSX
86−renderSegments ic update arrs = R.div_ (A.mapWithIndex renderLine arrs)
86+renderSegments ∷ HighlighterTheme -> ReactComponent InlineCode.Props -> ((Array (Array Segment) -> Array (Array Segment)) -> Effect Unit) -> Array (Array Segment) -> JSX
87+renderSegments highlighterTheme ic update arrs = R.div_ (A.mapWithIndex renderLine arrs)
8788 where
8889 { start, end } = visibleRange arrs
8990 renderLine i l = R.div_ (A.mapWithIndex (renderSegment i) l)
9091 renderSegment i j s =
9192 if between start end i then case s of
92− Filler s' -> R.code_ [ R.text s' ]
93+ Filler s' -> element syntaxHighlighterImpl { style: highlighterTheme, language: "purescript", children: s' }
9394 Hole width _ ->
9495 element ic
9596 $ justifill
@@ -135,10 +136,10 @@ toSegment = case _ of
135136 other -> Filler other
136137
137138type Ctx r
138− = (Compiler + Highlighter r)
139+ = (Compiler r)
139140
140141makeComponent ∷ { | Ctx () } -> Effect (ReactComponent { code ∷ String })
141−makeComponent { compileAndRun, highlight } = do
142+makeComponent { compileAndRun } = do
142143 ic <- InlineCode.makeComponent
143144 modal <- Modal.makeComponent
144145 closeIcon <- CloseIcon.makeComponent
@@ -152,6 +153,9 @@ makeComponent { compileAndRun, highlight } = do
152153 initialSegments = lines <#> \line -> rawSegments line <#> toSegment
153154 segments /\ modifySegments <- useState initialSegments
154155 result /\ modifyResult <- useState Nothing
156+ cssTheme <- useTheme
157+ let
158+ highlighterTheme = mkHighlighterTheme cssTheme
155159 modalTransitions <-
156160 useTransition [ result ] (Just show)
157161 $ css
@@ -184,7 +188,7 @@ makeComponent { compileAndRun, highlight } = do
184188 modifyResult (const (Just $ res)) # liftEffect
185189 pure
186190 $ fragment
187− $ [ renderSegments ic (modifySegments) segments
191+ $ [ renderSegments highlighterTheme ic (modifySegments) segments
188192 , jsx cluster {}
189193 [ R.div_
190194 [ jsx button
components/src/Yoga/FillInTheGaps/Stories.purs+8−20
@@ -2,29 +2,18 @@ module Yoga.FillInTheGaps.Stories where
22
33import Prelude hiding (add)
44import Data.Either (Either(..))
5−import Data.Foldable (foldMap)
65import Data.Maybe (Maybe(..))
76import Data.String as String
8−import Data.Tuple.Nested ((/\))
97import Effect (Effect)
10−import React.Basic.DOM (css)
11−import React.Basic.DOM as R
12−import React.Basic.Hooks (component, element, fragment, memo, useState)
13−import React.Basic.Hooks as React
148import Storybook.Decorator.FullScreen (fullScreenDecorator)
159import Storybook.React (Storybook, add, addDecorator, storiesOf)
16−import Yoga.Editor (mkEditor)
1710import Yoga.FillInTheGaps.Component as FillInTheGaps
18−import Yoga.Highlighter.Monaco (monacoHighlighter)
19−import Yoga.Highlighter.Types (HTMLString(..), Language(..))
2011
2112ctx ∷ { | FillInTheGaps.Ctx () }
2213ctx =
2314 { compileAndRun
24− , highlight
2515 }
2616 where
27− highlight c Purescript = pure (HTMLString c)
2817 compileAndRun = case _ of
2918 { code }
3019 | code == correctCode -> pure (Right { code: Nothing, stdout: "Hello World\n", stderr: "" })
@@ -37,10 +26,15 @@ stories = do
3726 add "The FillInTheGaps" (FillInTheGaps.makeComponent ctx)
3827 [ { code: codeWithHoles }
3928 ]
40− add "The FillInTheGaps with highlighted code" withHighlighting
41− [ { code: codeWithHoles }
42− ]
4329
30+codeWithHoles =
31+ """
32+--result Hello World
33+--start here
34+module Main where
35+import Batteries
36+
37+-- Some dumb comment
4438withHighlighting = do
4539 editorComponent <- memo mkEditor
4640 component "WithHighlighting" \(props ∷ { code ∷ String }) -> React.do
@@ -67,14 +61,8 @@ withHighlighting = do
6761 element g { code: codeWithHoles }
6862 ]
6963
70−codeWithHoles =
71− """
72−--result Hello World
73−module Main where
74−import Batteries
7564
7665main :: Effect Unit
77−--start here
7866main = log
7967 "{-Hello World-}"
8068--end here
components/src/Yoga/Highlighter.pursdeleted−3
@@ -1,3 +0,0 @@
1−module Yoga.Highlighter where
2−
3−import Yoga.Highlighter.Types (Highlighter)
components/src/Yoga/Highlighter/Monaco.pursdeleted−24
@@ -1,24 +0,0 @@
1−module Yoga.Highlighter.Monaco where
2−
3−import Prelude
4−import Control.Promise as Promise
5−import Effect.Aff (Aff)
6−import Yoga.Editor (Editor, colorizeImpl)
7−import Yoga.Highlighter.Types (HTMLString(..), Highlighter, Language(..))
8−
9−monacoHighlighter ∷ Editor -> { | Highlighter () }
10−monacoHighlighter editor =
11− { highlight
12− }
13− where
14− langToString ∷ Language -> String
15− langToString Purescript = "purescript"
16− highlight ∷ String -> Language -> Aff HTMLString
17− highlight code lang =
18− HTMLString
19− <$> Promise.toAff
20− ( colorizeImpl code
21− (langToString lang)
22− { tabSize: 2 }
23− editor
24− )
components/src/Yoga/Highlighter/Types.pursdeleted−15
@@ -1,15 +0,0 @@
1−module Yoga.Highlighter.Types where
2−
3−import Effect.Aff (Aff)
4−
5−data Language
6− = Purescript
7−
8−newtype HTMLString
9− = HTMLString String
10−
11−type Highlighter r
12− = ( highlight ∷
13− String -> Language -> Aff HTMLString
14− | r
15− )
components/src/Yoga/Monaco/Editor.js+2
@@ -874,6 +874,7 @@ exports.purescriptSyntax = {
874874 "data",
875875 "derive",
876876 "do",
877+ "ado",
877878 "else",
878879 "if",
879880 "import",
@@ -899,6 +900,7 @@ exports.purescriptSyntax = {
899900 "foreign",
900901 "forall",
901902 "∷",
903+ "∀",
902904 ],
903905 extraKeywords: [],
904906 typeKeywords: [],
components/src/Yoga/Monaco/Editor.ts+2−2
@@ -1,7 +1,5 @@
11"use strict";
22
3−exports.newMonacoEditorImpl = require("monaco-editor/min/vs/editor");
4−
53exports.monacoEditorImpl = async () => {
64 const x = await import("react-monaco-editor");
75 return x.default;
@@ -845,6 +843,7 @@ exports.purescriptSyntax = {
845843 "data",
846844 "derive",
847845 "do",
846+ "ado",
848847 "else",
849848 "if",
850849 "import",
@@ -870,6 +869,7 @@ exports.purescriptSyntax = {
870869 "foreign",
871870 "forall",
872871 "∷",
872+ "∀",
873873 ],
874874
875875 extraKeywords: [],
components/src/Yoga/Theme.purs+5−5
@@ -10,15 +10,15 @@ import Data.Symbol (SProxy(..))
1010import Record.Builder as RB
1111import Yoga.Theme.Types (Theme, CSSTheme)
1212
13−increaseContrast ∷ Color -> Color -> Color
14−increaseContrast contrastWith = go 0
13+increaseContrastTo ∷ Number -> Color -> Color -> Color
14+increaseContrastTo target contrastWith = go 0
1515 where
16− modify = if isLight contrastWith then darken else lighten
16+ modify x = if isLight contrastWith then (darken x <<< desaturate (x * (-1.5))) else (lighten x <<< desaturate (x * 0.5))
1717 go i col =
18− if contrast contrastWith col >= 7.5 || i >= 20 then
18+ if contrast contrastWith col >= ((if isLight contrastWith then (target * 0.8) else target)) || i >= 100 then
1919 col
2020 else
21− go (i + 1) (modify 0.1 col)
21+ go (i + 1) (modify 0.005 col)
2222
2323withAlpha ∷ Number -> Color -> Color
2424withAlpha alpha c1 = Color.rgba' r g b alpha
components/src/Yoga/Theme/Default.purs+1−1
@@ -19,7 +19,7 @@ darkTheme =
1919 { backgroundColour: Color.hsl 238.0 0.12 0.20
2020 , textColour: Color.hsl 225.0 0.28 0.90
2121 , interfaceColour: Color.hsl 225.0 0.48 0.12
22− , highlightColour: Color.hsl 265.0 0.58 0.77
22+ , highlightColour: Color.hsl 285.0 0.88 0.72
2323 , altHighlightColour: Color.hsl 84.0 0.617 0.631
2424 , textFontFamily: cons' "Rubik" systemFontStack
2525 , headingFontFamily: cons' "Rubik" systemFontStack
components/src/Yoga/Theme/Syntax.pursnew file+127
@@ -0,0 +1,127 @@
1+module Yoga.Theme.Syntax where
2+
3+import Prelude
4+import Color as Color
5+import React.Basic.DOM (css)
6+import React.Basic.SyntaxHighlighter.Component (HighlighterTheme)
7+import Yoga.Theme (increaseContrastTo)
8+import Yoga.Theme.Types (CSSTheme)
9+
10+mkHighlighterTheme ∷ CSSTheme -> HighlighterTheme
11+mkHighlighterTheme theme =
12+ let
13+ contrasted = increaseContrastTo 6.0 theme.backgroundColour
14+ in
15+ { hljs:
16+ css
17+ { display: "inline"
18+ , overflowX: "auto"
19+ }
20+ , "hljs-keyword":
21+ css
22+ { color: Color.cssStringRGBA (contrasted (Color.rotateHue (-140.0) theme.highlightColour))
23+ , fontWeight: "normal"
24+ }
25+ , "hljs-symbol":
26+ css
27+ { color: Color.cssStringRGBA (contrasted (Color.rotateHue (-140.0) theme.highlightColour))
28+ }
29+ , "hljs-type":
30+ css
31+ { color: Color.cssStringRGBA (contrasted (Color.rotateHue (-80.0) theme.highlightColour))
32+ , fontWeight: "normal"
33+ }
34+ , "hljs-string":
35+ css
36+ { color: Color.cssStringRGBA (contrasted (Color.rotateHue (-20.0) theme.highlightColour))
37+ }
38+ , "hljs-title":
39+ css
40+ { color: Color.cssStringRGBA (contrasted (Color.rotateHue (-120.0) theme.highlightColour))
41+ , fontStyle: "normal"
42+ }
43+ , "hljs-selector-tag":
44+ css
45+ { color: "yellow"
46+ , fontWeight: "bold"
47+ }
48+ , "hljs-literal":
49+ css
50+ { color: "green"
51+ , fontWeight: "bold"
52+ }
53+ , "hljs-section":
54+ css
55+ { color: "darkslateblue"
56+ , fontWeight: "bold"
57+ }
58+ , "hljs-link":
59+ css
60+ { color: "yellow"
61+ }
62+ , "hljs-subst":
63+ css
64+ { color: "#ddd"
65+ }
66+ , "hljs-name":
67+ css
68+ { color: "#d88"
69+ , fontWeight: "bold"
70+ }
71+ , "hljs-attribute":
72+ css
73+ { color: "tomato"
74+ }
75+ , "hljs-bullet":
76+ css
77+ { color: "#d88"
78+ }
79+ , "hljs-built_in":
80+ css
81+ { color: "#d88"
82+ }
83+ , "hljs-addition":
84+ css
85+ { color: "#d88"
86+ }
87+ , "hljs-variable":
88+ css
89+ { color: "#d88"
90+ }
91+ , "hljs-template-tag":
92+ css
93+ { color: "#d88"
94+ }
95+ , "hljs-template-variable":
96+ css
97+ { color: "#d88"
98+ }
99+ , "hljs-comment":
100+ css
101+ { color: "#777"
102+ }
103+ , "hljs-quote":
104+ css
105+ { color: "#777"
106+ }
107+ , "hljs-deletion":
108+ css
109+ { color: "#777"
110+ }
111+ , "hljs-meta":
112+ css
113+ { color: "#777"
114+ }
115+ , "hljs-doctag":
116+ css
117+ { fontWeight: "bold"
118+ }
119+ , "hljs-strong":
120+ css
121+ { fontWeight: "bold"
122+ }
123+ , "hljs-emphasis":
124+ css
125+ { fontStyle: "italic"
126+ }
127+ }