1module MDXProvider where
4import Data.Array (intercalate)
5import Data.Array as Array
6import Data.Either (Either(..))
7import Data.Function.Uncurried (mkFn2)
8import Data.Maybe (Maybe(..), fromMaybe, isJust)
9import Data.Nullable (Nullable)
10import Data.Nullable as Nullable
11import Data.String as String
12import Data.Traversable (mapAccumL)
13import Data.Tuple.Nested ((/\))
15import Effect.Aff (launchAff_)
16import Effect.Class (liftEffect)
17import Effect.Class.Console (log)
18import Effect.Unsafe (unsafePerformEffect)
19import Framer.Motion as M
21import Milkis.Impl (FetchImpl)
22import React.Basic (JSX, ReactComponent)
23import React.Basic.DOM (Props_h1, Props_h2, Props_h3, Props_h4, Props_p, Props_a, unsafeCreateDOMComponent)
24import React.Basic.DOM as R
25import React.Basic.Emotion as E
26import React.Basic.Hooks (ReactChildren, element, memo, reactChildrenFromArray, reactChildrenToArray, reactComponent, reactComponentWithChildren, useState)
27import React.Basic.Hooks as React
28import Shared.Models.Body (CompileResult)
29import Typography.SmallCaps (mkSmallCaps)
30import Unsafe.Coerce (unsafeCoerce)
31import Yoga.CompileEditor.Component (mkCompileEditor)
32import Yoga.Compiler.Api (apiCompiler)
33import Yoga.Compiler.Types (Compiler)
34import Yoga.FillInTheGaps.Component as FillInTheGaps
35import Yoga.FillInTheGaps.Logic (Segment, findResult, parseSegments, toCode)
36import Yoga.Helpers ((?||))
44 { mdxType ∷ Nullable String
45 , children ∷ Nullable String
46 , className ∷ Nullable String
51isQuiz ∷ MDX -> Boolean
53 a.props.mdxType == "pre"
54 && ((unsafeCoerce a).props.children.props.className == "language-purescript")
55 && ((unsafeCoerce a).props.children.props.mdxType == "code")
56 && ((unsafeCoerce a).props.children.props.children # parseSegments # isJust)
58type MdxProviderProps =
59 { children ∷ ReactChildren MDX
62mkLiveMdxProviderComponent ∷ FetchImpl -> Effect (ReactComponent MdxProviderProps)
63mkLiveMdxProviderComponent fetchImpl = mkMdxProviderComponent (apiCompiler fetchImpl)
65mkMdxProviderComponent ∷
68 Effect (ReactComponent MdxProviderProps)
69mkMdxProviderComponent compiler = do
70 editor <- memo $ mkCompileEditor compiler
71 quiz <- memo $ mkQuiz compiler
72 smallCaps <- mkSmallCaps
73 reactComponentWithChildren "MDXProviderComponent" do
74 \{ children } -> React.do
75 visibleUntil /\ updateVisible <- useState 1
77 onFailure title kids = log "Oopsie daisy"
78 onSuccess = updateVisible (_ + one)
79 mapVisible ∷ Int -> MDX -> _
81 { accum: i + if isQuiz kid then one else zero
82 , value: if (i < visibleUntil) then Just kid else Nothing
84 visibleKids ∷ Array MDX
86 reactChildrenToArray children
87 # mapAccumL mapVisible zero
90 contentMDX ∷ ReactChildren MDX
91 contentMDX = reactChildrenFromArray visibleKids
92 paragraph parChildren =
96 { fontFamily: E.str "'Cormorant Garamond', Comic Sans MS, serif"
97 , fontSize: E.str "min(calc(var(--s-1) + 2.4vw), var(--s1))"
98 , fontWeight: E.str "400"
99 , lineHeight: E.var "--line-height-small"
100 , "MsHyphens": E.str "auto"
101 , "WebkitHyphens": E.str "auto"
102 , hyphens: E.str "auto"
103 , overflow: E.str "hidden"
104 , fontVariantLigatures: E.str "common-ligatures"
105 , textAlign: E.str "justify"
106 , fontFeatureSettings: E.str $ """ "kern" 1, "liga" 1, "dlig" 1, "hlig" 1, "swsh" 1, "calt" 1, "case" 1 """
110 { fontFamily: E.str "'Cormorant Garamond', Comic Sans MS, serif"
111 , fontWeight: E.str "400"
114 , className: "blog-p"
115 , children: parChildren
121 \(props ∷ { children ∷ String }) ->
122 smallCaps props.children
123 , hr: (const $ R.hr {})
125 \(props ∷ { children ∷ Array JSX }) ->
126 paragraph props.children
129 R.span { children: props.children }
131 mkFn2 \(props ∷ PreProps) other -> do
133 childrenQ = Nullable.toMaybe props.children
134 propsQ = (_.props >>> Nullable.toMaybe) =<< childrenQ
135 mdxTypeQ = (_.mdxType >>> Nullable.toMaybe) =<< propsQ
136 childrenQ2 = (_.children >>> Nullable.toMaybe) =<< propsQ
137 classNameQ = (_.className >>> Nullable.toMaybe) =<< propsQ
138 isCode = fromMaybe false (mdxTypeQ <#> eq "code")
141 (fromMaybe 200 >>> show >>> (_ <> "px")) do
144 ( String.split (String.Pattern "\n") code
146 # \x -> (x * 12) + 100
148 language = fromMaybe "" (classNameQ >>= String.stripPrefix (String.Pattern "language-"))
149 segmentsQ = parseSegments (codeQ ?|| "")
150 case isCode, language, segmentsQ of
151 true, "purescript", Just initialSegments -> element quiz { initialSegments, onFailure, onSuccess }
154 { initialCode: fromMaybe "" codeQ
158 false, _, _ -> element (unsafePerformEffect $ unsafeCreateDOMComponent "pre") props
161 $ element mdxProvider
162 { children: contentMDX
163 , components: mdxComponents
167 { initialSegments ∷ Array (Array Segment)
168 , onFailure ∷ String -> Array JSX -> Effect Unit
169 , onSuccess ∷ Effect Unit
172mkQuiz ∷ ∀ r. { | Compiler r } -> Effect (ReactComponent QuizProps)
174 fillInTheGaps <- FillInTheGaps.makeComponent
175 reactComponent "Quiz" \({ initialSegments, onFailure, onSuccess } ∷ QuizProps) -> React.do
176 segments /\ updateSegments <- useState initialSegments
177 solvedWith /\ updateSolvedWith <- useState Nothing
179 $ element fillInTheGaps
183 let code = toCode segments
184 result <- compiler.compileAndRun { code }
185 liftEffect case result of
187 | String.stripSuffix (String.Pattern "\n") r.stdout == (findResult $ join segments) -> do
188 updateSolvedWith (const $ String.stripSuffix (String.Pattern "\n") r.stdout)
191 | r.stdout /= "\n" -> onFailure "Oh shit!" [ R.text r.stdout ]
192 Right r -> onFailure "Oh shit!" [ R.text r.stderr ]
193 Left (cr ∷ CompileResult) -> onFailure "Oh shit!" [ R.text (intercalate ", " (cr.result <#> _.message)) ]
196 let updated = update segments
197 unless (segments == updated) do updateSegments (const updated)
201foreign import mdxProvider ∷
204 { components ∷ { | r }
205 , children ∷ ReactChildren MDX
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list