Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
decker
decker
Commits
e894bbad
Commit
e894bbad
authored
May 02, 2021
by
Mario Botsch
Browse files
Merge branch 'master' into mario
parents
2ed2d99e
60ba40a9
Changes
11
Hide whitespace changes
Inline
Side-by-side
app/Decker.hs
View file @
e894bbad
...
...
@@ -258,14 +258,23 @@ run = do
need
[
src
]
command
[]
"sass"
[
src
,
out
]
--
"**/*.plantuml.svg"
%>
\
out
->
do
let
src
=
dropExtension
out
need
[
src
]
putNormal
$
"# plantuml (for "
<>
out
<>
")"
plantuml
[
src
]
liftIO
$
Dir
.
renameFile
(
src
-<.>
"svg"
)
out
--
"**/*.dot.svg"
%>
\
out
->
do
let
src
=
dropExtension
out
need
[
src
]
putNormal
$
"# dot (for "
<>
out
<>
")"
dot
[
"-o"
++
out
,
src
]
--
"**/*.gnuplot.svg"
%>
\
out
->
do
let
src
=
dropExtension
out
need
[
src
]
putNormal
$
"# gnuplot (for "
<>
out
<>
")"
gnuplot
[
"-e"
,
"
\"
set output '"
++
out
++
"'
\"
"
,
src
]
--
"**/*-recording.mp4"
%>
\
out
->
do
...
...
doc/media-filter-report-page.md
View file @
e894bbad
...
...
@@ -59,10 +59,26 @@ An SVG image that is embedded into the HTML document.
translates to
```
{.html}
<span class="decker svg embed" style="background-color:magenta;">
<svg>This space intentionally left blank</svg>
</span>
<div class="decker image error">
<h2 class="title">
<i class="fa fa-exclamation-triangle">
</i>
Decker error
</h2>
<p class="message">
test/decks/empty.svg: openFile: does not exist (No such file or directory)
</p>
<p>
encountered while processing
</p>
<pre class="markup">
<code class="markup">
{.embed css:background-color="magenta"}
</code>
</pre>
</div>
```
------------------------------------------------------------------------
...
...
resource/support/engine/engine.css
View file @
e894bbad
...
...
@@ -382,56 +382,56 @@ div.q-panel div.q-footer div.q-login:hover {
color
:
var
(
--whiteboard-active-color
);
}
div
.q-panel
div
.
content
{
div
.q-panel
div
.
item
{
font-size
:
1em
;
}
div
.q-panel
div
.
content
em
{
div
.q-panel
div
.
item
em
{
font-style
:
italic
;
}
div
.q-panel
div
.
content
strong
{
div
.q-panel
div
.
item
strong
{
font-weight
:
bold
;
}
div
.q-panel
div
.
content
a
{
div
.q-panel
div
.
item
a
{
color
:
darkblue
;
}
div
.q-panel
div
.
content
p
,
div
.q-panel
div
.
item
p
,
div
.q-panel
ul
,
div
.q-panel
ol
{
padding-bottom
:
0.3em
;
}
div
.q-panel
div
.
content
p
:last-child
,
div
.q-panel
div
.
content
ul
:last-child
,
div
.q-panel
div
.
content
ol
:last-child
{
div
.q-panel
div
.
item
p
:last-child
,
div
.q-panel
div
.
item
ul
:last-child
,
div
.q-panel
div
.
item
ol
:last-child
{
padding-bottom
:
0
;
}
div
.q-panel
div
.
content
ol
{
div
.q-panel
div
.
item
ol
{
list-style-type
:
lower-alpha
;
list-style-position
:
inside
;
}
div
.q-panel
div
.
content
ul
{
div
.q-panel
div
.
item
ul
{
list-style-type
:
disc
;
list-style-position
:
inside
;
}
div
.q-panel
div
.
content
code
{
div
.q-panel
div
.
item
code
{
font-family
:
Consolas
,
Monaco
,
monospace
;
font-size
:
0.9em
;
}
div
.q-panel
div
.
content
pre
{
div
.q-panel
div
.
item
pre
{
padding
:
0.2em
;
background-color
:
#eee
;
white-space
:
pre-wrap
;
}
div
.q-panel
div
.
content
h1
{
div
.q-panel
div
.
item
h1
{
font-size
:
1.2em
;
font-weight
:
bold
;
padding-bottom
:
0.2em
;
...
...
@@ -439,7 +439,7 @@ div.q-panel div.content h1 {
color
:
#333
;
}
div
.q-panel
div
.
content
h2
{
div
.q-panel
div
.
item
h2
{
font-size
:
1.1em
;
font-weight
:
bold
;
padding-bottom
:
0.2em
;
...
...
@@ -447,7 +447,7 @@ div.q-panel div.content h2 {
color
:
#333
;
}
div
.q-panel
div
.
content
img
{
div
.q-panel
div
.
item
img
{
width
:
100%
;
image-rendering
:
pixelated
;
}
...
...
resource/support/js/decker.js
View file @
e894bbad
...
...
@@ -33,7 +33,6 @@ function deckerStart() {
// if (!printMode) {
// setTimeout(continueWhereYouLeftOff, 500);
// }
renderSvgMath
();
}
function
prepareTaskLists
()
{
...
...
@@ -294,22 +293,6 @@ function continueWhereYouLeftOff() {
}
}
// TODO: Make geometry.js into a proper module and arrange it to be loaded after
// TODO: MathJax.
function
renderSvgMath
()
{
// Create a copy of the script with type 'geometry' that has type 'module' and
// will be executed immediately. Defers script execution until after MathJax
// has been initialized. Deletes the original 'geometry' script.
let
scripts
=
document
.
querySelectorAll
(
"
script[type=geometry]
"
);
for
(
let
script
of
scripts
)
{
let
js
=
document
.
createElement
(
"
script
"
);
js
.
setAttribute
(
"
type
"
,
"
module
"
);
js
.
innerText
=
script
.
innerText
;
script
.
insertAdjacentElement
(
"
beforebegin
"
,
js
);
script
.
parentNode
.
removeChild
(
script
);
}
}
// List of predicates that all must return true for a requested reload to
// actually be performed.
let
reloadInhibitors
=
[];
...
...
resource/support/plugins/math/math.js
View file @
e894bbad
...
...
@@ -12,7 +12,7 @@
* - disable SVG font caches, since it doesn't work in speaker notes
* - reset menu settings in localStorage
* - use promise mechanism to ensure that math is typset before PDF print
* - fix links generated by referencing equations to jump to the slide
* - fix links generated by referencing equations to jump to the slide
* containing the referenced equation
* - inject class=fragment to incrementally show multi-line equations
* (if MathJax element in enclosed in div.math-incremental)
...
...
@@ -23,105 +23,96 @@
"
use strict
"
;
let
RevealMath
=
window
.
RevealMath
||
(
function
(){
let
options
=
Reveal
.
getConfig
().
math
||
{};
let
mathjax
=
options
.
mathjax
||
'
https://cdn.jsdelivr.net/npm/mathjax@3/es5/
'
;
let
url
=
mathjax
+
'
tex-svg.js
'
;
function
loadScript
(
url
,
callback
)
{
var
head
=
document
.
querySelector
(
'
head
'
);
var
script
=
document
.
createElement
(
'
script
'
);
script
.
type
=
'
text/javascript
'
;
script
.
id
=
'
MathJax-script
'
;
script
.
src
=
url
;
// Wrapper for callback to make sure it only fires once
var
finish
=
function
()
{
if
(
typeof
callback
===
'
function
'
)
{
callback
.
call
();
callback
=
null
;
}
}
script
.
onload
=
finish
;
// IE
script
.
onreadystatechange
=
function
()
{
if
(
this
.
readyState
===
'
loaded
'
)
{
finish
();
}
}
// Normal browsers
head
.
appendChild
(
script
);
}
let
RevealMath
=
window
.
RevealMath
||
(
function
()
{
let
options
=
Reveal
.
getConfig
().
math
||
{};
let
mathjax
=
options
.
mathjax
||
"
https://cdn.jsdelivr.net/npm/mathjax@3/es5/
"
;
let
url
=
mathjax
+
"
tex-svg.js
"
;
function
loadScript
(
url
,
callback
)
{
var
head
=
document
.
querySelector
(
"
head
"
);
var
script
=
document
.
createElement
(
"
script
"
);
script
.
type
=
"
text/javascript
"
;
script
.
id
=
"
MathJax-script
"
;
script
.
src
=
url
;
// Wrapper for callback to make sure it only fires once
var
finish
=
function
()
{
if
(
typeof
callback
===
"
function
"
)
{
callback
.
call
();
callback
=
null
;
}
};
script
.
onload
=
finish
;
// IE
script
.
onreadystatechange
=
function
()
{
if
(
this
.
readyState
===
"
loaded
"
)
{
finish
();
}
};
// Normal browsers
head
.
appendChild
(
script
);
}
/*
* correct links generated by referencing equations, such that they
* point to the slide containing the referenced equation.
* Requires that each slide has a CSS id (as generated e.g. by pandoc/decker)
*/
function
fixLinks
()
{
for
(
var
a
of
document
.
getElementsByTagName
(
"
a
"
))
{
var
href
=
a
.
href
;
if
(
href
.
baseVal
)
{
var
label
=
href
.
baseVal
;
if
(
label
.
includes
(
"
#mjx-eqn
"
))
{
label
=
decodeURIComponent
(
label
.
substring
(
1
));
var
eqn
=
document
.
getElementById
(
label
);
if
(
eqn
)
{
var
s
=
eqn
.
closest
(
"
section
"
);
if
(
s
)
{
a
.
href
.
baseVal
=
location
.
origin
+
location
.
pathname
+
"
#
"
+
s
.
id
;
}
}
}
function
fixLinks
()
{
for
(
var
a
of
document
.
getElementsByTagName
(
"
a
"
))
{
var
href
=
a
.
href
;
if
(
href
.
baseVal
)
{
var
label
=
href
.
baseVal
;
if
(
label
.
includes
(
"
#mjx-eqn
"
))
{
label
=
decodeURIComponent
(
label
.
substring
(
1
));
var
eqn
=
document
.
getElementById
(
label
);
if
(
eqn
)
{
var
s
=
eqn
.
closest
(
"
section
"
);
if
(
s
)
{
a
.
href
.
baseVal
=
location
.
origin
+
location
.
pathname
+
"
#
"
+
s
.
id
;
}
}
}
}
}
}
/*
* If a multi-line equation is enclosed in a div with class math-incremental,
* then add class fragment to the individual rows of the equation, making it
* appear row-by-row.
*/
function
setupMathIncremental
()
{
// unlabeled equations
for
(
let
mrow
of
document
.
querySelectorAll
(
'
.reveal .math-incremental mjx-container svg g[data-mml-node="mtable"]:first-of-type > g[data-mml-node="mtr"]
'
))
{
mrow
.
classList
.
add
(
"
fragment
"
);
}
// unlabeled equations
for
(
let
mrow
of
document
.
querySelectorAll
(
'
.reveal .math-incremental mjx-container svg g[data-mml-node="mtable"]:first-of-type g[data-mml-node="mlabeledtr"]
'
))
{
mrow
.
classList
.
add
(
"
fragment
"
);
}
function
setupMathIncremental
()
{
// unlabeled equations
for
(
let
mrow
of
document
.
querySelectorAll
(
'
.reveal .math-incremental mjx-container svg g[data-mml-node="mtable"]:first-of-type > g[data-mml-node="mtr"]
'
))
{
mrow
.
classList
.
add
(
"
fragment
"
);
}
// unlabeled equations
for
(
let
mrow
of
document
.
querySelectorAll
(
'
.reveal .math-incremental mjx-container svg g[data-mml-node="mtable"]:first-of-type g[data-mml-node="mlabeledtr"]
'
))
{
mrow
.
classList
.
add
(
"
fragment
"
);
}
}
/*
* Inject CSS rules that (i) make SVG equations automatically shrink down to
* fit the enclosing container and (ii) remove pointer events from the
* fit the enclosing container and (ii) remove pointer events from the
* equation parts, such that Reveal's zoom plugin work nicely on equations, too.
*/
function
injectStyle
()
{
const
style
=
document
.
createElement
(
'
style
'
);
style
.
textContent
=
String
.
raw
`
function
injectStyle
()
{
const
style
=
document
.
createElement
(
"
style
"
);
style
.
textContent
=
String
.
raw
`
/* fit equation into container */
mjx-container > svg {
object-fit: contain;
...
...
@@ -139,113 +130,104 @@ let RevealMath = window.RevealMath || (function(){
pointer-events: all;
}
`
;
document
.
head
.
append
(
style
);
document
.
head
.
append
(
style
);
}
return
{
init
:
function
()
{
// remove menu settings, which are stored in localStorage.
// otherwise user could select CHTML renderer, which is not
// installed in decker.
if
(
window
.
localStorage
)
{
window
.
localStorage
.
removeItem
(
"
MathJax-Menu-Settings
"
);
}
// configure through global MathJax object
window
.
MathJax
=
{
loader
:
{
load
:
[
'
[tex]/ams
'
],
typeset
:
false
},
startup
:
{
ready
:
()
=>
{
console
.
log
(
'
mathjax loaded
'
);
//MathJax.startup.defaultReady();
}
},
svg
:
{
scale
:
0.9
,
// global scaling factor for all expressions
minScale
:
.
5
,
// smallest scaling factor to use
matchFontHeight
:
false
,
// true to match ex-height of surrounding font
mtextInheritFont
:
true
,
// true to make mtext elements use surrounding font
merrorInheritFont
:
true
,
// true to make merror text use surrounding font
mathmlSpacing
:
false
,
// true for MathML spacing rules, false for TeX rules
skipAttributes
:
{},
// RFDa and other attributes NOT to copy to the output
exFactor
:
.
5
,
// default size of ex in em units
displayAlign
:
'
center
'
,
// default for indentalign when set to 'auto'
displayIndent
:
'
0
'
,
// default for indentshift when set to 'auto'
fontCache
:
'
none
'
,
// or 'global' or 'none'
localID
:
null
,
// ID to use for local font cache (for single equation processing)
internalSpeechTitles
:
true
,
// insert <title> tags with speech content
titleID
:
0
// initial id number to use for aria-labeledby titles
},
tex
:
{
tags
:
'
ams
'
,
packages
:
{
'
[+]
'
:
[
'
ams
'
]
},
inlineMath
:
[
// start/end delimiter pairs for in-line math
[
'
$
'
,
'
$
'
],
[
'
\\
(
'
,
'
\\
)
'
]
],
displayMath
:
[
// start/end delimiter pairs for display math
[
'
$$
'
,
'
$$
'
],
[
'
\\
[
'
,
'
\\
]
'
]
]
},
options
:
{
enableMenu
:
false
,
// disable assistive-mml, since it messes up speaker notes
menuOptions
:
{
settings
:
{
assistiveMml
:
false
}
},
renderActions
:
{
assistiveMml
:
[]
// disable assistive mathml
}
}
};
// add user-defined Latex macros
let
macros
=
{
fragment
:
[
"
\\
class{fragment}{#1}
"
,
1
]
};
if
(
options
.
macros
)
{
macros
=
Object
.
assign
(
macros
,
options
.
macros
);
}
window
.
MathJax
.
tex
.
macros
=
macros
;
// use promise mechanism to make sure that math typesetting
// is performend before Reveal fires ready-event or
// generates a PDF
return
new
Promise
(
(
resolve
)
=>
{
// load mathjax script
loadScript
(
url
,
()
=>
{
// Typeset followed by an immediate reveal.js layout since
// the typesetting process could affect slide height
window
.
MathJax
.
startup
.
defaultReady
();
MathJax
.
startup
.
promise
.
then
(()
=>
{
console
.
log
(
"
mathjax typeset done
"
);
Reveal
.
layout
();
fixLinks
();
setupMathIncremental
();
injectStyle
();
resolve
();
});
});
});
return
{
init
:
function
()
{
// remove menu settings, which are stored in localStorage.
// otherwise user could select CHTML renderer, which is not
// installed in decker.
if
(
window
.
localStorage
)
{
window
.
localStorage
.
removeItem
(
"
MathJax-Menu-Settings
"
);
}
}
})();
// configure through global MathJax object
window
.
MathJax
=
{
loader
:
{
load
:
[
"
[tex]/ams
"
],
typeset
:
false
,
},
startup
:
{
ready
:
()
=>
{
console
.
log
(
"
mathjax loaded
"
);
//MathJax.startup.defaultReady();
},
},
svg
:
{
scale
:
0.9
,
// global scaling factor for all expressions
minScale
:
0.5
,
// smallest scaling factor to use
matchFontHeight
:
false
,
// true to match ex-height of surrounding font
mtextInheritFont
:
true
,
// true to make mtext elements use surrounding font
merrorInheritFont
:
true
,
// true to make merror text use surrounding font
mathmlSpacing
:
false
,
// true for MathML spacing rules, false for TeX rules
skipAttributes
:
{},
// RFDa and other attributes NOT to copy to the output
exFactor
:
0.5
,
// default size of ex in em units
displayAlign
:
"
center
"
,
// default for indentalign when set to 'auto'
displayIndent
:
"
0
"
,
// default for indentshift when set to 'auto'
fontCache
:
"
none
"
,
// or 'global' or 'none'
localID
:
null
,
// ID to use for local font cache (for single equation processing)
internalSpeechTitles
:
true
,
// insert <title> tags with speech content
titleID
:
0
,
// initial id number to use for aria-labeledby titles
},
tex
:
{
tags
:
"
ams
"
,
packages
:
{
"
[+]
"
:
[
"
ams
"
],
},
inlineMath
:
[
// start/end delimiter pairs for in-line math
[
"
$
"
,
"
$
"
],
[
"
\\
(
"
,
"
\\
)
"
],
],
displayMath
:
[
// start/end delimiter pairs for display math
[
"
$$
"
,
"
$$
"
],
[
"
\\
[
"
,
"
\\
]
"
],
],
},
options
:
{
enableMenu
:
false
,
// disable assistive-mml, since it messes up speaker notes
menuOptions
:
{
settings
:
{
assistiveMml
:
false
,
},
},
renderActions
:
{
assistiveMml
:
[],
// disable assistive mathml
},
},
};
// add user-defined Latex macros
let
macros
=
{
fragment
:
[
"
\\
class{fragment}{#1}
"
,
1
]
};
if
(
options
.
macros
)
{
macros
=
Object
.
assign
(
macros
,
options
.
macros
);
}
window
.
MathJax
.
tex
.
macros
=
macros
;
// use promise mechanism to make sure that math typesetting
// is performend before Reveal fires ready-event or
// generates a PDF
return
new
Promise
((
resolve
)
=>
{
// load mathjax script
loadScript
(
url
,
()
=>
{
// Typeset followed by an immediate reveal.js layout since
// the typesetting process could affect slide height
window
.
MathJax
.
startup
.
defaultReady
();
MathJax
.
startup
.
promise
.
then
(()
=>
{
console
.
log
(
"
mathjax typeset done
"
);
Reveal
.
layout
();
fixLinks
();
setupMathIncremental
();
injectStyle
();
resolve
();
});
});
});
},
};
})();
Reveal
.
registerPlugin
(
'
math
'
,
RevealMath
);
Reveal
.
registerPlugin
(
"
math
"
,
RevealMath
);
resource/template/deck.html
View file @
e894bbad
...
...
@@ -35,7 +35,6 @@ $endif$
<link
rel=
"stylesheet"
href=
"$decker-support-dir$/vendor/reveal/css/reveal.css"
>
<link
rel=
"stylesheet"
href=
"$decker-support-dir$/plugins/whiteboard/whiteboard.css"
>
<link
rel=
"stylesheet"
href=
"$decker-support-dir$/plugins/menu/menu.css"
>
<link
rel=
"stylesheet"
href=
"$decker-support-dir$/geometry/geometry.css"
>
$if(thebelab.enable)$
<link
rel=
"stylesheet"
href=
"$decker-support-dir$/plugins/thebelab/thebelab.css"
>
$endif$
...
...
src/Text/Decker/Filter/Image.hs
View file @
e894bbad
...
...
@@ -98,7 +98,7 @@ transformImages images caption = do
H
.
div
!
A
.
class_
"decker image-row"
$
toHtml
$
map
toHtml
imageRow
H
.
figcaption
captionHtml
language
cls
=
find
(`
elem
`
[
"dot"
,
"gnuplot"
,
"tex"
])
cls
language
cls
=
find
(`
elem
`
[
"plantuml"
,
"dot"
,
"gnuplot"
,
"tex"
])
cls
-- TODO this is incomplete
-- - captions are just swallowed but never rendered.
...
...
@@ -107,6 +107,8 @@ transformCodeBlock :: Block -> [Inline] -> Filter Block
transformCodeBlock
code
@
(
CodeBlock
attr
@
(
_
,
classes
,
_
)
text
)
caption
=
handle
(
blockError
code
)
$
if
|
all
(`
elem
`
classes
)
[
"plantuml"
,
"render"
]
->
runAttr
attr
(
transform
"plantuml"
)
>>=
renderHtml
|
all
(`
elem
`
classes
)
[
"dot"
,
"render"
]
->
runAttr
attr
(
transform
"dot"
)
>>=
renderHtml
|
all
(`
elem
`
classes
)
[
"gnuplot"
,
"render"
]
->
...
...
@@ -365,5 +367,5 @@ renderJavascriptHtml code = do
id
<-
liftIO
randomId
let
anchor
=
"let anchor = document.getElementById(
\"
"
<>
id
<>
"
\"
);
\n
"
return
$
do
H
.
div
!
A
.
id
(
toValue
id
)
!
A
.
class_
"
geometry
"
$
""
H
.
script
!
A
.
class_
"geometry"
!
A
.
type_
"geometry
"
$
toHtml
(
anchor
<>
code
)
H
.
div
!
A
.
id
(
toValue
id
)
!
A
.
class_
"
es6 module anchor
"
$
""
H
.
script
!
A
.
type_
"module"
!
A
.
defer
"
"
$
toHtml
(
anchor
<>
code
)
src/Text/Decker/Filter/Local.hs
View file @
e894bbad
...
...
@@ -61,7 +61,7 @@ svgExt = ["svg"]
yamlExt
=
[
"yaml"
,
"yml"
]
renderExt
=
[
"dot"
,
"gnuplot"
,
"tex"
]
renderExt
=
[
"dot"
,
"gnuplot"
,
"tex"
,
"plantuml"
]