@@ -58,8 +58,19 @@ ]]; list_ordered = [[]]; list_unordered = [[]]; footnote = [[ + @media screen { + a[href].fnref { + text-decoration-style: dashed; + color: @tone(0.7 45); + text-decoration-color: @tone/0.4(0.7 45); + } + a[href]:hover.fnref { + color: @tone(0.9 45); + text-decoration-color: @tone/0.7(0.7 45); + } + } aside.footnote { font-family: 90%; grid-template-columns: 1em 1fr min-content; grid-template-rows: 1fr min-content; @@ -101,8 +112,14 @@ opacity: 100%; pointer-events: all; backdrop-filter: blur(5px); } + } + @media screen and (max-width: calc(@width + 20em)) { + aside.footnote { + left: 1em; + right: 1em; + } } @media print { aside.footnote { display: grid; @@ -148,15 +165,16 @@ text-align:right; grid-row: 1/2; grid-column: 1/2; } - aside.footnote > div.text { + aside.footnote > .text { grid-row: 1/2; grid-column: 2/4; padding-left: 1em; overflow-y: auto; + margin-top: 0; } - aside.footnote > div.text > p:first-child { + aside.footnote > .text > :first-child { margin-top: 0; } ]]; header = [[ @@ -764,8 +782,9 @@ if opts.epub then linkattr['epub:type'] = 'noteref' else addStyle 'footnote' + linkattr.class = 'fnref' end local source, sid, ssec = b.origin:ref(f.ref) local cnc = getSafeID(ssec) .. ' ' .. sid local fn @@ -896,10 +915,10 @@ if next(secnodes) then if doc.secorder[2] then --#secs>1? -- only wrap in a section if >1 section table.insert(ir, tag('section', - {id = getSafeID(sec)}, - secnodes)) + {id = getSafeID(sec)}, + secnodes)) else ir = secnodes end end @@ -1192,14 +1211,35 @@ end for _, fn in ipairs(fnsorted) do local tag = tagproc.toIR.tag - local body = {nodes={}} - local ftir = {} - for l in fn.source:gmatch('([^\n]*)') do - ct.parse_line(l, fn.origin, ftir) + local body + if type(fn.source) == 'table' then + if fn.source.kind == 'resource' then + local fake_embed = { + kind = 'embed'; + rsrc = fn.source; + origin = fn.origin; + mode = 'inline'; + } + local rendered = astproc.toIR.block_renderers.embed( + fake_embed, fn.origin.sec + ) + if not rendered then + fn.origin:fail('unacceptable resource mime type “%s” for footnote target “%s”', fn.source.mime, fn.source.id or '(anonymous)') + end + body = rendered + else + fn.origin:fail('footnote span links to block “%s” of unacceptable kind “%s”', fn.source.kind) + end + else + body = {tag='div',nodes={}} + local ftir = {} + for l in fn.source:gmatch('([^\n]*)') do + ct.parse_line(l, fn.origin, ftir) + end + renderBlocks(ftir,body) end - renderBlocks(ftir,body) local fattr = {id=fn.id} if opts.epub then ---UUUUUUGHHH local npfx = string.format('(%u) ', fn.num) @@ -1218,17 +1258,26 @@ end until false else - body.nodes[1] = {tag='p',attrs={},nodes={npfx}} + if body.tag == 'div' then + body.nodes[1] = {tag='p',attrs={},nodes={npfx}} + elseif body.tag == 'pre' then + body.nodes[1] = npfx .. body.nodes[1] + else + body = {tag='div', nodes = {npfx, body}} + end end fattr['epub:type'] = 'footnote' else fattr.class = 'footnote' end + body.attrs = body.attrs or {} + body.attrs.class = 'text' local note = tag('aside', fattr, opts.epub and body.nodes or { tag('div',{class='number'}, tostring(fn.num)), - tag('div',{class='text'}, body.nodes), + body, +-- tag('div',{class='text'}, body.nodes), tag('a',{href='#0'},'⤫') }) table.insert(ir, note) end