Refactor html
command with extra options (#1725)
This PR redefines the `html` command unifying our previous subcommands for the HTML backend. You should use the command in the following way to obtain the same results as before: - `juvix html src.juvix` -> `juvix html src.juvix --only-source` - `juvix dev doc src.juvix` -> `juvix html src.juvix` - Other fixes here include the flag `--non-recursive`, which replaces the previous behavior in that we now generate all the HTML recursively by default. - The flag `--no-print-metadata` is now called `--no-footer` - Also, another change introduced by this PR is asset handling; for example, with our canonical Juvix program, the new output is organized as follows. ``` juvix html HelloWorld.juvix --only-source && tree html/ Copying assets files to test/html/assets Writing HelloWorld.html html/ ├── assets │ ├── css │ │ ├── linuwial.css │ │ ├── source-ayu-light.css │ │ └── source-nord.css │ ├── images │ │ ├── tara-magicien.png │ │ ├── tara-seating.svg │ │ ├── tara-smiling.png │ │ ├── tara-smiling.svg │ │ ├── tara-teaching.png │ │ └── tara-teaching.svg │ └── js │ ├── highlight.js │ └── tex-chtml.js └── HelloWorld.html ├── Stdlib.Data.Bool.html ├── Stdlib.Data.List.html ├── Stdlib.Data.Maybe.html ├── Stdlib.Data.Nat.html ├── Stdlib.Data.Ord.html ├── Stdlib.Data.Product.html ├── Stdlib.Data.String.html ├── Stdlib.Function.html ├── Stdlib.Prelude.html └── Stdlib.System.IO.html ``` In addition, for the vscode-plugin, this PR adds two flags, `--prefix-assets` and `--prefix-url`, for which one provides input to help vscode find resource locations and Juvix files. PS. Make sure to run `make clean` the first time you run `make install` for the first time.
14
Makefile
@ -3,9 +3,8 @@ PREFIX="$(PWD)/.stack-work/prefix"
|
||||
UNAME := $(shell uname)
|
||||
HLINTQUIET :=
|
||||
|
||||
ASSETS = seating-mascot.051c86a.svg \
|
||||
Seating_Tara_smiling.svg \
|
||||
teaching-mascot.f828959.svg
|
||||
|
||||
IMAGES = $(shell find assets/images -type f)
|
||||
|
||||
ORGFILES = $(shell find docs/org -type f -name '*.org')
|
||||
MDFILES:=$(patsubst docs/org/%,docs/md/%,$(ORGFILES:.org=.md))
|
||||
@ -34,6 +33,9 @@ else
|
||||
THREADS := $(shell echo %NUMBER_OF_PROCESSORS%)
|
||||
endif
|
||||
|
||||
images:
|
||||
echo $(IMAGES)
|
||||
|
||||
all: install
|
||||
|
||||
clean: clean-runtime
|
||||
@ -97,8 +99,8 @@ markdown-files: docs/md/README.md docs/md/changelog.md $(MDFILES)
|
||||
.PHONY: markdown-docs
|
||||
markdown-docs: markdown-files
|
||||
@echo "copying assets ..."
|
||||
@mkdir -p docs/md/assets
|
||||
@cp -v $(addprefix assets/,$(ASSETS)) docs/md/assets
|
||||
@mkdir -p docs/md/assets/images
|
||||
@cp -v $(IMAGES) docs/md/assets/images/
|
||||
@mdbook build
|
||||
|
||||
.PHONY: serve-docs
|
||||
@ -191,7 +193,7 @@ fast-build: submodules runtime
|
||||
|
||||
.PHONY: runtime
|
||||
runtime:
|
||||
cd runtime && make -j 4
|
||||
cd runtime && make -j 4 -s
|
||||
|
||||
# -- Install
|
||||
|
||||
|
@ -26,7 +26,7 @@ alt="pages-build-deployment" /></a>
|
||||
|
||||
#+begin_html
|
||||
<a href="https://github.com/anoma/juvix">
|
||||
<img align="right" width="300" height="300" alt="Juvix Mascot" src="assets/seating-mascot.051c86a.svg" />
|
||||
<img align="right" width="300" height="300" alt="Juvix Mascot" src="assets/images/tara-seating.svg" />
|
||||
</a>
|
||||
#+end_html
|
||||
|
||||
|
@ -8,7 +8,6 @@ import Commands.Base
|
||||
import Commands.Dev.Asm qualified as Asm
|
||||
import Commands.Dev.Core qualified as Core
|
||||
import Commands.Dev.DisplayRoot qualified as DisplayRoot
|
||||
import Commands.Dev.Doc qualified as Doc
|
||||
import Commands.Dev.Highlight qualified as Highlight
|
||||
import Commands.Dev.Internal qualified as Internal
|
||||
import Commands.Dev.MiniC qualified as MiniC
|
||||
@ -23,7 +22,6 @@ runCommand = \case
|
||||
Highlight opts -> Highlight.runCommand opts
|
||||
Parse opts -> Parse.runCommand opts
|
||||
Scope opts -> Scope.runCommand opts
|
||||
Doc opts -> Doc.runCommand opts
|
||||
Internal opts -> Internal.runCommand opts
|
||||
MiniC opts -> MiniC.runCommand opts
|
||||
Termination opts -> Termination.runCommand opts
|
||||
|
@ -1,16 +0,0 @@
|
||||
module Commands.Dev.Doc where
|
||||
|
||||
import Commands.Base
|
||||
import Commands.Dev.Doc.Options
|
||||
import Juvix.Compiler.Backend.Html.Translation.FromTyped qualified as Doc
|
||||
import Juvix.Extra.Process
|
||||
import System.Process qualified as Process
|
||||
|
||||
runCommand :: Members '[Embed IO, App] r => DocOptions -> Sem r ()
|
||||
runCommand DocOptions {..} = do
|
||||
ctx <- runPipeline _docInputFile upToInternalTyped
|
||||
docDir <- someBaseToAbs' (_docOutputDir ^. pathPath)
|
||||
Doc.compile docDir "proj" ctx
|
||||
when _docOpen $ case openCmd of
|
||||
Nothing -> say "Could not recognize the 'open' command for your OS"
|
||||
Just opencmd -> embed (void (Process.spawnProcess opencmd [toFilePath (docDir <//> Doc.indexFileName)]))
|
@ -1,28 +0,0 @@
|
||||
module Commands.Dev.Doc.Options where
|
||||
|
||||
import CommonOptions
|
||||
|
||||
data DocOptions = DocOptions
|
||||
{ _docOutputDir :: AppPath Dir,
|
||||
_docOpen :: Bool,
|
||||
_docInputFile :: AppPath File
|
||||
}
|
||||
deriving stock (Data)
|
||||
|
||||
makeLenses ''DocOptions
|
||||
|
||||
parseDoc :: Parser DocOptions
|
||||
parseDoc = do
|
||||
_docOutputDir <-
|
||||
parseGenericOutputDir
|
||||
( value (Rel (relDir "doc"))
|
||||
<> showDefault
|
||||
<> help "html output directory"
|
||||
)
|
||||
_docOpen <-
|
||||
switch
|
||||
( long "open"
|
||||
<> help "open the documentation after generating it"
|
||||
)
|
||||
_docInputFile <- parseInputJuvixFile
|
||||
pure DocOptions {..}
|
@ -6,7 +6,6 @@ module Commands.Dev.Options
|
||||
module Commands.Dev.Parse.Options,
|
||||
module Commands.Dev.Highlight.Options,
|
||||
module Commands.Dev.Scope.Options,
|
||||
module Commands.Dev.Doc.Options,
|
||||
module Commands.Dev.Termination.Options,
|
||||
module Commands.Dev.DisplayRoot.Options,
|
||||
)
|
||||
@ -15,7 +14,6 @@ where
|
||||
import Commands.Dev.Asm.Options hiding (Compile)
|
||||
import Commands.Dev.Core.Options
|
||||
import Commands.Dev.DisplayRoot.Options
|
||||
import Commands.Dev.Doc.Options
|
||||
import Commands.Dev.Highlight.Options
|
||||
import Commands.Dev.Internal.Options
|
||||
import Commands.Dev.MiniC.Options
|
||||
@ -36,7 +34,6 @@ data DevCommand
|
||||
| Parse ParseOptions
|
||||
| Scope ScopeOptions
|
||||
| Termination TerminationCommand
|
||||
| Doc DocOptions
|
||||
deriving stock (Data)
|
||||
|
||||
parseDevCommand :: Parser DevCommand
|
||||
@ -50,20 +47,12 @@ parseDevCommand =
|
||||
commandRuntime,
|
||||
commandMiniC,
|
||||
commandParse,
|
||||
commandDoc,
|
||||
commandScope,
|
||||
commandShowRoot,
|
||||
commandTermination
|
||||
]
|
||||
)
|
||||
|
||||
commandDoc :: Mod CommandFields DevCommand
|
||||
commandDoc =
|
||||
command "doc" $
|
||||
info
|
||||
(Doc <$> parseDoc)
|
||||
(progDesc "Generate documentation")
|
||||
|
||||
commandHighlight :: Mod CommandFields DevCommand
|
||||
commandHighlight =
|
||||
command "highlight" $
|
||||
|
@ -2,13 +2,63 @@ module Commands.Html where
|
||||
|
||||
import Commands.Base
|
||||
import Commands.Html.Options
|
||||
import Juvix.Compiler.Backend.Html.Translation.FromTyped (JudocArgs (..))
|
||||
import Juvix.Compiler.Backend.Html.Translation.FromTyped qualified as Html
|
||||
import Juvix.Compiler.Backend.Html.Translation.FromTyped.Source
|
||||
( GenSourceHtmlArgs (..),
|
||||
)
|
||||
import Juvix.Compiler.Concrete.Pretty qualified as Concrete
|
||||
import Juvix.Compiler.Concrete.Translation.FromParsed.Analysis.Scoping qualified as Scoper
|
||||
import Juvix.Extra.Process
|
||||
import System.Process qualified as Process
|
||||
|
||||
runCommand :: Members '[Embed IO, App] r => HtmlOptions -> Sem r ()
|
||||
runCommand HtmlOptions {..} = do
|
||||
runGenOnlySourceHtml :: Members '[Embed IO, App] r => HtmlOptions -> Sem r ()
|
||||
runGenOnlySourceHtml HtmlOptions {..} = do
|
||||
res <- runPipeline _htmlInputFile upToScoping
|
||||
let m = head (res ^. Scoper.resultModules)
|
||||
outDir <- someBaseToAbs' (_htmlOutputDir ^. pathPath)
|
||||
embed (Html.genHtml Concrete.defaultOptions _htmlRecursive _htmlTheme outDir _htmlPrintMetadata m)
|
||||
outputDir <- someBaseToAbs' (_htmlOutputDir ^. pathPath)
|
||||
embed $
|
||||
Html.genSourceHtml
|
||||
GenSourceHtmlArgs
|
||||
{ _genSourceHtmlArgsAssetsDir = _htmlAssetsPrefix,
|
||||
_genSourceHtmlArgsHtmlKind = Html.HtmlSrc,
|
||||
_genSourceHtmlArgsParamBase = "",
|
||||
_genSourceHtmlArgsUrlPrefix = _htmlUrlPrefix,
|
||||
_genSourceHtmlArgsConcreteOpts = Concrete.defaultOptions,
|
||||
_genSourceHtmlArgsEntryPoint = m,
|
||||
_genSourceHtmlArgsOutputDir = outputDir,
|
||||
_genSourceHtmlArgsNoFooter = _htmlNoFooter,
|
||||
_genSourceHtmlArgsNonRecursive = _htmlNonRecursive,
|
||||
_genSourceHtmlArgsTheme = _htmlTheme
|
||||
}
|
||||
|
||||
runCommand :: Members '[Embed IO, App] r => HtmlOptions -> Sem r ()
|
||||
runCommand HtmlOptions {..}
|
||||
| _htmlOnlySource = runGenOnlySourceHtml HtmlOptions {..}
|
||||
| otherwise = do
|
||||
ctx <- runPipeline _htmlInputFile upToInternalTyped
|
||||
outputDir <- someBaseToAbs' (_htmlOutputDir ^. pathPath)
|
||||
Html.genJudocHtml
|
||||
JudocArgs
|
||||
{ _judocArgsAssetsPrefix = _htmlAssetsPrefix,
|
||||
_judocArgsBaseName = "proj",
|
||||
_judocArgsCtx = ctx,
|
||||
_judocArgsOutputDir = outputDir,
|
||||
_judocArgsUrlPrefix = _htmlUrlPrefix,
|
||||
_judocArgsTheme = _htmlTheme,
|
||||
_judocArgsNonRecursive = _htmlNonRecursive,
|
||||
_judocArgsNoFooter = _htmlNoFooter
|
||||
}
|
||||
when _htmlOpen $ case openCmd of
|
||||
Nothing -> say "Could not recognize the 'open' command for your OS"
|
||||
Just opencmd ->
|
||||
embed
|
||||
( void
|
||||
( Process.spawnProcess
|
||||
opencmd
|
||||
[ toFilePath
|
||||
( outputDir <//> Html.indexFileName
|
||||
)
|
||||
]
|
||||
)
|
||||
)
|
||||
|
@ -1,14 +1,18 @@
|
||||
module Commands.Html.Options where
|
||||
|
||||
import CommonOptions
|
||||
import Juvix.Compiler.Backend.Html.Data.Theme
|
||||
import Juvix.Compiler.Backend.Html.Data.Options hiding (HtmlOptions)
|
||||
|
||||
data HtmlOptions = HtmlOptions
|
||||
{ _htmlRecursive :: Bool,
|
||||
{ _htmlNonRecursive :: Bool,
|
||||
_htmlOnlySource :: Bool,
|
||||
_htmlTheme :: Theme,
|
||||
_htmlOutputDir :: AppPath Dir,
|
||||
_htmlInputFile :: AppPath File,
|
||||
_htmlPrintMetadata :: Bool
|
||||
_htmlNoFooter :: Bool,
|
||||
_htmlAssetsPrefix :: Text,
|
||||
_htmlUrlPrefix :: Text,
|
||||
_htmlOpen :: Bool
|
||||
}
|
||||
deriving stock (Data)
|
||||
|
||||
@ -16,10 +20,15 @@ makeLenses ''HtmlOptions
|
||||
|
||||
parseHtml :: Parser HtmlOptions
|
||||
parseHtml = do
|
||||
_htmlRecursive <-
|
||||
_htmlNonRecursive <-
|
||||
switch
|
||||
( long "recursive"
|
||||
<> help "export imported modules recursively"
|
||||
( long "non-recursive"
|
||||
<> help "Export imported modules recursively"
|
||||
)
|
||||
_htmlOnlySource <-
|
||||
switch
|
||||
( long "only-source"
|
||||
<> help "Generate only Html for the source code with syntax highlighting"
|
||||
)
|
||||
_htmlTheme <-
|
||||
option
|
||||
@ -28,26 +37,46 @@ parseHtml = do
|
||||
<> metavar "THEME"
|
||||
<> value Ayu
|
||||
<> showDefault
|
||||
<> help "selects a theme: ayu (light); nord (dark)"
|
||||
<> help "Theme for syntax highlighting. Options: ayu (light) and nord (dark)"
|
||||
<> completeWith (map show allThemes)
|
||||
)
|
||||
_htmlOutputDir <-
|
||||
parseGenericOutputDir
|
||||
( value (Rel $(mkRelDir "html"))
|
||||
<> showDefault
|
||||
<> help "html output directory"
|
||||
<> help "Html output directory"
|
||||
<> action "directory"
|
||||
)
|
||||
_htmlPrintMetadata <-
|
||||
_htmlNoFooter <-
|
||||
switch
|
||||
( long "print-metadata"
|
||||
<> help "Add HTML footer with metadata"
|
||||
( long "no-footer"
|
||||
<> help "Remove HTML Juvix footer"
|
||||
)
|
||||
_htmlAssetsPrefix <-
|
||||
strOption
|
||||
( value ""
|
||||
<> long "prefix-assets"
|
||||
<> showDefault
|
||||
<> help "Prefix used for assets's source path"
|
||||
)
|
||||
_htmlUrlPrefix <-
|
||||
strOption
|
||||
( value ""
|
||||
<> long "prefix-url"
|
||||
<> showDefault
|
||||
<> help "Prefix used for inner Juvix hyperlinks"
|
||||
)
|
||||
_htmlOpen <-
|
||||
switch
|
||||
( long "open"
|
||||
<> help "Open the documentation after generating it"
|
||||
)
|
||||
_htmlInputFile <- parseInputJuvixFile
|
||||
pure HtmlOptions {..}
|
||||
where
|
||||
allThemes :: [Theme]
|
||||
allThemes = allElements
|
||||
|
||||
parseTheme :: String -> Either String Theme
|
||||
parseTheme s = case map toLower s of
|
||||
"nord" -> Right Nord
|
||||
|
@ -1,5 +1,3 @@
|
||||
@import "extra.css";
|
||||
|
||||
/* @group Fundamentals */
|
||||
|
||||
* { margin: 0; padding: 0 }
|
BIN
assets/images/tara-magicien.png
Normal file
After Width: | Height: | Size: 147 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
BIN
assets/images/tara-smiling.png
Normal file
After Width: | Height: | Size: 71 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
BIN
assets/images/tara-teaching.png
Normal file
After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
1
assets/js/tex-chtml.js
Normal file
@ -2,7 +2,7 @@
|
||||
|
||||
#+begin_html
|
||||
<a href="https://github.com/anoma/juvix">
|
||||
<img align="right" width="300" height="300" alt="Juvix Mascot" src="../assets/Seating_Tara_smiling.svg" />
|
||||
<img align="right" width="300" height="300" alt="Juvix Mascot" src="../assets/images/tara-smiling.svg" />
|
||||
</a>
|
||||
#+end_html
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
#+begin_html
|
||||
<a href="https://github.com/anoma/juvix">
|
||||
<img align="left" width="200" height="200" alt="Juvix Mascot" src="../assets/teaching-mascot.f828959.svg" />
|
||||
<img align="left" width="200" height="200" alt="Juvix Mascot" src="../assets/images/tara-teaching.svg" />
|
||||
</a>
|
||||
#+end_html
|
||||
|
||||
|
@ -14,7 +14,10 @@ github: anoma/juvix
|
||||
|
||||
extra-source-files:
|
||||
- README.org
|
||||
- assets/*
|
||||
- assets/css/*.css
|
||||
- assets/js/*.js
|
||||
- assets/images/*.svg
|
||||
- assets/images/*.png
|
||||
- juvix-stdlib/juvix.yaml
|
||||
- juvix-stdlib/**/*.juvix
|
||||
- runtime/include/**/*.h
|
||||
|
@ -1,3 +1,3 @@
|
||||
module Juvix.Compiler.Backend.Html.Data (module Juvix.Compiler.Backend.Html.Data.Theme) where
|
||||
module Juvix.Compiler.Backend.Html.Data (module Juvix.Compiler.Backend.Html.Data.Options) where
|
||||
|
||||
import Juvix.Compiler.Backend.Html.Data.Theme
|
||||
import Juvix.Compiler.Backend.Html.Data.Options
|
||||
|
26
src/Juvix/Compiler/Backend/Html/Data/Options.hs
Normal file
@ -0,0 +1,26 @@
|
||||
module Juvix.Compiler.Backend.Html.Data.Options where
|
||||
|
||||
import Juvix.Prelude
|
||||
|
||||
data HtmlOptions = HtmlOptions
|
||||
{ _htmlOptionsKind :: HtmlKind,
|
||||
_htmlOptionsAssetsPrefix :: Text,
|
||||
_htmlOptionsUrlPrefix :: Text,
|
||||
_htmlOptionsOutputDir :: Path Abs Dir,
|
||||
_htmlOptionsParamBase :: Text,
|
||||
_htmlOptionsTheme :: Theme,
|
||||
_htmlOptionsNoFooter :: Bool
|
||||
}
|
||||
|
||||
data Theme
|
||||
= Nord
|
||||
| Ayu
|
||||
deriving stock (Show, Enum, Bounded, Data)
|
||||
|
||||
data HtmlKind
|
||||
= HtmlDoc
|
||||
| HtmlSrc
|
||||
| HtmlOnly
|
||||
deriving stock (Data)
|
||||
|
||||
makeLenses ''HtmlOptions
|
@ -1,14 +0,0 @@
|
||||
module Juvix.Compiler.Backend.Html.Data.Theme where
|
||||
|
||||
import Juvix.Prelude
|
||||
|
||||
data Theme
|
||||
= Nord
|
||||
| Ayu
|
||||
deriving stock (Show, Enum, Bounded, Data)
|
||||
|
||||
data HtmlKind
|
||||
= HtmlDoc
|
||||
| HtmlSrc
|
||||
| HtmlOnly
|
||||
deriving stock (Data)
|
@ -1,26 +1,27 @@
|
||||
module Juvix.Compiler.Backend.Html.Extra where
|
||||
|
||||
import Juvix.Compiler.Backend.Html.Data.Options
|
||||
import Juvix.Extra.Strings qualified as Str
|
||||
import Juvix.Extra.Version
|
||||
import Juvix.Prelude
|
||||
import Text.Blaze.Html5 as Html hiding (map)
|
||||
import Text.Blaze.Html5.Attributes qualified as Attr
|
||||
|
||||
mathJaxCdn :: Html
|
||||
mathJaxCdn = script1 <> script2
|
||||
where
|
||||
script1 =
|
||||
script
|
||||
! Attr.src src1
|
||||
$ mempty
|
||||
script2 =
|
||||
script
|
||||
! Attr.type_ "text/javascript"
|
||||
! Attr.id "MathJax-script"
|
||||
! Attr.src src2
|
||||
$ mempty
|
||||
src1 :: AttributeValue
|
||||
src1 = "https://polyfill.io/v3/polyfill.min.js?features=es6"
|
||||
src2 :: AttributeValue
|
||||
src2 = "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"
|
||||
mathJaxCdn :: Members '[Reader HtmlOptions] r => Sem r Html
|
||||
mathJaxCdn = do
|
||||
assetsPrefix <- textValue <$> asks (^. htmlOptionsAssetsPrefix)
|
||||
let script1 =
|
||||
script
|
||||
! Attr.src "https://polyfill.io/v3/polyfill.min.js?features=es6"
|
||||
$ mempty
|
||||
|
||||
script2 =
|
||||
script
|
||||
! Attr.type_ "text/javascript"
|
||||
! Attr.id "MathJax-script"
|
||||
! Attr.src (assetsPrefix <> "assets/js/tex-chtml.js")
|
||||
$ mempty
|
||||
return $ script1 <> script2
|
||||
|
||||
-- | This is useful fore debugging only. Note that it only works on a server
|
||||
-- protocol, opening the file from the local system won't work. For that, one
|
||||
@ -32,40 +33,88 @@ livejs =
|
||||
! Attr.src "https://livejs.com/live.js"
|
||||
$ mempty
|
||||
|
||||
linuwialCss :: Html
|
||||
linuwialCss =
|
||||
link
|
||||
! Attr.href "assets/linuwial.css"
|
||||
! Attr.rel "stylesheet"
|
||||
! Attr.type_ "text/css"
|
||||
! Attr.title "Linuwial"
|
||||
cssLink :: Members '[Reader HtmlOptions] r => AttributeValue -> Sem r Html
|
||||
cssLink css = do
|
||||
assetsPrefix <- textValue <$> asks (^. htmlOptionsAssetsPrefix)
|
||||
return $
|
||||
link
|
||||
! Attr.href (assetsPrefix <> "assets/css/" <> css)
|
||||
! Attr.rel "stylesheet"
|
||||
! Attr.type_ "text/css"
|
||||
|
||||
sourceCss :: Html
|
||||
sourceCss =
|
||||
link
|
||||
! Attr.href "assets/source.css"
|
||||
! Attr.rel "stylesheet"
|
||||
! Attr.type_ "text/css"
|
||||
|
||||
cssLink :: AttributeValue -> Html
|
||||
cssLink css =
|
||||
link
|
||||
! Attr.href css
|
||||
! Attr.rel "stylesheet"
|
||||
! Attr.type_ "text/css"
|
||||
|
||||
ayuCss :: Html
|
||||
ayuCss = cssLink "assets/source-ayu-light.css"
|
||||
|
||||
nordCss :: Html
|
||||
nordCss = cssLink "assets/source-nord.css"
|
||||
|
||||
highlightJs :: Html
|
||||
highlightJs =
|
||||
script
|
||||
! Attr.src "assets/highlight.js"
|
||||
! Attr.type_ "text/javascript"
|
||||
jsLink :: Members '[Reader HtmlOptions] r => AttributeValue -> Sem r Html
|
||||
jsLink js = do
|
||||
assetsPrefix <- textValue <$> asks (^. htmlOptionsAssetsPrefix)
|
||||
return
|
||||
$ script
|
||||
! Attr.src (assetsPrefix <> "assets/js/" <> js)
|
||||
! Attr.type_ "text/javascript"
|
||||
$ mempty
|
||||
|
||||
linuwialCss :: Members '[Reader HtmlOptions] r => Sem r Html
|
||||
linuwialCss = cssLink "linuwial.css"
|
||||
|
||||
ayuCss :: Members '[Reader HtmlOptions] r => Sem r Html
|
||||
ayuCss = cssLink "source-ayu-light.css"
|
||||
|
||||
nordCss :: Members '[Reader HtmlOptions] r => Sem r Html
|
||||
nordCss = cssLink "source-nord.css"
|
||||
|
||||
themeCss :: Members '[Reader HtmlOptions] r => Sem r Html
|
||||
themeCss = do
|
||||
theme <- asks (^. htmlOptionsTheme)
|
||||
case theme of
|
||||
Ayu -> ayuCss
|
||||
Nord -> nordCss
|
||||
|
||||
highlightJs :: Members '[Reader HtmlOptions] r => Sem r Html
|
||||
highlightJs = jsLink "highlight.js"
|
||||
|
||||
metaUtf8 :: Html
|
||||
metaUtf8 = meta ! Attr.charset "UTF-8"
|
||||
|
||||
taraSmiling :: Members '[Reader HtmlOptions] r => Sem r Html
|
||||
taraSmiling = do
|
||||
assetsPrefix <- textValue <$> asks (^. htmlOptionsAssetsPrefix)
|
||||
return $
|
||||
Html.a ! Attr.href Str.juvixDotOrg $
|
||||
Html.img
|
||||
! Attr.id "tara"
|
||||
! Attr.src (assetsPrefix <> "assets/images/tara-smiling.svg")
|
||||
! Attr.alt "Tara"
|
||||
|
||||
htmlJuvixFooter ::
|
||||
Members '[Reader HtmlOptions] r =>
|
||||
Sem r Html
|
||||
htmlJuvixFooter = do
|
||||
noFooter <- asks (^. htmlOptionsNoFooter)
|
||||
htmlKind <- asks (^. htmlOptionsKind)
|
||||
tara <- taraSmiling
|
||||
if
|
||||
| noFooter -> return mempty
|
||||
| otherwise -> do
|
||||
let juvixLinkOrg :: Html
|
||||
juvixLinkOrg =
|
||||
a ! Attr.href Str.juvixDotOrg $
|
||||
toHtml ("Juvix " :: Text)
|
||||
|
||||
commitInfo :: Html
|
||||
commitInfo =
|
||||
a
|
||||
! Attr.href
|
||||
(textValue ("https://github.com/anoma/juvix/commit/" <> shortHash))
|
||||
$ toHtml versionTag
|
||||
|
||||
juvixVersion :: Html
|
||||
juvixVersion =
|
||||
toHtml ("Powered by " :: Text)
|
||||
<> juvixLinkOrg
|
||||
<> commitInfo
|
||||
|
||||
return $
|
||||
case htmlKind of
|
||||
HtmlDoc ->
|
||||
Html.div ! Attr.id "footer" $
|
||||
p juvixVersion
|
||||
<> tara
|
||||
_ -> footer . pre $ juvixVersion
|
||||
|
@ -5,7 +5,6 @@ module Juvix.Compiler.Backend.Html.Translation.FromTyped
|
||||
)
|
||||
where
|
||||
|
||||
import Data.ByteString qualified as BS
|
||||
import Data.ByteString.Builder qualified as Builder
|
||||
import Data.HashMap.Strict qualified as HashMap
|
||||
import Data.Time.Clock
|
||||
@ -24,21 +23,26 @@ import Juvix.Compiler.Internal.Translation.FromInternal.Analysis.ArityChecking.D
|
||||
import Juvix.Compiler.Internal.Translation.FromInternal.Analysis.TypeChecking qualified as InternalTyped
|
||||
import Juvix.Compiler.Internal.Translation.FromInternal.Analysis.TypeChecking.Data.Context
|
||||
import Juvix.Compiler.Pipeline.EntryPoint
|
||||
import Juvix.Extra.Paths
|
||||
import Juvix.Extra.Assets
|
||||
import Juvix.Extra.Strings qualified as Str
|
||||
import Juvix.Extra.Version
|
||||
import Juvix.Prelude
|
||||
import Juvix.Prelude qualified as Prelude
|
||||
import Text.Blaze.Html.Renderer.Utf8 qualified as Html
|
||||
import Text.Blaze.Html5 as Html hiding (map)
|
||||
import Text.Blaze.Html5.Attributes qualified as Attr
|
||||
|
||||
data DocParams = DocParams
|
||||
{ _docParamBase :: Text,
|
||||
_docOutputDir :: Path Abs Dir
|
||||
data JudocArgs = JudocArgs
|
||||
{ _judocArgsOutputDir :: Path Abs Dir,
|
||||
_judocArgsBaseName :: Text,
|
||||
_judocArgsAssetsPrefix :: Text,
|
||||
_judocArgsUrlPrefix :: Text,
|
||||
_judocArgsCtx :: InternalTypedResult,
|
||||
_judocArgsTheme :: Theme,
|
||||
_judocArgsNonRecursive :: Bool,
|
||||
_judocArgsNoFooter :: Bool
|
||||
}
|
||||
|
||||
makeLenses ''DocParams
|
||||
makeLenses ''JudocArgs
|
||||
|
||||
data Tree k a = Tree
|
||||
{ _treeLabel :: a,
|
||||
@ -70,12 +74,12 @@ indexFileName = $(mkRelFile "index.html")
|
||||
|
||||
createIndexFile ::
|
||||
forall r.
|
||||
Members '[Reader DocParams, Embed IO, Reader HtmlOptions, Reader EntryPoint] r =>
|
||||
Members '[Embed IO, Reader HtmlOptions, Reader EntryPoint] r =>
|
||||
[TopModulePath] ->
|
||||
Sem r ()
|
||||
createIndexFile ps = do
|
||||
outDir <- asks (^. docOutputDir)
|
||||
indexHtml >>= (template mempty >=> writeHtml (outDir <//> indexFileName))
|
||||
outputDir <- asks (^. htmlOptionsOutputDir)
|
||||
indexHtml >>= (template mempty >=> writeHtml (outputDir <//> indexFileName))
|
||||
where
|
||||
indexHtml :: Sem r Html
|
||||
indexHtml = do
|
||||
@ -85,8 +89,10 @@ createIndexFile ps = do
|
||||
Html.div ! Attr.id "module-list" $
|
||||
(p ! Attr.class_ "caption" $ "Modules")
|
||||
<> tree'
|
||||
|
||||
tree :: ModuleTree
|
||||
tree = indexTree ps
|
||||
|
||||
root :: ModuleTree -> Sem r Html
|
||||
root (Tree _ t) = do
|
||||
c' <- mconcatMapM (uncurry goChild) (HashMap.toList t)
|
||||
@ -106,10 +112,13 @@ createIndexFile ps = do
|
||||
return $
|
||||
Html.span ! Attr.class_ attrBare $
|
||||
(a ! Attr.href lnk $ toHtml (prettyText lbl'))
|
||||
|
||||
attrBase :: Html.AttributeValue
|
||||
attrBase = "details-toggle-control details-toggle"
|
||||
|
||||
attrBare :: Html.AttributeValue
|
||||
attrBare = attrBase <> " directory"
|
||||
|
||||
node :: Sem r Html
|
||||
node = do
|
||||
row' <- nodeRow
|
||||
@ -127,46 +136,6 @@ createIndexFile ps = do
|
||||
summary "Subtree"
|
||||
<> ul (mconcatMap li c')
|
||||
|
||||
compile :: Members '[Embed IO] r => Path Abs Dir -> Text -> InternalTypedResult -> Sem r ()
|
||||
compile dir baseName ctx = runReader params . runReader normTable . runReader entry $ do
|
||||
copyAssets
|
||||
mapM_ goTopModule topModules
|
||||
runReader docHtmlOpts (createIndexFile (map topModulePath (toList topModules)))
|
||||
where
|
||||
entry :: EntryPoint
|
||||
entry = ctx ^. InternalTyped.internalTypedResultEntryPoint
|
||||
normTable :: InternalTyped.NormalizedTable
|
||||
normTable = ctx ^. InternalTyped.resultNormalized
|
||||
|
||||
mainMod :: Module 'Scoped 'ModuleTop
|
||||
mainMod =
|
||||
ctx
|
||||
^. InternalTyped.resultInternalArityResult
|
||||
. InternalArity.resultInternalResult
|
||||
. Internal.resultAbstract
|
||||
. Abstract.resultScoper
|
||||
. Scoped.mainModule
|
||||
copyAssets :: forall s. Members '[Embed IO, Reader DocParams] s => Sem s ()
|
||||
copyAssets = do
|
||||
toAssetsDir <- (<//> $(mkRelDir "assets")) <$> asks (^. docOutputDir)
|
||||
let writeAsset :: (Path Rel File, BS.ByteString) -> Sem s ()
|
||||
writeAsset (filePath, fileContents) =
|
||||
Prelude.embed $ BS.writeFile (toFilePath (toAssetsDir <//> filePath)) fileContents
|
||||
ensureDir toAssetsDir
|
||||
mapM_ writeAsset assetFiles
|
||||
where
|
||||
assetFiles :: [(Path Rel File, BS.ByteString)]
|
||||
assetFiles = assetsDir
|
||||
|
||||
params :: DocParams
|
||||
params =
|
||||
DocParams
|
||||
{ _docParamBase = baseName,
|
||||
_docOutputDir = dir
|
||||
}
|
||||
topModules :: HashMap NameId (Module 'Scoped 'ModuleTop)
|
||||
topModules = getAllModules mainMod
|
||||
|
||||
writeHtml :: Members '[Embed IO] r => Path Abs File -> Html -> Sem r ()
|
||||
writeHtml f h = Prelude.embed $ do
|
||||
ensureDir dir
|
||||
@ -175,94 +144,117 @@ writeHtml f h = Prelude.embed $ do
|
||||
dir :: Path Abs Dir
|
||||
dir = parent f
|
||||
|
||||
moduleDocPath :: Members '[Reader HtmlOptions, Reader DocParams] r => Module 'Scoped 'ModuleTop -> Sem r (Path Abs File)
|
||||
genJudocHtml :: Members '[Embed IO] r => JudocArgs -> Sem r ()
|
||||
genJudocHtml JudocArgs {..} =
|
||||
runReader htmlOpts . runReader normTable . runReader entry $ do
|
||||
Prelude.embed (writeAssets _judocArgsOutputDir)
|
||||
mapM_ goTopModule allModules
|
||||
createIndexFile (map topModulePath (toList allModules))
|
||||
where
|
||||
entry :: EntryPoint
|
||||
entry = _judocArgsCtx ^. InternalTyped.internalTypedResultEntryPoint
|
||||
|
||||
normTable :: InternalTyped.NormalizedTable
|
||||
normTable = _judocArgsCtx ^. InternalTyped.resultNormalized
|
||||
|
||||
mainMod :: Module 'Scoped 'ModuleTop
|
||||
mainMod =
|
||||
_judocArgsCtx
|
||||
^. InternalTyped.resultInternalArityResult
|
||||
. InternalArity.resultInternalResult
|
||||
. Internal.resultAbstract
|
||||
. Abstract.resultScoper
|
||||
. Scoped.mainModule
|
||||
|
||||
htmlOpts :: HtmlOptions
|
||||
htmlOpts =
|
||||
HtmlOptions
|
||||
{ _htmlOptionsKind = HtmlDoc,
|
||||
_htmlOptionsAssetsPrefix = _judocArgsAssetsPrefix,
|
||||
_htmlOptionsOutputDir = _judocArgsOutputDir,
|
||||
_htmlOptionsUrlPrefix = _judocArgsUrlPrefix,
|
||||
_htmlOptionsParamBase = _judocArgsBaseName,
|
||||
_htmlOptionsTheme = _judocArgsTheme,
|
||||
_htmlOptionsNoFooter = _judocArgsNoFooter
|
||||
}
|
||||
|
||||
allModules
|
||||
| _judocArgsNonRecursive = pure mainMod
|
||||
| otherwise = toList topModules
|
||||
|
||||
topModules :: HashMap NameId (Module 'Scoped 'ModuleTop)
|
||||
topModules = getAllModules mainMod
|
||||
|
||||
moduleDocPath :: Members '[Reader HtmlOptions] r => Module 'Scoped 'ModuleTop -> Sem r (Path Abs File)
|
||||
moduleDocPath m = do
|
||||
relPath <- moduleDocRelativePath (m ^. modulePath . S.nameConcrete)
|
||||
outDir <- asks (^. docOutputDir)
|
||||
return (outDir <//> relPath)
|
||||
outputDir <- asks (^. htmlOptionsOutputDir)
|
||||
return (outputDir <//> relPath)
|
||||
|
||||
topModulePath ::
|
||||
Module 'Scoped 'ModuleTop -> TopModulePath
|
||||
topModulePath :: Module 'Scoped 'ModuleTop -> TopModulePath
|
||||
topModulePath = (^. modulePath . S.nameConcrete)
|
||||
|
||||
srcHtmlOpts :: HtmlOptions
|
||||
srcHtmlOpts = HtmlOptions HtmlSrc
|
||||
|
||||
docHtmlOpts :: HtmlOptions
|
||||
docHtmlOpts = HtmlOptions HtmlDoc
|
||||
|
||||
template :: forall r. Members '[Reader EntryPoint] r => Html -> Html -> Sem r Html
|
||||
template :: forall r. Members '[Reader EntryPoint, Reader HtmlOptions] r => Html -> Html -> Sem r Html
|
||||
template rightMenu' content' = do
|
||||
mathJax <- mathJaxCdn
|
||||
ayuTheme <- ayuCss
|
||||
judocTheme <- linuwialCss
|
||||
let mhead :: Html
|
||||
mhead =
|
||||
Html.head $
|
||||
title titleStr
|
||||
<> Html.meta
|
||||
! Attr.httpEquiv "Content-Type"
|
||||
! Attr.content "text/html; charset=UTF-8"
|
||||
<> Html.meta
|
||||
! Attr.name "viewport"
|
||||
! Attr.content "width=device-width, initial-scale=1"
|
||||
<> mathJax
|
||||
<> livejs
|
||||
<> ayuTheme
|
||||
<> judocTheme
|
||||
|
||||
titleStr :: Html
|
||||
titleStr = "Juvix Documentation"
|
||||
|
||||
packageHeader :: Sem r Html
|
||||
packageHeader = do
|
||||
pkgName' <- toHtml <$> asks (^. entryPointPackage . packageName)
|
||||
version' <- toHtml <$> asks (^. entryPointPackage . packageVersion . to prettyV)
|
||||
return $
|
||||
Html.div ! Attr.id "package-header" $
|
||||
( Html.span ! Attr.class_ "caption" $
|
||||
pkgName' <> " - " <> version'
|
||||
)
|
||||
<> rightMenu'
|
||||
|
||||
mbody :: Sem r Html
|
||||
mbody = do
|
||||
bodyHeader' <- packageHeader
|
||||
footer' <- htmlJuvixFooter
|
||||
return $
|
||||
body ! Attr.class_ "js-enabled" $
|
||||
bodyHeader'
|
||||
<> content'
|
||||
<> footer'
|
||||
|
||||
body' <- mbody
|
||||
return (docTypeHtml (mhead <> body'))
|
||||
where
|
||||
mhead :: Html
|
||||
mhead =
|
||||
Html.head $
|
||||
title titleStr
|
||||
<> Html.meta
|
||||
! Attr.httpEquiv "Content-Type"
|
||||
! Attr.content "text/html; charset=UTF-8"
|
||||
<> Html.meta
|
||||
! Attr.name "viewport"
|
||||
! Attr.content "width=device-width, initial-scale=1"
|
||||
<> mathJaxCdn
|
||||
<> livejs
|
||||
<> ayuCss
|
||||
<> linuwialCss
|
||||
|
||||
titleStr :: Html
|
||||
titleStr = "Juvix Documentation"
|
||||
|
||||
packageHeader :: Sem r Html
|
||||
packageHeader = do
|
||||
pkgName' <- toHtml <$> asks (^. entryPointPackage . packageName)
|
||||
version' <- toHtml <$> asks (^. entryPointPackage . packageVersion . to prettyV)
|
||||
return $
|
||||
Html.div ! Attr.id "package-header" $
|
||||
( Html.span ! Attr.class_ "caption" $
|
||||
pkgName' <> " - " <> version'
|
||||
)
|
||||
<> rightMenu'
|
||||
|
||||
mbody :: Sem r Html
|
||||
mbody = do
|
||||
bodyHeader' <- packageHeader
|
||||
return $
|
||||
body ! Attr.class_ "js-enabled" $
|
||||
bodyHeader'
|
||||
<> content'
|
||||
<> mfooter
|
||||
|
||||
mfooter :: Html
|
||||
mfooter =
|
||||
Html.div ! Attr.id "footer" $
|
||||
p
|
||||
( "Build by "
|
||||
<> (Html.a ! Attr.href Str.juvixDotOrg $ "Juvix")
|
||||
<> " version "
|
||||
<> toHtml versionDoc
|
||||
)
|
||||
<> ( Html.a ! Attr.href Str.juvixDotOrg $
|
||||
Html.img
|
||||
! Attr.id "tara"
|
||||
! Attr.src "assets/Seating_Tara_smiling.svg"
|
||||
! Attr.alt "Tara"
|
||||
)
|
||||
return $ docTypeHtml (mhead <> body')
|
||||
|
||||
-- | This function compiles a datalang module into Html documentation.
|
||||
goTopModule ::
|
||||
forall r.
|
||||
Members '[Reader DocParams, Embed IO, Reader EntryPoint, Reader NormalizedTable] r =>
|
||||
Members '[Reader HtmlOptions, Embed IO, Reader EntryPoint, Reader NormalizedTable] r =>
|
||||
Module 'Scoped 'ModuleTop ->
|
||||
Sem r ()
|
||||
goTopModule m = do
|
||||
runReader docHtmlOpts $ do
|
||||
htmlOpts <- ask @HtmlOptions
|
||||
runReader (htmlOpts {_htmlOptionsKind = HtmlDoc}) $ do
|
||||
fpath <- moduleDocPath m
|
||||
Prelude.embed (putStrLn ("processing " <> pack (toFilePath fpath)))
|
||||
Prelude.embed (putStrLn ("Writing " <> pack (toFilePath fpath)))
|
||||
docHtml >>= writeHtml fpath
|
||||
|
||||
runReader srcHtmlOpts $ do
|
||||
runReader (htmlOpts {_htmlOptionsKind = HtmlSrc}) $ do
|
||||
fpath <- moduleDocPath m
|
||||
srcHtml >>= writeHtml fpath
|
||||
where
|
||||
@ -272,7 +264,12 @@ goTopModule m = do
|
||||
srcHtml :: forall s. Members '[Reader HtmlOptions, Embed IO] s => Sem s Html
|
||||
srcHtml = do
|
||||
utc <- Prelude.embed getCurrentTime
|
||||
return (genModuleHtml defaultOptions HtmlSrc True utc Ayu m)
|
||||
genModuleHtml
|
||||
GenModuleHtmlArgs
|
||||
{ _genModuleHtmlArgsConcreteOpts = defaultOptions,
|
||||
_genModuleHtmlArgsUTC = utc,
|
||||
_genModuleHtmlArgsEntryPoint = m
|
||||
}
|
||||
|
||||
docHtml :: forall s. Members '[Reader HtmlOptions, Reader EntryPoint, Reader NormalizedTable] s => Sem s Html
|
||||
docHtml = do
|
||||
@ -285,7 +282,7 @@ goTopModule m = do
|
||||
sourceRef' <- local (set htmlOptionsKind HtmlSrc) (nameIdAttrRef tmp Nothing)
|
||||
return $
|
||||
ul ! Attr.id "page-menu" ! Attr.class_ "links" $
|
||||
li (a ! Attr.href sourceRef' $ "Source")
|
||||
li (a ! Attr.href sourceRef' $ "Source") -- TODO: review here
|
||||
<> li (a ! Attr.href (fromString (toFilePath indexFileName)) $ "Index")
|
||||
|
||||
content :: Sem s Html
|
||||
@ -353,11 +350,13 @@ goJudoc (Judoc bs) = mconcatMapM goBlock bs
|
||||
goBlock = \case
|
||||
JudocParagraph ls -> Html.p . concatWith (\l r -> l <> " " <> r) <$> mapM goLine (toList ls)
|
||||
JudocExample e -> goExample e
|
||||
|
||||
goLine :: JudocParagraphLine 'Scoped -> Sem r Html
|
||||
goLine (JudocParagraphLine atoms) = mconcatMapM goAtom (toList atoms)
|
||||
|
||||
goExample :: Example 'Scoped -> Sem r Html
|
||||
goExample ex = do
|
||||
e' <- ppCodeHtml (ex ^. exampleExpression)
|
||||
e' <- ppCodeHtml defaultOptions (ex ^. exampleExpression)
|
||||
norm' <- asks @NormalizedTable (^?! at (ex ^. exampleId) . _Just) >>= ppCodeHtmlInternal
|
||||
return $
|
||||
Html.pre ! Attr.class_ "screen" $
|
||||
@ -366,9 +365,10 @@ goJudoc (Judoc bs) = mconcatMapM goBlock bs
|
||||
<> e'
|
||||
<> "\n"
|
||||
<> norm'
|
||||
|
||||
goAtom :: JudocAtom 'Scoped -> Sem r Html
|
||||
goAtom = \case
|
||||
JudocExpression e -> ppCodeHtml e
|
||||
JudocExpression e -> ppCodeHtml defaultOptions e
|
||||
JudocText txt -> return (toHtml txt)
|
||||
|
||||
goStatement :: Members '[Reader HtmlOptions, Reader NormalizedTable] r => Statement 'Scoped -> Sem r Html
|
||||
@ -381,7 +381,7 @@ goStatement = \case
|
||||
|
||||
goOpen :: forall r. Members '[Reader HtmlOptions] r => OpenModule 'Scoped -> Sem r Html
|
||||
goOpen op
|
||||
| Public <- op ^. openPublic = noDefHeader <$> ppCodeHtml op
|
||||
| Public <- op ^. openPublic = noDefHeader <$> ppCodeHtml defaultOptions op
|
||||
| otherwise = mempty
|
||||
|
||||
goAxiom :: forall r. Members '[Reader HtmlOptions, Reader NormalizedTable] r => AxiomDef 'Scoped -> Sem r Html
|
||||
@ -394,7 +394,7 @@ goAxiom axiom = do
|
||||
tmp :: TopModulePath
|
||||
tmp = axiom ^. axiomName . S.nameDefinedIn . S.absTopModulePath
|
||||
axiomHeader :: Sem r Html
|
||||
axiomHeader = ppCodeHtml (set axiomDoc Nothing axiom)
|
||||
axiomHeader = ppCodeHtml defaultOptions (set axiomDoc Nothing axiom)
|
||||
|
||||
goInductive :: forall r. Members '[Reader HtmlOptions, Reader NormalizedTable] r => InductiveDef 'Scoped -> Sem r Html
|
||||
goInductive def = do
|
||||
@ -409,7 +409,7 @@ goInductive def = do
|
||||
tmp = def ^. inductiveName . S.nameDefinedIn . S.absTopModulePath
|
||||
inductiveHeader :: Sem r Html
|
||||
inductiveHeader =
|
||||
runReader defaultOptions (ppInductiveSignature def) >>= ppCodeHtml
|
||||
runReader defaultOptions (ppInductiveSignature def) >>= ppCodeHtml defaultOptions
|
||||
|
||||
goConstructors :: forall r. Members '[Reader HtmlOptions, Reader NormalizedTable] r => NonEmpty (InductiveConstructorDef 'Scoped) -> Sem r Html
|
||||
goConstructors cc = do
|
||||
@ -432,7 +432,7 @@ goConstructors cc = do
|
||||
|
||||
srcPart :: Sem r Html
|
||||
srcPart = do
|
||||
sig' <- ppCodeHtml (set constructorDoc Nothing c)
|
||||
sig' <- ppCodeHtml defaultOptions (set constructorDoc Nothing c)
|
||||
return $
|
||||
td ! Attr.class_ "src" $
|
||||
sig'
|
||||
@ -469,7 +469,7 @@ goTypeSignature sig = do
|
||||
uid :: NameId
|
||||
uid = sig ^. sigName . S.nameId
|
||||
typeSig :: Sem r Html
|
||||
typeSig = ppCodeHtml (set sigDoc Nothing sig)
|
||||
typeSig = ppCodeHtml defaultOptions (set sigDoc Nothing sig)
|
||||
|
||||
sourceAndSelfLink :: Members '[Reader HtmlOptions] r => TopModulePath -> NameId -> Sem r Html
|
||||
sourceAndSelfLink tmp name = do
|
||||
|
@ -1,12 +1,11 @@
|
||||
module Juvix.Compiler.Backend.Html.Translation.FromTyped.Source where
|
||||
|
||||
import Data.ByteString qualified as BS
|
||||
import Data.Text qualified as Text
|
||||
import Data.Text.IO qualified as Text
|
||||
import Data.Text.Lazy (toStrict)
|
||||
import Data.Time.Clock
|
||||
import Data.Time.Format
|
||||
import Juvix.Compiler.Backend.Html.Data.Theme
|
||||
import Juvix.Compiler.Backend.Html.Data.Options
|
||||
import Juvix.Compiler.Backend.Html.Extra
|
||||
import Juvix.Compiler.Concrete.Data.ScopedName qualified as S
|
||||
import Juvix.Compiler.Concrete.Extra
|
||||
@ -14,8 +13,7 @@ import Juvix.Compiler.Concrete.Language
|
||||
import Juvix.Compiler.Concrete.Pretty.Base
|
||||
import Juvix.Compiler.Concrete.Translation.FromParsed.Analysis.PathResolver
|
||||
import Juvix.Compiler.Internal.Pretty qualified as Internal
|
||||
import Juvix.Extra.Paths
|
||||
import Juvix.Extra.Version
|
||||
import Juvix.Extra.Assets (writeAssets)
|
||||
import Juvix.Prelude
|
||||
import Prettyprinter.Render.Util.SimpleDocTree
|
||||
import Text.Blaze.Html
|
||||
@ -23,113 +21,159 @@ import Text.Blaze.Html.Renderer.Text qualified as Html
|
||||
import Text.Blaze.Html5 as Html hiding (map)
|
||||
import Text.Blaze.Html5.Attributes qualified as Attr
|
||||
|
||||
newtype HtmlOptions = HtmlOptions
|
||||
{ _htmlOptionsKind :: HtmlKind
|
||||
}
|
||||
|
||||
makeLenses ''HtmlOptions
|
||||
|
||||
kindSuffix :: HtmlKind -> String
|
||||
kindSuffix = \case
|
||||
HtmlDoc -> ""
|
||||
HtmlSrc -> "-src"
|
||||
HtmlOnly -> ""
|
||||
|
||||
genHtml :: Options -> Bool -> Theme -> Path Abs Dir -> Bool -> Module 'Scoped 'ModuleTop -> IO ()
|
||||
genHtml opts recursive theme outputDir printMetadata entry = do
|
||||
data GenSourceHtmlArgs = GenSourceHtmlArgs
|
||||
{ _genSourceHtmlArgsConcreteOpts :: Options,
|
||||
_genSourceHtmlArgsAssetsDir :: Text,
|
||||
_genSourceHtmlArgsHtmlKind :: HtmlKind,
|
||||
_genSourceHtmlArgsParamBase :: Text,
|
||||
_genSourceHtmlArgsUrlPrefix :: Text,
|
||||
_genSourceHtmlArgsEntryPoint :: Module 'Scoped 'ModuleTop,
|
||||
_genSourceHtmlArgsOutputDir :: Path Abs Dir,
|
||||
_genSourceHtmlArgsNonRecursive :: Bool,
|
||||
_genSourceHtmlArgsNoFooter :: Bool,
|
||||
_genSourceHtmlArgsTheme :: Theme
|
||||
}
|
||||
|
||||
makeLenses ''GenSourceHtmlArgs
|
||||
|
||||
data GenModuleHtmlArgs = GenModuleHtmlArgs
|
||||
{ _genModuleHtmlArgsConcreteOpts :: Options,
|
||||
_genModuleHtmlArgsUTC :: UTCTime,
|
||||
_genModuleHtmlArgsEntryPoint :: Module 'Scoped 'ModuleTop
|
||||
}
|
||||
|
||||
makeLenses ''GenModuleHtmlArgs
|
||||
|
||||
data GenModuleTextArgs = GenModuleTextArgs
|
||||
{ _genModuleTextArgsConcreteOpts :: Options,
|
||||
_genModuleTextArgsUTC :: UTCTime,
|
||||
_genModuleTextArgsEntryPoint :: Module 'Scoped 'ModuleTop
|
||||
}
|
||||
|
||||
makeLenses ''GenModuleTextArgs
|
||||
|
||||
genSourceHtml :: GenSourceHtmlArgs -> IO ()
|
||||
genSourceHtml o@GenSourceHtmlArgs {..} = do
|
||||
let outputDir = _genSourceHtmlArgsOutputDir
|
||||
ensureDir outputDir
|
||||
copyAssetFiles
|
||||
writeAssets outputDir
|
||||
withCurrentDir outputDir $ do
|
||||
mapM_ outputModule allModules
|
||||
where
|
||||
htmlOptions :: HtmlOptions
|
||||
htmlOptions =
|
||||
HtmlOptions
|
||||
{ _htmlOptionsOutputDir = o ^. genSourceHtmlArgsOutputDir,
|
||||
_htmlOptionsUrlPrefix = o ^. genSourceHtmlArgsUrlPrefix,
|
||||
_htmlOptionsAssetsPrefix = o ^. genSourceHtmlArgsAssetsDir,
|
||||
_htmlOptionsKind = o ^. genSourceHtmlArgsHtmlKind,
|
||||
_htmlOptionsParamBase = o ^. genSourceHtmlArgsParamBase,
|
||||
_htmlOptionsTheme = o ^. genSourceHtmlArgsTheme,
|
||||
_htmlOptionsNoFooter = o ^. genSourceHtmlArgsNoFooter
|
||||
}
|
||||
|
||||
entry = o ^. genSourceHtmlArgsEntryPoint
|
||||
|
||||
allModules
|
||||
| recursive = toList (getAllModules entry)
|
||||
| otherwise = pure entry
|
||||
| _genSourceHtmlArgsNonRecursive = pure entry
|
||||
| otherwise = toList topModules
|
||||
|
||||
copyAssetFiles :: IO ()
|
||||
copyAssetFiles = do
|
||||
ensureDir toAssetsDir
|
||||
mapM_ writeAsset assetFiles
|
||||
where
|
||||
assetFiles :: [(Path Rel File, BS.ByteString)]
|
||||
assetFiles = assetsDir
|
||||
|
||||
writeAsset :: (Path Rel File, BS.ByteString) -> IO ()
|
||||
writeAsset (filePath, fileContents) =
|
||||
BS.writeFile (toFilePath (toAssetsDir <//> filePath)) fileContents
|
||||
toAssetsDir = outputDir <//> $(mkRelDir "assets")
|
||||
topModules :: HashMap NameId (Module 'Scoped 'ModuleTop)
|
||||
topModules = getAllModules entry
|
||||
|
||||
outputModule :: Module 'Scoped 'ModuleTop -> IO ()
|
||||
outputModule m = do
|
||||
ensureDir (parent htmlFile)
|
||||
putStrLn $ "Writing " <> pack (toFilePath htmlFile)
|
||||
let absPath = (htmlOptions ^. htmlOptionsOutputDir) <//> htmlFile
|
||||
putStrLn $ "Writing " <> pack (toFilePath absPath)
|
||||
utc <- getCurrentTime
|
||||
Text.writeFile (toFilePath htmlFile) (genModule opts HtmlOnly printMetadata utc theme m)
|
||||
Text.writeFile
|
||||
(toFilePath htmlFile)
|
||||
( run . runReader htmlOptions $
|
||||
genModuleText
|
||||
GenModuleTextArgs
|
||||
{ _genModuleTextArgsConcreteOpts = o ^. genSourceHtmlArgsConcreteOpts,
|
||||
_genModuleTextArgsUTC = utc,
|
||||
_genModuleTextArgsEntryPoint = m
|
||||
}
|
||||
)
|
||||
where
|
||||
htmlFile :: Path Rel File
|
||||
htmlFile = relFile (topModulePathToDottedPath (m ^. modulePath . S.nameConcrete) <.> ".html")
|
||||
|
||||
genModuleHtml :: Options -> HtmlKind -> Bool -> UTCTime -> Theme -> Module 'Scoped 'ModuleTop -> Html
|
||||
genModuleHtml opts htmlKind printMetadata utc theme m =
|
||||
docTypeHtml ! Attr.xmlns "http://www.w3.org/1999/xhtml" $
|
||||
mhead
|
||||
<> mbody
|
||||
<> if printMetadata then infoFooter else mempty
|
||||
where
|
||||
themeCss :: Html
|
||||
themeCss = case theme of
|
||||
Ayu -> ayuCss
|
||||
Nord -> nordCss
|
||||
|
||||
htmlOpts :: HtmlOptions
|
||||
htmlOpts =
|
||||
HtmlOptions
|
||||
{ _htmlOptionsKind = htmlKind
|
||||
genModuleText ::
|
||||
forall r.
|
||||
Members '[Reader HtmlOptions] r =>
|
||||
GenModuleTextArgs ->
|
||||
Sem r Text
|
||||
genModuleText GenModuleTextArgs {..} = do
|
||||
outputHtml <-
|
||||
genModuleHtml $
|
||||
GenModuleHtmlArgs
|
||||
{ _genModuleHtmlArgsConcreteOpts = _genModuleTextArgsConcreteOpts,
|
||||
_genModuleHtmlArgsUTC = _genModuleTextArgsUTC,
|
||||
_genModuleHtmlArgsEntryPoint = _genModuleTextArgsEntryPoint
|
||||
}
|
||||
return . toStrict . Html.renderHtml $ outputHtml
|
||||
|
||||
pp :: PrettyCode a => a -> Html
|
||||
pp = ppCodeHtml' htmlOpts opts
|
||||
genModuleHtml ::
|
||||
forall r.
|
||||
Members '[Reader HtmlOptions] r =>
|
||||
GenModuleHtmlArgs ->
|
||||
Sem r Html
|
||||
genModuleHtml o = do
|
||||
outHtml <- mhead <> mbody
|
||||
return $
|
||||
docTypeHtml ! Attr.xmlns "http://www.w3.org/1999/xhtml" $
|
||||
outHtml
|
||||
where
|
||||
mhead :: Sem r Html
|
||||
mhead = do
|
||||
css <- themeCss
|
||||
js <- highlightJs
|
||||
return $
|
||||
metaUtf8
|
||||
<> css
|
||||
<> js
|
||||
|
||||
prettySrc :: Html
|
||||
prettySrc =
|
||||
(pre ! Attr.id "src-content") $
|
||||
pp m
|
||||
|
||||
mheader :: Html
|
||||
mheader =
|
||||
Html.div ! Attr.id "package-header" $
|
||||
(Html.span ! Attr.class_ "caption" $ "")
|
||||
|
||||
mhead :: Html
|
||||
mhead =
|
||||
metaUtf8
|
||||
<> themeCss
|
||||
<> highlightJs
|
||||
|
||||
mbody :: Html
|
||||
mbody :: Sem r Html
|
||||
mbody =
|
||||
mheader
|
||||
<> prettySrc
|
||||
fold
|
||||
[ mheader,
|
||||
prettySrc,
|
||||
htmlJuvixFooter,
|
||||
formattedTime
|
||||
]
|
||||
|
||||
infoFooter :: Html
|
||||
infoFooter =
|
||||
footer . pre $
|
||||
toHtml ("Powered by " :: Text)
|
||||
<> (a ! Attr.href "https://anoma.github.io/juvix" $ toHtml ("Juvix CLI " :: Text))
|
||||
<> (a ! Attr.href (textValue commitAddress) $ toHtml versionTag)
|
||||
<> br
|
||||
<> Html.span (toHtml $ ("Last modified on " :: String) <> formattedTime)
|
||||
where
|
||||
commitAddress :: Text
|
||||
commitAddress = "https://github.com/anoma/juvix/commit/" <> shortHash
|
||||
formattedTime :: Sem r Html
|
||||
formattedTime =
|
||||
return $
|
||||
Html.span . toHtml $
|
||||
"Last modified on "
|
||||
<> formatTime
|
||||
defaultTimeLocale
|
||||
"%Y-%m-%d %-H:%M %Z"
|
||||
(o ^. genModuleHtmlArgsUTC)
|
||||
|
||||
formattedTime = formatTime defaultTimeLocale "%Y-%m-%d %-H:%M %Z" utc
|
||||
prettySrc :: Sem r Html
|
||||
prettySrc = do
|
||||
pp <-
|
||||
ppCodeHtml
|
||||
(o ^. genModuleHtmlArgsConcreteOpts)
|
||||
(o ^. genModuleHtmlArgsEntryPoint)
|
||||
return $ (pre ! Attr.id "src-content") pp
|
||||
|
||||
genModule :: Options -> HtmlKind -> Bool -> UTCTime -> Theme -> Module 'Scoped 'ModuleTop -> Text
|
||||
genModule opts htmlKind printMetadata utc theme =
|
||||
toStrict
|
||||
. Html.renderHtml
|
||||
. genModuleHtml opts htmlKind printMetadata utc theme
|
||||
mheader :: Sem r Html
|
||||
mheader =
|
||||
return $
|
||||
Html.div ! Attr.id "package-header" $
|
||||
(Html.span ! Attr.class_ "caption" $ "")
|
||||
|
||||
docStream' :: PrettyCode a => Options -> a -> SimpleDocStream Ann
|
||||
docStream' opts m = layoutPretty defaultLayoutOptions (runPrettyCode opts m)
|
||||
@ -140,10 +184,14 @@ renderTree = go
|
||||
ppCodeHtml' :: PrettyCode a => HtmlOptions -> Options -> a -> Html
|
||||
ppCodeHtml' htmlOpts opts = run . runReader htmlOpts . renderTree . treeForm . docStream' opts
|
||||
|
||||
ppCodeHtml :: (Members '[Reader HtmlOptions] r, PrettyCode a) => a -> Sem r Html
|
||||
ppCodeHtml x = do
|
||||
ppCodeHtml ::
|
||||
(Members '[Reader HtmlOptions] r, PrettyCode a) =>
|
||||
Options ->
|
||||
a ->
|
||||
Sem r Html
|
||||
ppCodeHtml opts x = do
|
||||
o <- ask
|
||||
return (ppCodeHtml' o defaultOptions x)
|
||||
return (ppCodeHtml' o opts x)
|
||||
|
||||
ppCodeHtmlInternal :: (Members '[Reader HtmlOptions] r, Internal.PrettyCode a) => a -> Sem r Html
|
||||
ppCodeHtmlInternal x = do
|
||||
@ -225,4 +273,9 @@ moduleDocRelativePath m = do
|
||||
nameIdAttrRef :: Members '[Reader HtmlOptions] r => TopModulePath -> Maybe S.NameId -> Sem r AttributeValue
|
||||
nameIdAttrRef tp s = do
|
||||
pth <- toFilePath <$> moduleDocRelativePath tp
|
||||
return (fromString pth <> preEscapedToValue '#' <>? (nameIdAttr <$> s))
|
||||
prefixUrl <- unpack <$> asks (^. htmlOptionsUrlPrefix)
|
||||
return $
|
||||
fromString prefixUrl
|
||||
<> fromString pth
|
||||
<> preEscapedToValue '#'
|
||||
<>? (nameIdAttr <$> s)
|
||||
|
@ -11,13 +11,16 @@ topModulePathToRelativePath ext suffix joinpath mp = relFile relFilePath
|
||||
where
|
||||
relDirPath :: FilePath
|
||||
relDirPath = foldr (joinpath . toPath) mempty (mp ^. modulePathDir)
|
||||
|
||||
relFilePath :: FilePath
|
||||
relFilePath = addExt (relDirPath `joinpath'` toPath (mp ^. modulePathName) <> suffix)
|
||||
|
||||
joinpath' :: FilePath -> FilePath -> FilePath
|
||||
joinpath' l r
|
||||
| null l = r
|
||||
| otherwise = joinpath l r
|
||||
addExt = (<.> ext)
|
||||
|
||||
toPath :: Symbol -> FilePath
|
||||
toPath s = unpack (s ^. symbolText)
|
||||
|
||||
|
@ -278,16 +278,15 @@ goFunctionDef (f, sym) = do
|
||||
mkBody :: Sem r Node
|
||||
mkBody
|
||||
| nPatterns == 0 = runReader initIndexTable (goExpression (f ^. Internal.funDefClauses . _head1 . Internal.clauseBody))
|
||||
| otherwise =
|
||||
( do
|
||||
let values :: [Node]
|
||||
values = mkVar Info.empty <$> vs
|
||||
indexTable :: IndexTable
|
||||
indexTable = IndexTable {_indexTableVarsNum = nPatterns, _indexTableVars = mempty}
|
||||
ms <- mapM (runReader indexTable . goFunctionClause) (f ^. Internal.funDefClauses)
|
||||
let match = mkMatch' (fromList values) (toList ms)
|
||||
return $ foldr (\_ n -> mkLambda' n) match vs
|
||||
)
|
||||
| otherwise = do
|
||||
let values :: [Node]
|
||||
values = mkVar Info.empty <$> vs
|
||||
indexTable :: IndexTable
|
||||
indexTable = IndexTable {_indexTableVarsNum = nPatterns, _indexTableVars = mempty}
|
||||
ms <- mapM (runReader indexTable . goFunctionClause) (f ^. Internal.funDefClauses)
|
||||
let match = mkMatch' (fromList values) (toList ms)
|
||||
return $ foldr (\_ n -> mkLambda' n) match vs
|
||||
|
||||
-- Assumption: All clauses have the same number of patterns
|
||||
nPatterns :: Int
|
||||
nPatterns = length (f ^. Internal.funDefClauses . _head1 . Internal.clausePatterns)
|
||||
|
49
src/Juvix/Extra/Assets.hs
Normal file
@ -0,0 +1,49 @@
|
||||
module Juvix.Extra.Assets
|
||||
( module Juvix.Extra.Assets,
|
||||
)
|
||||
where
|
||||
|
||||
import Data.ByteString qualified as BS
|
||||
import Juvix.Extra.Paths
|
||||
import Juvix.Prelude.Base
|
||||
import Juvix.Prelude.Path
|
||||
|
||||
data AssetKind
|
||||
= Css
|
||||
| Js
|
||||
| Images
|
||||
|
||||
assetsDirByKind :: AssetKind -> [(Path Rel File, ByteString)]
|
||||
assetsDirByKind k = map (first relFile) $
|
||||
case k of
|
||||
Css -> $(cssDirQ)
|
||||
Js -> $(jsDirQ)
|
||||
Images -> $(imagesDirQ)
|
||||
|
||||
absDirAssetsByKind :: Path Abs Dir -> AssetKind -> Path Abs Dir
|
||||
absDirAssetsByKind baseDir k = baseDir <//> $(mkRelDir "assets") <//> dir
|
||||
where
|
||||
dir :: Path Rel Dir
|
||||
dir = case k of
|
||||
Css -> $(mkRelDir "css")
|
||||
Js -> $(mkRelDir "js")
|
||||
Images -> $(mkRelDir "images")
|
||||
|
||||
assetsWithAbsPathAndContent :: Path Abs Dir -> [(Path Abs File, ByteString)]
|
||||
assetsWithAbsPathAndContent baseDir =
|
||||
[ (absPath, content)
|
||||
| kind <- [Css, Js, Images],
|
||||
(relPart, content) <- assetsDirByKind kind,
|
||||
let absPath = absDirAssetsByKind baseDir kind <//> relPart
|
||||
]
|
||||
|
||||
writeAssets :: Path Abs Dir -> IO ()
|
||||
writeAssets baseDir = do
|
||||
putStrLn $ "Copying assets files to " <> pack (toFilePath baseDir)
|
||||
mapM_ writeAssetFile (assetsWithAbsPathAndContent baseDir)
|
||||
where
|
||||
writeAssetFile :: (Path Abs File, ByteString) -> IO ()
|
||||
writeAssetFile (p, content) = do
|
||||
let dirFile = parent p
|
||||
createDirIfMissing True dirFile
|
||||
BS.writeFile (toFilePath p) content
|
@ -15,6 +15,15 @@ relToProject r = $(projectPath) <//> r
|
||||
assetsDir :: [(Path Rel File, ByteString)]
|
||||
assetsDir = map (first relFile) $(assetsDirQ)
|
||||
|
||||
cssDir :: [(Path Rel File, ByteString)]
|
||||
cssDir = map (first relFile) $(cssDirQ)
|
||||
|
||||
jsDir :: [(Path Rel File, ByteString)]
|
||||
jsDir = map (first relFile) $(jsDirQ)
|
||||
|
||||
imagesDir :: [(Path Rel File, ByteString)]
|
||||
imagesDir = map (first relFile) $(imagesDirQ)
|
||||
|
||||
-- | Given a relative file from the root of the project, checks that the file
|
||||
-- exists and returns the absolute path
|
||||
mkProjFile :: Path Rel File -> Q Exp
|
||||
|
@ -7,6 +7,15 @@ import Language.Haskell.TH.Syntax
|
||||
assetsDirQ :: Q Exp
|
||||
assetsDirQ = FE.makeRelativeToProject "assets" >>= FE.embedDir
|
||||
|
||||
cssDirQ :: Q Exp
|
||||
cssDirQ = FE.makeRelativeToProject "assets/css" >>= FE.embedDir
|
||||
|
||||
jsDirQ :: Q Exp
|
||||
jsDirQ = FE.makeRelativeToProject "assets/js" >>= FE.embedDir
|
||||
|
||||
imagesDirQ :: Q Exp
|
||||
imagesDirQ = FE.makeRelativeToProject "assets/images" >>= FE.embedDir
|
||||
|
||||
projectFilePath :: Q Exp
|
||||
projectFilePath = FE.makeRelativeToProject "." >>= lift
|
||||
|
||||
|
@ -191,5 +191,5 @@ tests =
|
||||
$(mkRelDir "Internal")
|
||||
$(mkRelFile "Synonyms.juvix")
|
||||
]
|
||||
<> [ compilationTest t | t <- Compilation.tests, t ^. Compilation.name `notElem` ["Self-application"]
|
||||
<> [ compilationTest t | t <- Compilation.tests, t ^. Compilation.name /= "Self-application"
|
||||
]
|
||||
|
@ -7,9 +7,9 @@ tests:
|
||||
- bash
|
||||
script: |
|
||||
cd milestone/ValidityPredicates
|
||||
juvix html SimpleFungibleToken.juvix
|
||||
juvix html SimpleFungibleToken.juvix --only-source
|
||||
cat html/SimpleFungibleToken.html
|
||||
stdout:
|
||||
stdout:
|
||||
contains:
|
||||
<!DOCTYPE HTML>
|
||||
exit-status: 0
|
||||
@ -20,12 +20,13 @@ tests:
|
||||
- bash
|
||||
script: |
|
||||
rm -rf html
|
||||
juvix html milestone/ValidityPredicates/SimpleFungibleToken.juvix --output-dir=html
|
||||
juvix html milestone/ValidityPredicates/SimpleFungibleToken.juvix --only-source --output-dir=html --non-recursive
|
||||
[ -d html/assets ]
|
||||
[ -f html/SimpleFungibleToken.html ]
|
||||
stdout:
|
||||
equals: |
|
||||
Writing SimpleFungibleToken.html
|
||||
stdout:
|
||||
matches: |
|
||||
Copying assets files to .*
|
||||
Writing .*SimpleFungibleToken.html
|
||||
exit-status: 0
|
||||
|
||||
- name: recursive-generation
|
||||
@ -34,9 +35,7 @@ tests:
|
||||
- bash
|
||||
script: |
|
||||
rm -rf html
|
||||
juvix html milestone/ValidityPredicates/SimpleFungibleToken.juvix --output-dir=html --recursive
|
||||
[ -d html/assets ]
|
||||
[ -f html/SimpleFungibleToken.html ]
|
||||
juvix html milestone/ValidityPredicates/SimpleFungibleToken.juvix --only-source --output-dir=html
|
||||
(ls html | wc -l)
|
||||
cd html
|
||||
[ -f Stdlib.Data.Ord.html ]
|
||||
@ -54,10 +53,94 @@ tests:
|
||||
[ -f Stdlib.Prelude.html ]
|
||||
[ -f Anoma.Base.html ]
|
||||
[ -f SimpleFungibleToken.html ]
|
||||
[ -f assets/highlight.js ]
|
||||
[ -f assets/source-ayu-light.css ]
|
||||
[ -f assets/source-nord.css ]
|
||||
stdout:
|
||||
[ -f assets/css/source-ayu-light.css ]
|
||||
[ -f assets/css/source-nord.css ]
|
||||
[ -f assets/images/tara-magicien.png ]
|
||||
[ -f assets/images/tara-seating.svg ]
|
||||
[ -f assets/images/tara-smiling.png ]
|
||||
[ -f assets/images/tara-smiling.svg ]
|
||||
[ -f assets/images/tara-teaching.png ]
|
||||
[ -f assets/images/tara-teaching.svg ]
|
||||
[ -f assets/js/highlight.js ]
|
||||
[ -f assets/js/tex-chtml.js ]
|
||||
stdout:
|
||||
contains: |
|
||||
Writing SimpleFungibleToken.html
|
||||
SimpleFungibleToken.html
|
||||
exit-status: 0
|
||||
|
||||
|
||||
- name: judoc-assets
|
||||
command:
|
||||
shell:
|
||||
- bash
|
||||
script: |
|
||||
rm -rf html
|
||||
juvix html milestone/ValidityPredicates/SimpleFungibleToken.juvix --output-dir=html
|
||||
(ls html | wc -l)
|
||||
cd html
|
||||
[ -f Stdlib.Data.Ord.html ]
|
||||
[ -f Stdlib.Data.String.html ]
|
||||
[ -f Stdlib.Data.Nat.html ]
|
||||
[ -f Stdlib.System.IO.html ]
|
||||
[ -f Stdlib.Function.html ]
|
||||
[ -f Stdlib.Data.List.html ]
|
||||
[ -f Stdlib.Data.String.Ord.html ]
|
||||
[ -f Stdlib.Data.Product.html ]
|
||||
[ -f Data.Int.Ops.html ]
|
||||
[ -f Stdlib.Data.Maybe.html ]
|
||||
[ -f Data.Int.html ]
|
||||
[ -f Stdlib.Data.Bool.html ]
|
||||
[ -f Stdlib.Prelude.html ]
|
||||
[ -f Anoma.Base.html ]
|
||||
[ -f SimpleFungibleToken.html ]
|
||||
[ -f assets/css/source-ayu-light.css ]
|
||||
[ -f assets/css/source-nord.css ]
|
||||
[ -f assets/css/linuwial.css ]
|
||||
[ -f assets/images/tara-magicien.png ]
|
||||
[ -f assets/images/tara-seating.svg ]
|
||||
[ -f assets/images/tara-smiling.png ]
|
||||
[ -f assets/images/tara-smiling.svg ]
|
||||
[ -f assets/images/tara-teaching.png ]
|
||||
[ -f assets/images/tara-teaching.svg ]
|
||||
[ -f assets/js/highlight.js ]
|
||||
[ -f assets/js/tex-chtml.js ]
|
||||
stdout:
|
||||
contains: |
|
||||
SimpleFungibleToken.html
|
||||
exit-status: 0
|
||||
|
||||
- name: non-recursive-generation
|
||||
command:
|
||||
shell:
|
||||
- bash
|
||||
script: |
|
||||
rm -rf html
|
||||
juvix html milestone/ValidityPredicates/SimpleFungibleToken.juvix --output-dir=html --non-recursive
|
||||
(ls html | wc -l)
|
||||
cd html
|
||||
[ -d assets ]
|
||||
[ -f SimpleFungibleToken.html ]
|
||||
stdout:
|
||||
matches: |
|
||||
Copying assets files to .*
|
||||
Writing .*SimpleFungibleToken.html
|
||||
4
|
||||
exit-status: 0
|
||||
|
||||
- name: non-recursive-generation-only-source
|
||||
command:
|
||||
shell:
|
||||
- bash
|
||||
script: |
|
||||
rm -rf html
|
||||
juvix html milestone/ValidityPredicates/SimpleFungibleToken.juvix --output-dir=html --non-recursive --only-source
|
||||
(ls html | wc -l)
|
||||
cd html
|
||||
[ -d assets/ ]
|
||||
[ -f SimpleFungibleToken.html ]
|
||||
stdout:
|
||||
matches: |
|
||||
Copying assets files to .*
|
||||
Writing .*SimpleFungibleToken.html
|
||||
2
|
||||
exit-status: 0
|
||||
|