Use latest skylighting; ensure no duplicate ids on code lines.

The line identifiers are built using the code block's identifier
as a prefix. If the code block has null identifier, we use
"cb1", "cb2", etc.

Closes #4031.
This commit is contained in:
John MacFarlane 2017-11-02 16:02:04 -07:00
parent 5df272254d
commit 856587ff63
6 changed files with 24 additions and 13 deletions

View file

@ -320,7 +320,7 @@ library
tagsoup >= 0.13.7 && < 0.15, tagsoup >= 0.13.7 && < 0.15,
base64-bytestring >= 0.1 && < 1.1, base64-bytestring >= 0.1 && < 1.1,
zlib >= 0.5 && < 0.7, zlib >= 0.5 && < 0.7,
skylighting >= 0.4.2 && <0.5, skylighting >= 0.4.3 && <0.5,
data-default >= 0.4 && < 0.8, data-default >= 0.4 && < 0.8,
temporary >= 1.1 && < 1.3, temporary >= 1.1 && < 1.3,
blaze-html >= 0.5 && < 0.10, blaze-html >= 0.5 && < 0.10,

View file

@ -81,12 +81,15 @@ highlight :: SyntaxMap
-> Attr -- ^ Attributes of the CodeBlock -> Attr -- ^ Attributes of the CodeBlock
-> String -- ^ Raw contents of the CodeBlock -> String -- ^ Raw contents of the CodeBlock
-> Either String a -> Either String a
highlight syntaxmap formatter (_, classes, keyvals) rawCode = highlight syntaxmap formatter (ident, classes, keyvals) rawCode =
let firstNum = fromMaybe 1 (safeRead (fromMaybe "1" $ lookup "startFrom" keyvals)) let firstNum = fromMaybe 1 (safeRead (fromMaybe "1" $ lookup "startFrom" keyvals))
fmtOpts = defaultFormatOpts{ fmtOpts = defaultFormatOpts{
startNumber = firstNum, startNumber = firstNum,
numberLines = any (`elem` numberLines = any (`elem`
["number","numberLines", "number-lines"]) classes } ["number","numberLines", "number-lines"]) classes,
lineIdPrefix = if null ident
then mempty
else T.pack (ident ++ "-") }
tokenizeOpts = TokenizerConfig{ syntaxMap = syntaxmap tokenizeOpts = TokenizerConfig{ syntaxMap = syntaxmap
, traceOutput = False } , traceOutput = False }
classes' = map T.pack classes classes' = map T.pack classes

View file

@ -101,6 +101,7 @@ data WriterState = WriterState
, stHtml5 :: Bool -- ^ Use HTML5 , stHtml5 :: Bool -- ^ Use HTML5
, stEPUBVersion :: Maybe EPUBVersion -- ^ EPUB version if for epub , stEPUBVersion :: Maybe EPUBVersion -- ^ EPUB version if for epub
, stSlideVariant :: HTMLSlideVariant , stSlideVariant :: HTMLSlideVariant
, stCodeBlockNum :: Int -- ^ Number of code block
} }
defaultWriterState :: WriterState defaultWriterState :: WriterState
@ -108,7 +109,8 @@ defaultWriterState = WriterState {stNotes= [], stMath = False, stQuotes = False,
stHighlighting = False, stSecNum = [], stHighlighting = False, stSecNum = [],
stElement = False, stHtml5 = False, stElement = False, stHtml5 = False,
stEPUBVersion = Nothing, stEPUBVersion = Nothing,
stSlideVariant = NoSlides} stSlideVariant = NoSlides,
stCodeBlockNum = 0}
-- Helpers to render HTML with the appropriate function. -- Helpers to render HTML with the appropriate function.
@ -703,6 +705,12 @@ blockToHtml _ HorizontalRule = do
html5 <- gets stHtml5 html5 <- gets stHtml5
return $ if html5 then H5.hr else H.hr return $ if html5 then H5.hr else H.hr
blockToHtml opts (CodeBlock (id',classes,keyvals) rawCode) = do blockToHtml opts (CodeBlock (id',classes,keyvals) rawCode) = do
id'' <- if null id'
then do
modify $ \st -> st{ stCodeBlockNum = stCodeBlockNum st + 1 }
codeblocknum <- gets stCodeBlockNum
return ("cb" ++ show codeblocknum)
else return id'
let tolhs = isEnabled Ext_literate_haskell opts && let tolhs = isEnabled Ext_literate_haskell opts &&
any (\c -> map toLower c == "haskell") classes && any (\c -> map toLower c == "haskell") classes &&
any (\c -> map toLower c == "literate") classes any (\c -> map toLower c == "literate") classes
@ -716,7 +724,7 @@ blockToHtml opts (CodeBlock (id',classes,keyvals) rawCode) = do
else rawCode else rawCode
hlCode = if isJust (writerHighlightStyle opts) hlCode = if isJust (writerHighlightStyle opts)
then highlight (writerSyntaxMap opts) formatHtmlBlock then highlight (writerSyntaxMap opts) formatHtmlBlock
(id',classes',keyvals) adjCode (id'',classes',keyvals) adjCode
else Left "" else Left ""
case hlCode of case hlCode of
Left msg -> do Left msg -> do
@ -725,7 +733,7 @@ blockToHtml opts (CodeBlock (id',classes,keyvals) rawCode) = do
addAttrs opts (id',classes,keyvals) addAttrs opts (id',classes,keyvals)
$ H.pre $ H.code $ toHtml adjCode $ H.pre $ H.code $ toHtml adjCode
Right h -> modify (\st -> st{ stHighlighting = True }) >> Right h -> modify (\st -> st{ stHighlighting = True }) >>
addAttrs opts (id',[],keyvals) h addAttrs opts (id'',[],keyvals) h
blockToHtml opts (BlockQuote blocks) = do blockToHtml opts (BlockQuote blocks) = do
-- in S5, treat list in blockquote specially -- in S5, treat list in blockquote specially
-- if default is incremental, make it nonincremental; -- if default is incremental, make it nonincremental;

View file

@ -9,7 +9,7 @@ packages:
extra-deps: extra-deps:
- pandoc-types-1.17.2 - pandoc-types-1.17.2
- hslua-0.9.2 - hslua-0.9.2
- skylighting-0.4.2 - skylighting-0.4.3
- cmark-gfm-0.1.1 - cmark-gfm-0.1.1
- QuickCheck-2.10.0.1 - QuickCheck-2.10.0.1
- tasty-quickcheck-0.9.1 - tasty-quickcheck-0.9.1

View file

@ -72,9 +72,9 @@ code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Infor
<h1 id="lhs-test">lhs test</h1> <h1 id="lhs-test">lhs test</h1>
<p><code>unsplit</code> is an arrow that takes a pair of values and combines them to <p><code>unsplit</code> is an arrow that takes a pair of values and combines them to
return a single value:</p> return a single value:</p>
<pre class="sourceCode literate haskell"><code class="sourceCode haskell"><div class="sourceLine" id="1" href="#1" data-line-number="1"><span class="ot">unsplit ::</span> (<span class="dt">Arrow</span> a) <span class="ot">=&gt;</span> (b <span class="ot">-&gt;</span> c <span class="ot">-&gt;</span> d) <span class="ot">-&gt;</span> a (b, c) d</div> <pre class="sourceCode literate haskell" id="cb1"><code class="sourceCode haskell"><div class="sourceLine" id="cb1-1" data-line-number="cb1-1"><span class="ot">unsplit ::</span> (<span class="dt">Arrow</span> a) <span class="ot">=&gt;</span> (b <span class="ot">-&gt;</span> c <span class="ot">-&gt;</span> d) <span class="ot">-&gt;</span> a (b, c) d</div>
<div class="sourceLine" id="2" href="#2" data-line-number="2">unsplit <span class="fu">=</span> arr <span class="fu">.</span> uncurry</div> <div class="sourceLine" id="cb1-2" data-line-number="cb1-2">unsplit <span class="fu">=</span> arr <span class="fu">.</span> uncurry</div>
<div class="sourceLine" id="3" href="#3" data-line-number="3"> <span class="co">-- arr (\op (x,y) -&gt; x `op` y)</span></div></code></pre> <div class="sourceLine" id="cb1-3" data-line-number="cb1-3"> <span class="co">-- arr (\op (x,y) -&gt; x `op` y)</span></div></code></pre>
<p><code>(***)</code> combines two arrows into a new arrow by running the two arrows on a <p><code>(***)</code> combines two arrows into a new arrow by running the two arrows on a
pair of values (one arrow on the first item of the pair and one arrow on the pair of values (one arrow on the first item of the pair and one arrow on the
second item of the pair).</p> second item of the pair).</p>

View file

@ -72,9 +72,9 @@ code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Infor
<h1 id="lhs-test">lhs test</h1> <h1 id="lhs-test">lhs test</h1>
<p><code>unsplit</code> is an arrow that takes a pair of values and combines them to <p><code>unsplit</code> is an arrow that takes a pair of values and combines them to
return a single value:</p> return a single value:</p>
<pre class="sourceCode literate literatehaskell"><code class="sourceCode literatehaskell"><div class="sourceLine" id="1" href="#1" data-line-number="1"><span class="ot">&gt; unsplit ::</span> (<span class="dt">Arrow</span> a) <span class="ot">=&gt;</span> (b <span class="ot">-&gt;</span> c <span class="ot">-&gt;</span> d) <span class="ot">-&gt;</span> a (b, c) d</div> <pre class="sourceCode literate literatehaskell" id="cb1"><code class="sourceCode literatehaskell"><div class="sourceLine" id="cb1-1" data-line-number="cb1-1"><span class="ot">&gt; unsplit ::</span> (<span class="dt">Arrow</span> a) <span class="ot">=&gt;</span> (b <span class="ot">-&gt;</span> c <span class="ot">-&gt;</span> d) <span class="ot">-&gt;</span> a (b, c) d</div>
<div class="sourceLine" id="2" href="#2" data-line-number="2"><span class="ot">&gt;</span> unsplit <span class="fu">=</span> arr <span class="fu">.</span> uncurry</div> <div class="sourceLine" id="cb1-2" data-line-number="cb1-2"><span class="ot">&gt;</span> unsplit <span class="fu">=</span> arr <span class="fu">.</span> uncurry</div>
<div class="sourceLine" id="3" href="#3" data-line-number="3"><span class="ot">&gt;</span> <span class="co">-- arr (\op (x,y) -&gt; x `op` y)</span></div></code></pre> <div class="sourceLine" id="cb1-3" data-line-number="cb1-3"><span class="ot">&gt;</span> <span class="co">-- arr (\op (x,y) -&gt; x `op` y)</span></div></code></pre>
<p><code>(***)</code> combines two arrows into a new arrow by running the two arrows on a <p><code>(***)</code> combines two arrows into a new arrow by running the two arrows on a
pair of values (one arrow on the first item of the pair and one arrow on the pair of values (one arrow on the first item of the pair and one arrow on the
second item of the pair).</p> second item of the pair).</p>