remove unused extensions
This commit is contained in:
-1704
File diff suppressed because it is too large
Load Diff
Binary file not shown.
-10
File diff suppressed because one or more lines are too long
-7
File diff suppressed because one or more lines are too long
@@ -1,225 +0,0 @@
|
||||
/* cyrillic-ext */
|
||||
@font-face {
|
||||
font-family: "Source Sans Pro";
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
font-display: swap;
|
||||
src: url(./googlefonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ik4zwmhdu3cOWxy40.woff2)
|
||||
format("woff2");
|
||||
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
|
||||
U+FE2E-FE2F;
|
||||
}
|
||||
/* cyrillic */
|
||||
@font-face {
|
||||
font-family: "Source Sans Pro";
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
font-display: swap;
|
||||
src: url(./googlefonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ik4zwkxdu3cOWxy40.woff2)
|
||||
format("woff2");
|
||||
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
/* greek-ext */
|
||||
@font-face {
|
||||
font-family: "Source Sans Pro";
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
font-display: swap;
|
||||
src: url(./googlefonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ik4zwmxdu3cOWxy40.woff2)
|
||||
format("woff2");
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
/* greek */
|
||||
@font-face {
|
||||
font-family: "Source Sans Pro";
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
font-display: swap;
|
||||
src: url(./googlefonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ik4zwlBdu3cOWxy40.woff2)
|
||||
format("woff2");
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: "Source Sans Pro";
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
font-display: swap;
|
||||
src: url(./googlefonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ik4zwmBdu3cOWxy40.woff2)
|
||||
format("woff2");
|
||||
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
|
||||
U+01AF-01B0, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: "Source Sans Pro";
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
font-display: swap;
|
||||
src: url(./googlefonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ik4zwmRdu3cOWxy40.woff2)
|
||||
format("woff2");
|
||||
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,
|
||||
U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: "Source Sans Pro";
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
font-display: swap;
|
||||
src: url(./googlefonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ik4zwlxdu3cOWxw.woff2)
|
||||
format("woff2");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
|
||||
U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
|
||||
U+FEFF, U+FFFD;
|
||||
}
|
||||
/* cyrillic-ext */
|
||||
@font-face {
|
||||
font-family: "Source Sans Pro";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url(./googlefonts/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNa7lujVj9_mf.woff2)
|
||||
format("woff2");
|
||||
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
|
||||
U+FE2E-FE2F;
|
||||
}
|
||||
/* cyrillic */
|
||||
@font-face {
|
||||
font-family: "Source Sans Pro";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url(./googlefonts/6xK3dSBYKcSV-LCoeQqfX1RYOo3qPK7lujVj9_mf.woff2)
|
||||
format("woff2");
|
||||
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
/* greek-ext */
|
||||
@font-face {
|
||||
font-family: "Source Sans Pro";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url(./googlefonts/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNK7lujVj9_mf.woff2)
|
||||
format("woff2");
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
/* greek */
|
||||
@font-face {
|
||||
font-family: "Source Sans Pro";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url(./googlefonts/6xK3dSBYKcSV-LCoeQqfX1RYOo3qO67lujVj9_mf.woff2)
|
||||
format("woff2");
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: "Source Sans Pro";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url(./googlefonts/6xK3dSBYKcSV-LCoeQqfX1RYOo3qN67lujVj9_mf.woff2)
|
||||
format("woff2");
|
||||
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
|
||||
U+01AF-01B0, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: "Source Sans Pro";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url(./googlefonts/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNq7lujVj9_mf.woff2)
|
||||
format("woff2");
|
||||
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,
|
||||
U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: "Source Sans Pro";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url(./googlefonts/6xK3dSBYKcSV-LCoeQqfX1RYOo3qOK7lujVj9w.woff2)
|
||||
format("woff2");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
|
||||
U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
|
||||
U+FEFF, U+FFFD;
|
||||
}
|
||||
/* cyrillic-ext */
|
||||
@font-face {
|
||||
font-family: "Source Sans Pro";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url(./googlefonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmhdu3cOWxy40.woff2)
|
||||
format("woff2");
|
||||
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F,
|
||||
U+FE2E-FE2F;
|
||||
}
|
||||
/* cyrillic */
|
||||
@font-face {
|
||||
font-family: "Source Sans Pro";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url(./googlefonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwkxdu3cOWxy40.woff2)
|
||||
format("woff2");
|
||||
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
/* greek-ext */
|
||||
@font-face {
|
||||
font-family: "Source Sans Pro";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url(./googlefonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmxdu3cOWxy40.woff2)
|
||||
format("woff2");
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
/* greek */
|
||||
@font-face {
|
||||
font-family: "Source Sans Pro";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url(./googlefonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwlBdu3cOWxy40.woff2)
|
||||
format("woff2");
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: "Source Sans Pro";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url(./googlefonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmBdu3cOWxy40.woff2)
|
||||
format("woff2");
|
||||
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
|
||||
U+01AF-01B0, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: "Source Sans Pro";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url(./googlefonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmRdu3cOWxy40.woff2)
|
||||
format("woff2");
|
||||
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,
|
||||
U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: "Source Sans Pro";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url(./googlefonts/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwlxdu3cOWxw.woff2)
|
||||
format("woff2");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
|
||||
U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
|
||||
U+FEFF, U+FFFD;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,8 +0,0 @@
|
||||
title: D2
|
||||
author: Data Intuitive
|
||||
version: 1.1.0
|
||||
quarto-required: ">=1.3"
|
||||
contributes:
|
||||
filters:
|
||||
- d2.lua
|
||||
|
||||
@@ -1,272 +0,0 @@
|
||||
-- Enum for D2Theme
|
||||
local D2Theme = {
|
||||
NeutralDefault = 0,
|
||||
NeutralGrey = 1,
|
||||
FlagshipTerrastruct = 3,
|
||||
CoolClassics = 4,
|
||||
MixedBerryBlue = 5,
|
||||
GrapeSoda = 6,
|
||||
Aubergine = 7,
|
||||
ColorblindClear = 8,
|
||||
VanillaNitroCola = 100,
|
||||
OrangeCreamsicle = 101,
|
||||
ShirelyTemple = 102,
|
||||
EarthTones = 103,
|
||||
EvergladeGreen = 104,
|
||||
ButteredToast = 105,
|
||||
DarkMauve = 200,
|
||||
Terminal = 300,
|
||||
TerminalGrayscale = 301,
|
||||
Origami = 302
|
||||
}
|
||||
|
||||
-- Enum for D2Layout
|
||||
local D2Layout = {
|
||||
dagre = 'dagre',
|
||||
elk = 'elk'
|
||||
}
|
||||
|
||||
-- Enum for D2Format
|
||||
local D2Format = {
|
||||
svg = 'svg',
|
||||
png = 'png',
|
||||
pdf = 'pdf'
|
||||
}
|
||||
-- Enum for Embed mode
|
||||
local EmbedMode = {
|
||||
inline = "inline",
|
||||
link = "link",
|
||||
raw = "raw"
|
||||
}
|
||||
|
||||
-- Helper function to copy a table
|
||||
function copyTable(obj, seen)
|
||||
-- Handle non-tables and previously-seen tables.
|
||||
if type(obj) ~= 'table' then return obj end
|
||||
if seen and seen[obj] then return seen[obj] end
|
||||
|
||||
-- New table; mark it as seen and copy recursively.
|
||||
local s = seen or {}
|
||||
local res = {}
|
||||
s[obj] = res
|
||||
for k, v in pairs(obj) do res[copyTable(k, s)] = copyTable(v, s) end
|
||||
return setmetatable(res, getmetatable(obj))
|
||||
end
|
||||
|
||||
-- Helper function for debugging
|
||||
function dump(o)
|
||||
if type(o) == 'table' then
|
||||
local s = '{ '
|
||||
for k,v in pairs(o) do
|
||||
if type(k) ~= 'number' then k = '"'..k..'"' end
|
||||
s = s .. '['..k..'] = ' .. dump(v) .. ','
|
||||
end
|
||||
return s .. '} '
|
||||
else
|
||||
return tostring(o)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Counter for the diagram files
|
||||
local counter = 0
|
||||
|
||||
local function render_graph(globalOptions)
|
||||
local filter = {
|
||||
CodeBlock = function(cb)
|
||||
-- Check if the CodeBlock has the 'd2' class
|
||||
if not cb.classes:includes('d2') or cb.text == nil then
|
||||
return nil
|
||||
end
|
||||
|
||||
counter = counter + 1
|
||||
|
||||
-- Initialise options table
|
||||
local options = copyTable(globalOptions)
|
||||
|
||||
-- Process codeblock attributes
|
||||
for k, v in pairs(cb.attributes) do
|
||||
options[k] = v
|
||||
end
|
||||
|
||||
-- Transform options
|
||||
if options.theme ~= nil and type(options.theme) == "string" then
|
||||
assert(D2Theme[options.theme] ~= nil, "Invalid theme: " .. options.theme .. ". Options are: " .. dump(D2Theme))
|
||||
options.theme = D2Theme[options.theme]
|
||||
end
|
||||
if options.layout ~= nil and type(options.layout) == "string" then
|
||||
assert(D2Layout[options.layout] ~= nil, "Invalid layout: " .. options.layout .. ". Options are: " .. dump(D2Layout))
|
||||
options.layout = D2Layout[options.layout]
|
||||
end
|
||||
if options.format ~= nil and type(options.format) == "string" then
|
||||
assert(D2Format[options.format] ~= nil, "Invalid format: " .. options.format .. ". Options are: " .. dump(D2Format))
|
||||
options.format = D2Format[options.format]
|
||||
end
|
||||
if options.embed_mode ~= nil and type(options.embed_mode) == "string" then
|
||||
assert(EmbedMode[options.embed_mode] ~= nil, "Invalid embed_mode: " .. options.embed_mode .. ". Options are: " .. dump(EmbedMode))
|
||||
options.embed_mode = EmbedMode[options.embed_mode]
|
||||
end
|
||||
if options.sketch ~= nil and type(options.sketch) == "string" then
|
||||
assert(options.sketch == "true" or options.sketch == "false", "Invalid sketch: " .. options.sketch .. ". Options are: true, false")
|
||||
options.sketch = options.sketch == "true"
|
||||
end
|
||||
if options.pad ~= nil and type(options.pad) == "string" then
|
||||
assert(tonumber(options.pad) ~= nil, "Invalid pad: " .. options.pad .. ". Must be a number")
|
||||
options.pad = tonumber(options.pad)
|
||||
end
|
||||
if options.echo ~= nil and type(options.echo) == "string" then
|
||||
assert(options.echo == "true" or options.echo == "false", "Invalid echo: " .. options.echo .. ". Options are: true, false")
|
||||
options.echo = options.echo == "true"
|
||||
end
|
||||
|
||||
-- Set default filename
|
||||
if options.filename == nil then
|
||||
options.filename = "diagram-" .. counter
|
||||
end
|
||||
|
||||
-- Set the default format to pdf since svg is not supported in PDF output
|
||||
if options.format == D2Format.svg and quarto.doc.is_format("latex") then
|
||||
options.format = D2Format.pdf
|
||||
end
|
||||
-- Set the default embed_mode to link if the quarto format is not html or the figure format is pdf
|
||||
if not quarto.doc.is_format("html") or options.format == D2Format.pdf then
|
||||
options.embed_mode = EmbedMode.link
|
||||
end
|
||||
|
||||
-- Set the default folder to ./images when embed_mode is link
|
||||
if options.folder == nil and options.embed_mode == EmbedMode.link then
|
||||
options.folder = "./images"
|
||||
end
|
||||
|
||||
-- Generate diagram using `d2` CLI utility
|
||||
local result = pandoc.system.with_temporary_directory('svg-convert', function (tmpdir)
|
||||
-- determine path name of input file
|
||||
local inputPath = pandoc.path.join({tmpdir, "temp_" .. counter .. ".txt"})
|
||||
|
||||
-- determine path name of output file
|
||||
local outputPath
|
||||
if options.folder ~= nil then
|
||||
os.execute("mkdir -p " .. options.folder)
|
||||
outputPath = options.folder .. "/" .. options.filename .. "." .. options.format
|
||||
else
|
||||
outputPath = pandoc.path.join({tmpdir, options.filename .. "." .. options.format})
|
||||
end
|
||||
|
||||
-- write graph text to file
|
||||
local tmpFile = io.open(inputPath, "w")
|
||||
if tmpFile == nil then
|
||||
print("Error: Could not open file for writing")
|
||||
return nil
|
||||
end
|
||||
tmpFile:write(cb.text)
|
||||
tmpFile:close()
|
||||
|
||||
-- run d2
|
||||
os.execute(
|
||||
"d2" ..
|
||||
" --theme=" .. options.theme ..
|
||||
" --layout=" .. options.layout ..
|
||||
" --sketch=" .. tostring(options.sketch) ..
|
||||
" --pad=" .. options.pad ..
|
||||
" " .. inputPath ..
|
||||
" " .. outputPath
|
||||
)
|
||||
|
||||
if options.embed_mode == EmbedMode.link then
|
||||
return outputPath
|
||||
else
|
||||
local file = io.open(outputPath, "rb")
|
||||
local data
|
||||
if file then
|
||||
data = file:read('*all')
|
||||
file:close()
|
||||
end
|
||||
os.remove(outputPath)
|
||||
|
||||
if options.embed_mode == EmbedMode.raw then
|
||||
return data
|
||||
elseif options.embed_mode == EmbedMode.inline then
|
||||
dump(options)
|
||||
|
||||
if options.format == "svg" then
|
||||
return "data:image/svg+xml;base64," .. quarto.base64.encode(data)
|
||||
elseif options.format == "png" then
|
||||
return "data:image/png;base64," .. quarto.base64.encode(data)
|
||||
else
|
||||
print("Error: Unsupported format")
|
||||
return nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Read the generated output into a Pandoc Image element
|
||||
local output
|
||||
if options.embed_mode == EmbedMode.raw then
|
||||
output = pandoc.Div({pandoc.RawInline("html", result)})
|
||||
|
||||
if options.width ~= nil then
|
||||
output.attributes.style = "width: " .. options.width .. ";"
|
||||
end
|
||||
if options.height ~= nil then
|
||||
output.attributes.style = output.attributes.style .. "height: " .. options.height .. ";"
|
||||
end
|
||||
|
||||
else
|
||||
local image = pandoc.Image({}, result)
|
||||
|
||||
-- Set the width and height attributes, if they exist
|
||||
if options.width ~= nil then
|
||||
image.attributes.width = options.width
|
||||
end
|
||||
|
||||
if options.height ~= nil then
|
||||
image.attributes.height = options.height
|
||||
end
|
||||
|
||||
if options.caption ~= '' then
|
||||
image.caption = pandoc.Str(options.caption)
|
||||
end
|
||||
|
||||
output = pandoc.Para({image})
|
||||
end
|
||||
|
||||
-- Wrap the Image element in a Para element and return it
|
||||
if options.echo then
|
||||
local codeBlock = pandoc.CodeBlock(cb.text, cb.attr)
|
||||
output = pandoc.Div({codeBlock, output})
|
||||
end
|
||||
return output
|
||||
end
|
||||
}
|
||||
return filter
|
||||
end
|
||||
|
||||
|
||||
function Pandoc(doc)
|
||||
|
||||
local options = {
|
||||
theme = D2Theme.NeutralDefault,
|
||||
layout = D2Layout.dagre,
|
||||
format = D2Format.svg,
|
||||
sketch = false,
|
||||
pad = 100,
|
||||
folder = nil,
|
||||
filename = nil,
|
||||
caption = '',
|
||||
width = nil,
|
||||
height = nil,
|
||||
echo = false,
|
||||
embed_mode = "inline"
|
||||
}
|
||||
|
||||
-- Process global attributes
|
||||
local globalOptions = doc.meta["d2"]
|
||||
if type(globalOptions) == "table" then
|
||||
for k, v in pairs(globalOptions) do
|
||||
options[k] = pandoc.utils.stringify(v)
|
||||
end
|
||||
end
|
||||
|
||||
return doc:walk(render_graph(options))
|
||||
end
|
||||
@@ -1,6 +0,0 @@
|
||||
title: Qrcode
|
||||
author: Jannik Buhr
|
||||
version: 0.0.1
|
||||
contributes:
|
||||
shortcodes:
|
||||
- qrcode.lua
|
||||
@@ -1,614 +0,0 @@
|
||||
/**
|
||||
* @fileoverview
|
||||
* - Using the 'QRCode for Javascript library'
|
||||
* - Fixed dataset of 'QRCode for Javascript library' for support full-spec.
|
||||
* - this library has no dependencies.
|
||||
*
|
||||
* @author davidshimjs
|
||||
* @see <a href="http://www.d-project.com/" target="_blank">http://www.d-project.com/</a>
|
||||
* @see <a href="http://jeromeetienne.github.com/jquery-qrcode/" target="_blank">http://jeromeetienne.github.com/jquery-qrcode/</a>
|
||||
*/
|
||||
var QRCode;
|
||||
|
||||
(function () {
|
||||
//---------------------------------------------------------------------
|
||||
// QRCode for JavaScript
|
||||
//
|
||||
// Copyright (c) 2009 Kazuhiko Arase
|
||||
//
|
||||
// URL: http://www.d-project.com/
|
||||
//
|
||||
// Licensed under the MIT license:
|
||||
// http://www.opensource.org/licenses/mit-license.php
|
||||
//
|
||||
// The word "QR Code" is registered trademark of
|
||||
// DENSO WAVE INCORPORATED
|
||||
// http://www.denso-wave.com/qrcode/faqpatent-e.html
|
||||
//
|
||||
//---------------------------------------------------------------------
|
||||
function QR8bitByte(data) {
|
||||
this.mode = QRMode.MODE_8BIT_BYTE;
|
||||
this.data = data;
|
||||
this.parsedData = [];
|
||||
|
||||
// Added to support UTF-8 Characters
|
||||
for (var i = 0, l = this.data.length; i < l; i++) {
|
||||
var byteArray = [];
|
||||
var code = this.data.charCodeAt(i);
|
||||
|
||||
if (code > 0x10000) {
|
||||
byteArray[0] = 0xF0 | ((code & 0x1C0000) >>> 18);
|
||||
byteArray[1] = 0x80 | ((code & 0x3F000) >>> 12);
|
||||
byteArray[2] = 0x80 | ((code & 0xFC0) >>> 6);
|
||||
byteArray[3] = 0x80 | (code & 0x3F);
|
||||
} else if (code > 0x800) {
|
||||
byteArray[0] = 0xE0 | ((code & 0xF000) >>> 12);
|
||||
byteArray[1] = 0x80 | ((code & 0xFC0) >>> 6);
|
||||
byteArray[2] = 0x80 | (code & 0x3F);
|
||||
} else if (code > 0x80) {
|
||||
byteArray[0] = 0xC0 | ((code & 0x7C0) >>> 6);
|
||||
byteArray[1] = 0x80 | (code & 0x3F);
|
||||
} else {
|
||||
byteArray[0] = code;
|
||||
}
|
||||
|
||||
this.parsedData.push(byteArray);
|
||||
}
|
||||
|
||||
this.parsedData = Array.prototype.concat.apply([], this.parsedData);
|
||||
|
||||
if (this.parsedData.length != this.data.length) {
|
||||
this.parsedData.unshift(191);
|
||||
this.parsedData.unshift(187);
|
||||
this.parsedData.unshift(239);
|
||||
}
|
||||
}
|
||||
|
||||
QR8bitByte.prototype = {
|
||||
getLength: function (buffer) {
|
||||
return this.parsedData.length;
|
||||
},
|
||||
write: function (buffer) {
|
||||
for (var i = 0, l = this.parsedData.length; i < l; i++) {
|
||||
buffer.put(this.parsedData[i], 8);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function QRCodeModel(typeNumber, errorCorrectLevel) {
|
||||
this.typeNumber = typeNumber;
|
||||
this.errorCorrectLevel = errorCorrectLevel;
|
||||
this.modules = null;
|
||||
this.moduleCount = 0;
|
||||
this.dataCache = null;
|
||||
this.dataList = [];
|
||||
}
|
||||
|
||||
QRCodeModel.prototype={addData:function(data){var newData=new QR8bitByte(data);this.dataList.push(newData);this.dataCache=null;},isDark:function(row,col){if(row<0||this.moduleCount<=row||col<0||this.moduleCount<=col){throw new Error(row+","+col);}
|
||||
return this.modules[row][col];},getModuleCount:function(){return this.moduleCount;},make:function(){this.makeImpl(false,this.getBestMaskPattern());},makeImpl:function(test,maskPattern){this.moduleCount=this.typeNumber*4+17;this.modules=new Array(this.moduleCount);for(var row=0;row<this.moduleCount;row++){this.modules[row]=new Array(this.moduleCount);for(var col=0;col<this.moduleCount;col++){this.modules[row][col]=null;}}
|
||||
this.setupPositionProbePattern(0,0);this.setupPositionProbePattern(this.moduleCount-7,0);this.setupPositionProbePattern(0,this.moduleCount-7);this.setupPositionAdjustPattern();this.setupTimingPattern();this.setupTypeInfo(test,maskPattern);if(this.typeNumber>=7){this.setupTypeNumber(test);}
|
||||
if(this.dataCache==null){this.dataCache=QRCodeModel.createData(this.typeNumber,this.errorCorrectLevel,this.dataList);}
|
||||
this.mapData(this.dataCache,maskPattern);},setupPositionProbePattern:function(row,col){for(var r=-1;r<=7;r++){if(row+r<=-1||this.moduleCount<=row+r)continue;for(var c=-1;c<=7;c++){if(col+c<=-1||this.moduleCount<=col+c)continue;if((0<=r&&r<=6&&(c==0||c==6))||(0<=c&&c<=6&&(r==0||r==6))||(2<=r&&r<=4&&2<=c&&c<=4)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}},getBestMaskPattern:function(){var minLostPoint=0;var pattern=0;for(var i=0;i<8;i++){this.makeImpl(true,i);var lostPoint=QRUtil.getLostPoint(this);if(i==0||minLostPoint>lostPoint){minLostPoint=lostPoint;pattern=i;}}
|
||||
return pattern;},createMovieClip:function(target_mc,instance_name,depth){var qr_mc=target_mc.createEmptyMovieClip(instance_name,depth);var cs=1;this.make();for(var row=0;row<this.modules.length;row++){var y=row*cs;for(var col=0;col<this.modules[row].length;col++){var x=col*cs;var dark=this.modules[row][col];if(dark){qr_mc.beginFill(0,100);qr_mc.moveTo(x,y);qr_mc.lineTo(x+cs,y);qr_mc.lineTo(x+cs,y+cs);qr_mc.lineTo(x,y+cs);qr_mc.endFill();}}}
|
||||
return qr_mc;},setupTimingPattern:function(){for(var r=8;r<this.moduleCount-8;r++){if(this.modules[r][6]!=null){continue;}
|
||||
this.modules[r][6]=(r%2==0);}
|
||||
for(var c=8;c<this.moduleCount-8;c++){if(this.modules[6][c]!=null){continue;}
|
||||
this.modules[6][c]=(c%2==0);}},setupPositionAdjustPattern:function(){var pos=QRUtil.getPatternPosition(this.typeNumber);for(var i=0;i<pos.length;i++){for(var j=0;j<pos.length;j++){var row=pos[i];var col=pos[j];if(this.modules[row][col]!=null){continue;}
|
||||
for(var r=-2;r<=2;r++){for(var c=-2;c<=2;c++){if(r==-2||r==2||c==-2||c==2||(r==0&&c==0)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}}}},setupTypeNumber:function(test){var bits=QRUtil.getBCHTypeNumber(this.typeNumber);for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[Math.floor(i/3)][i%3+this.moduleCount-8-3]=mod;}
|
||||
for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[i%3+this.moduleCount-8-3][Math.floor(i/3)]=mod;}},setupTypeInfo:function(test,maskPattern){var data=(this.errorCorrectLevel<<3)|maskPattern;var bits=QRUtil.getBCHTypeInfo(data);for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<6){this.modules[i][8]=mod;}else if(i<8){this.modules[i+1][8]=mod;}else{this.modules[this.moduleCount-15+i][8]=mod;}}
|
||||
for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<8){this.modules[8][this.moduleCount-i-1]=mod;}else if(i<9){this.modules[8][15-i-1+1]=mod;}else{this.modules[8][15-i-1]=mod;}}
|
||||
this.modules[this.moduleCount-8][8]=(!test);},mapData:function(data,maskPattern){var inc=-1;var row=this.moduleCount-1;var bitIndex=7;var byteIndex=0;for(var col=this.moduleCount-1;col>0;col-=2){if(col==6)col--;while(true){for(var c=0;c<2;c++){if(this.modules[row][col-c]==null){var dark=false;if(byteIndex<data.length){dark=(((data[byteIndex]>>>bitIndex)&1)==1);}
|
||||
var mask=QRUtil.getMask(maskPattern,row,col-c);if(mask){dark=!dark;}
|
||||
this.modules[row][col-c]=dark;bitIndex--;if(bitIndex==-1){byteIndex++;bitIndex=7;}}}
|
||||
row+=inc;if(row<0||this.moduleCount<=row){row-=inc;inc=-inc;break;}}}}};QRCodeModel.PAD0=0xEC;QRCodeModel.PAD1=0x11;QRCodeModel.createData=function(typeNumber,errorCorrectLevel,dataList){var rsBlocks=QRRSBlock.getRSBlocks(typeNumber,errorCorrectLevel);var buffer=new QRBitBuffer();for(var i=0;i<dataList.length;i++){var data=dataList[i];buffer.put(data.mode,4);buffer.put(data.getLength(),QRUtil.getLengthInBits(data.mode,typeNumber));data.write(buffer);}
|
||||
var totalDataCount=0;for(var i=0;i<rsBlocks.length;i++){totalDataCount+=rsBlocks[i].dataCount;}
|
||||
if(buffer.getLengthInBits()>totalDataCount*8){throw new Error("code length overflow. ("
|
||||
+buffer.getLengthInBits()
|
||||
+">"
|
||||
+totalDataCount*8
|
||||
+")");}
|
||||
if(buffer.getLengthInBits()+4<=totalDataCount*8){buffer.put(0,4);}
|
||||
while(buffer.getLengthInBits()%8!=0){buffer.putBit(false);}
|
||||
while(true){if(buffer.getLengthInBits()>=totalDataCount*8){break;}
|
||||
buffer.put(QRCodeModel.PAD0,8);if(buffer.getLengthInBits()>=totalDataCount*8){break;}
|
||||
buffer.put(QRCodeModel.PAD1,8);}
|
||||
return QRCodeModel.createBytes(buffer,rsBlocks);};QRCodeModel.createBytes=function(buffer,rsBlocks){var offset=0;var maxDcCount=0;var maxEcCount=0;var dcdata=new Array(rsBlocks.length);var ecdata=new Array(rsBlocks.length);for(var r=0;r<rsBlocks.length;r++){var dcCount=rsBlocks[r].dataCount;var ecCount=rsBlocks[r].totalCount-dcCount;maxDcCount=Math.max(maxDcCount,dcCount);maxEcCount=Math.max(maxEcCount,ecCount);dcdata[r]=new Array(dcCount);for(var i=0;i<dcdata[r].length;i++){dcdata[r][i]=0xff&buffer.buffer[i+offset];}
|
||||
offset+=dcCount;var rsPoly=QRUtil.getErrorCorrectPolynomial(ecCount);var rawPoly=new QRPolynomial(dcdata[r],rsPoly.getLength()-1);var modPoly=rawPoly.mod(rsPoly);ecdata[r]=new Array(rsPoly.getLength()-1);for(var i=0;i<ecdata[r].length;i++){var modIndex=i+modPoly.getLength()-ecdata[r].length;ecdata[r][i]=(modIndex>=0)?modPoly.get(modIndex):0;}}
|
||||
var totalCodeCount=0;for(var i=0;i<rsBlocks.length;i++){totalCodeCount+=rsBlocks[i].totalCount;}
|
||||
var data=new Array(totalCodeCount);var index=0;for(var i=0;i<maxDcCount;i++){for(var r=0;r<rsBlocks.length;r++){if(i<dcdata[r].length){data[index++]=dcdata[r][i];}}}
|
||||
for(var i=0;i<maxEcCount;i++){for(var r=0;r<rsBlocks.length;r++){if(i<ecdata[r].length){data[index++]=ecdata[r][i];}}}
|
||||
return data;};var QRMode={MODE_NUMBER:1<<0,MODE_ALPHA_NUM:1<<1,MODE_8BIT_BYTE:1<<2,MODE_KANJI:1<<3};var QRErrorCorrectLevel={L:1,M:0,Q:3,H:2};var QRMaskPattern={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7};var QRUtil={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:(1<<10)|(1<<8)|(1<<5)|(1<<4)|(1<<2)|(1<<1)|(1<<0),G18:(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8)|(1<<5)|(1<<2)|(1<<0),G15_MASK:(1<<14)|(1<<12)|(1<<10)|(1<<4)|(1<<1),getBCHTypeInfo:function(data){var d=data<<10;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)>=0){d^=(QRUtil.G15<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)));}
|
||||
return((data<<10)|d)^QRUtil.G15_MASK;},getBCHTypeNumber:function(data){var d=data<<12;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)>=0){d^=(QRUtil.G18<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)));}
|
||||
return(data<<12)|d;},getBCHDigit:function(data){var digit=0;while(data!=0){digit++;data>>>=1;}
|
||||
return digit;},getPatternPosition:function(typeNumber){return QRUtil.PATTERN_POSITION_TABLE[typeNumber-1];},getMask:function(maskPattern,i,j){switch(maskPattern){case QRMaskPattern.PATTERN000:return(i+j)%2==0;case QRMaskPattern.PATTERN001:return i%2==0;case QRMaskPattern.PATTERN010:return j%3==0;case QRMaskPattern.PATTERN011:return(i+j)%3==0;case QRMaskPattern.PATTERN100:return(Math.floor(i/2)+Math.floor(j/3))%2==0;case QRMaskPattern.PATTERN101:return(i*j)%2+(i*j)%3==0;case QRMaskPattern.PATTERN110:return((i*j)%2+(i*j)%3)%2==0;case QRMaskPattern.PATTERN111:return((i*j)%3+(i+j)%2)%2==0;default:throw new Error("bad maskPattern:"+maskPattern);}},getErrorCorrectPolynomial:function(errorCorrectLength){var a=new QRPolynomial([1],0);for(var i=0;i<errorCorrectLength;i++){a=a.multiply(new QRPolynomial([1,QRMath.gexp(i)],0));}
|
||||
return a;},getLengthInBits:function(mode,type){if(1<=type&&type<10){switch(mode){case QRMode.MODE_NUMBER:return 10;case QRMode.MODE_ALPHA_NUM:return 9;case QRMode.MODE_8BIT_BYTE:return 8;case QRMode.MODE_KANJI:return 8;default:throw new Error("mode:"+mode);}}else if(type<27){switch(mode){case QRMode.MODE_NUMBER:return 12;case QRMode.MODE_ALPHA_NUM:return 11;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 10;default:throw new Error("mode:"+mode);}}else if(type<41){switch(mode){case QRMode.MODE_NUMBER:return 14;case QRMode.MODE_ALPHA_NUM:return 13;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 12;default:throw new Error("mode:"+mode);}}else{throw new Error("type:"+type);}},getLostPoint:function(qrCode){var moduleCount=qrCode.getModuleCount();var lostPoint=0;for(var row=0;row<moduleCount;row++){for(var col=0;col<moduleCount;col++){var sameCount=0;var dark=qrCode.isDark(row,col);for(var r=-1;r<=1;r++){if(row+r<0||moduleCount<=row+r){continue;}
|
||||
for(var c=-1;c<=1;c++){if(col+c<0||moduleCount<=col+c){continue;}
|
||||
if(r==0&&c==0){continue;}
|
||||
if(dark==qrCode.isDark(row+r,col+c)){sameCount++;}}}
|
||||
if(sameCount>5){lostPoint+=(3+sameCount-5);}}}
|
||||
for(var row=0;row<moduleCount-1;row++){for(var col=0;col<moduleCount-1;col++){var count=0;if(qrCode.isDark(row,col))count++;if(qrCode.isDark(row+1,col))count++;if(qrCode.isDark(row,col+1))count++;if(qrCode.isDark(row+1,col+1))count++;if(count==0||count==4){lostPoint+=3;}}}
|
||||
for(var row=0;row<moduleCount;row++){for(var col=0;col<moduleCount-6;col++){if(qrCode.isDark(row,col)&&!qrCode.isDark(row,col+1)&&qrCode.isDark(row,col+2)&&qrCode.isDark(row,col+3)&&qrCode.isDark(row,col+4)&&!qrCode.isDark(row,col+5)&&qrCode.isDark(row,col+6)){lostPoint+=40;}}}
|
||||
for(var col=0;col<moduleCount;col++){for(var row=0;row<moduleCount-6;row++){if(qrCode.isDark(row,col)&&!qrCode.isDark(row+1,col)&&qrCode.isDark(row+2,col)&&qrCode.isDark(row+3,col)&&qrCode.isDark(row+4,col)&&!qrCode.isDark(row+5,col)&&qrCode.isDark(row+6,col)){lostPoint+=40;}}}
|
||||
var darkCount=0;for(var col=0;col<moduleCount;col++){for(var row=0;row<moduleCount;row++){if(qrCode.isDark(row,col)){darkCount++;}}}
|
||||
var ratio=Math.abs(100*darkCount/moduleCount/moduleCount-50)/5;lostPoint+=ratio*10;return lostPoint;}};var QRMath={glog:function(n){if(n<1){throw new Error("glog("+n+")");}
|
||||
return QRMath.LOG_TABLE[n];},gexp:function(n){while(n<0){n+=255;}
|
||||
while(n>=256){n-=255;}
|
||||
return QRMath.EXP_TABLE[n];},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)};for(var i=0;i<8;i++){QRMath.EXP_TABLE[i]=1<<i;}
|
||||
for(var i=8;i<256;i++){QRMath.EXP_TABLE[i]=QRMath.EXP_TABLE[i-4]^QRMath.EXP_TABLE[i-5]^QRMath.EXP_TABLE[i-6]^QRMath.EXP_TABLE[i-8];}
|
||||
for(var i=0;i<255;i++){QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]]=i;}
|
||||
function QRPolynomial(num,shift){if(num.length==undefined){throw new Error(num.length+"/"+shift);}
|
||||
var offset=0;while(offset<num.length&&num[offset]==0){offset++;}
|
||||
this.num=new Array(num.length-offset+shift);for(var i=0;i<num.length-offset;i++){this.num[i]=num[i+offset];}}
|
||||
QRPolynomial.prototype={get:function(index){return this.num[index];},getLength:function(){return this.num.length;},multiply:function(e){var num=new Array(this.getLength()+e.getLength()-1);for(var i=0;i<this.getLength();i++){for(var j=0;j<e.getLength();j++){num[i+j]^=QRMath.gexp(QRMath.glog(this.get(i))+QRMath.glog(e.get(j)));}}
|
||||
return new QRPolynomial(num,0);},mod:function(e){if(this.getLength()-e.getLength()<0){return this;}
|
||||
var ratio=QRMath.glog(this.get(0))-QRMath.glog(e.get(0));var num=new Array(this.getLength());for(var i=0;i<this.getLength();i++){num[i]=this.get(i);}
|
||||
for(var i=0;i<e.getLength();i++){num[i]^=QRMath.gexp(QRMath.glog(e.get(i))+ratio);}
|
||||
return new QRPolynomial(num,0).mod(e);}};function QRRSBlock(totalCount,dataCount){this.totalCount=totalCount;this.dataCount=dataCount;}
|
||||
QRRSBlock.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]];QRRSBlock.getRSBlocks=function(typeNumber,errorCorrectLevel){var rsBlock=QRRSBlock.getRsBlockTable(typeNumber,errorCorrectLevel);if(rsBlock==undefined){throw new Error("bad rs block @ typeNumber:"+typeNumber+"/errorCorrectLevel:"+errorCorrectLevel);}
|
||||
var length=rsBlock.length/3;var list=[];for(var i=0;i<length;i++){var count=rsBlock[i*3+0];var totalCount=rsBlock[i*3+1];var dataCount=rsBlock[i*3+2];for(var j=0;j<count;j++){list.push(new QRRSBlock(totalCount,dataCount));}}
|
||||
return list;};QRRSBlock.getRsBlockTable=function(typeNumber,errorCorrectLevel){switch(errorCorrectLevel){case QRErrorCorrectLevel.L:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+0];case QRErrorCorrectLevel.M:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+1];case QRErrorCorrectLevel.Q:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+2];case QRErrorCorrectLevel.H:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+3];default:return undefined;}};function QRBitBuffer(){this.buffer=[];this.length=0;}
|
||||
QRBitBuffer.prototype={get:function(index){var bufIndex=Math.floor(index/8);return((this.buffer[bufIndex]>>>(7-index%8))&1)==1;},put:function(num,length){for(var i=0;i<length;i++){this.putBit(((num>>>(length-i-1))&1)==1);}},getLengthInBits:function(){return this.length;},putBit:function(bit){var bufIndex=Math.floor(this.length/8);if(this.buffer.length<=bufIndex){this.buffer.push(0);}
|
||||
if(bit){this.buffer[bufIndex]|=(0x80>>>(this.length%8));}
|
||||
this.length++;}};var QRCodeLimitLength=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]];
|
||||
|
||||
function _isSupportCanvas() {
|
||||
return typeof CanvasRenderingContext2D != "undefined";
|
||||
}
|
||||
|
||||
// android 2.x doesn't support Data-URI spec
|
||||
function _getAndroid() {
|
||||
var android = false;
|
||||
var sAgent = navigator.userAgent;
|
||||
|
||||
if (/android/i.test(sAgent)) { // android
|
||||
android = true;
|
||||
var aMat = sAgent.toString().match(/android ([0-9]\.[0-9])/i);
|
||||
|
||||
if (aMat && aMat[1]) {
|
||||
android = parseFloat(aMat[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return android;
|
||||
}
|
||||
|
||||
var svgDrawer = (function() {
|
||||
|
||||
var Drawing = function (el, htOption) {
|
||||
this._el = el;
|
||||
this._htOption = htOption;
|
||||
};
|
||||
|
||||
Drawing.prototype.draw = function (oQRCode) {
|
||||
var _htOption = this._htOption;
|
||||
var _el = this._el;
|
||||
var nCount = oQRCode.getModuleCount();
|
||||
var nWidth = Math.floor(_htOption.width / nCount);
|
||||
var nHeight = Math.floor(_htOption.height / nCount);
|
||||
|
||||
this.clear();
|
||||
|
||||
function makeSVG(tag, attrs) {
|
||||
var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
|
||||
for (var k in attrs)
|
||||
if (attrs.hasOwnProperty(k)) el.setAttribute(k, attrs[k]);
|
||||
return el;
|
||||
}
|
||||
|
||||
var svg = makeSVG("svg" , {'viewBox': '0 0 ' + String(nCount) + " " + String(nCount), 'width': '100%', 'height': '100%', 'fill': _htOption.colorLight});
|
||||
svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
|
||||
_el.appendChild(svg);
|
||||
|
||||
svg.appendChild(makeSVG("rect", {"fill": _htOption.colorLight, "width": "100%", "height": "100%"}));
|
||||
svg.appendChild(makeSVG("rect", {"fill": _htOption.colorDark, "width": "1", "height": "1", "id": "template"}));
|
||||
|
||||
for (var row = 0; row < nCount; row++) {
|
||||
for (var col = 0; col < nCount; col++) {
|
||||
if (oQRCode.isDark(row, col)) {
|
||||
var child = makeSVG("use", {"x": String(col), "y": String(row)});
|
||||
child.setAttributeNS("http://www.w3.org/1999/xlink", "href", "#template")
|
||||
svg.appendChild(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
Drawing.prototype.clear = function () {
|
||||
while (this._el.hasChildNodes())
|
||||
this._el.removeChild(this._el.lastChild);
|
||||
};
|
||||
return Drawing;
|
||||
})();
|
||||
|
||||
var useSVG = document.documentElement.tagName.toLowerCase() === "svg";
|
||||
|
||||
// Drawing in DOM by using Table tag
|
||||
var Drawing = useSVG ? svgDrawer : !_isSupportCanvas() ? (function () {
|
||||
var Drawing = function (el, htOption) {
|
||||
this._el = el;
|
||||
this._htOption = htOption;
|
||||
};
|
||||
|
||||
/**
|
||||
* Draw the QRCode
|
||||
*
|
||||
* @param {QRCode} oQRCode
|
||||
*/
|
||||
Drawing.prototype.draw = function (oQRCode) {
|
||||
var _htOption = this._htOption;
|
||||
var _el = this._el;
|
||||
var nCount = oQRCode.getModuleCount();
|
||||
var nWidth = Math.floor(_htOption.width / nCount);
|
||||
var nHeight = Math.floor(_htOption.height / nCount);
|
||||
var aHTML = ['<table style="border:0;border-collapse:collapse;">'];
|
||||
|
||||
for (var row = 0; row < nCount; row++) {
|
||||
aHTML.push('<tr>');
|
||||
|
||||
for (var col = 0; col < nCount; col++) {
|
||||
aHTML.push('<td style="border:0;border-collapse:collapse;padding:0;margin:0;width:' + nWidth + 'px;height:' + nHeight + 'px;background-color:' + (oQRCode.isDark(row, col) ? _htOption.colorDark : _htOption.colorLight) + ';"></td>');
|
||||
}
|
||||
|
||||
aHTML.push('</tr>');
|
||||
}
|
||||
|
||||
aHTML.push('</table>');
|
||||
_el.innerHTML = aHTML.join('');
|
||||
|
||||
// Fix the margin values as real size.
|
||||
var elTable = _el.childNodes[0];
|
||||
var nLeftMarginTable = (_htOption.width - elTable.offsetWidth) / 2;
|
||||
var nTopMarginTable = (_htOption.height - elTable.offsetHeight) / 2;
|
||||
|
||||
if (nLeftMarginTable > 0 && nTopMarginTable > 0) {
|
||||
elTable.style.margin = nTopMarginTable + "px " + nLeftMarginTable + "px";
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear the QRCode
|
||||
*/
|
||||
Drawing.prototype.clear = function () {
|
||||
this._el.innerHTML = '';
|
||||
};
|
||||
|
||||
return Drawing;
|
||||
})() : (function () { // Drawing in Canvas
|
||||
function _onMakeImage() {
|
||||
this._elImage.src = this._elCanvas.toDataURL("image/png");
|
||||
this._elImage.style.display = "block";
|
||||
this._elCanvas.style.display = "none";
|
||||
}
|
||||
|
||||
// Android 2.1 bug workaround
|
||||
// http://code.google.com/p/android/issues/detail?id=5141
|
||||
if (this._android && this._android <= 2.1) {
|
||||
var factor = 1 / window.devicePixelRatio;
|
||||
var drawImage = CanvasRenderingContext2D.prototype.drawImage;
|
||||
CanvasRenderingContext2D.prototype.drawImage = function (image, sx, sy, sw, sh, dx, dy, dw, dh) {
|
||||
if (("nodeName" in image) && /img/i.test(image.nodeName)) {
|
||||
for (var i = arguments.length - 1; i >= 1; i--) {
|
||||
arguments[i] = arguments[i] * factor;
|
||||
}
|
||||
} else if (typeof dw == "undefined") {
|
||||
arguments[1] *= factor;
|
||||
arguments[2] *= factor;
|
||||
arguments[3] *= factor;
|
||||
arguments[4] *= factor;
|
||||
}
|
||||
|
||||
drawImage.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the user's browser supports Data URI or not
|
||||
*
|
||||
* @private
|
||||
* @param {Function} fSuccess Occurs if it supports Data URI
|
||||
* @param {Function} fFail Occurs if it doesn't support Data URI
|
||||
*/
|
||||
function _safeSetDataURI(fSuccess, fFail) {
|
||||
var self = this;
|
||||
self._fFail = fFail;
|
||||
self._fSuccess = fSuccess;
|
||||
|
||||
// Check it just once
|
||||
if (self._bSupportDataURI === null) {
|
||||
var el = document.createElement("img");
|
||||
var fOnError = function() {
|
||||
self._bSupportDataURI = false;
|
||||
|
||||
if (self._fFail) {
|
||||
self._fFail.call(self);
|
||||
}
|
||||
};
|
||||
var fOnSuccess = function() {
|
||||
self._bSupportDataURI = true;
|
||||
|
||||
if (self._fSuccess) {
|
||||
self._fSuccess.call(self);
|
||||
}
|
||||
};
|
||||
|
||||
el.onabort = fOnError;
|
||||
el.onerror = fOnError;
|
||||
el.onload = fOnSuccess;
|
||||
el.src = "data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="; // the Image contains 1px data.
|
||||
return;
|
||||
} else if (self._bSupportDataURI === true && self._fSuccess) {
|
||||
self._fSuccess.call(self);
|
||||
} else if (self._bSupportDataURI === false && self._fFail) {
|
||||
self._fFail.call(self);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Drawing QRCode by using canvas
|
||||
*
|
||||
* @constructor
|
||||
* @param {HTMLElement} el
|
||||
* @param {Object} htOption QRCode Options
|
||||
*/
|
||||
var Drawing = function (el, htOption) {
|
||||
this._bIsPainted = false;
|
||||
this._android = _getAndroid();
|
||||
|
||||
this._htOption = htOption;
|
||||
this._elCanvas = document.createElement("canvas");
|
||||
this._elCanvas.width = htOption.width;
|
||||
this._elCanvas.height = htOption.height;
|
||||
el.appendChild(this._elCanvas);
|
||||
this._el = el;
|
||||
this._oContext = this._elCanvas.getContext("2d");
|
||||
this._bIsPainted = false;
|
||||
this._elImage = document.createElement("img");
|
||||
this._elImage.alt = "Scan me!";
|
||||
this._elImage.style.display = "none";
|
||||
this._el.appendChild(this._elImage);
|
||||
this._bSupportDataURI = null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Draw the QRCode
|
||||
*
|
||||
* @param {QRCode} oQRCode
|
||||
*/
|
||||
Drawing.prototype.draw = function (oQRCode) {
|
||||
var _elImage = this._elImage;
|
||||
var _oContext = this._oContext;
|
||||
var _htOption = this._htOption;
|
||||
|
||||
var nCount = oQRCode.getModuleCount();
|
||||
var nWidth = _htOption.width / nCount;
|
||||
var nHeight = _htOption.height / nCount;
|
||||
var nRoundedWidth = Math.round(nWidth);
|
||||
var nRoundedHeight = Math.round(nHeight);
|
||||
|
||||
_elImage.style.display = "none";
|
||||
this.clear();
|
||||
|
||||
for (var row = 0; row < nCount; row++) {
|
||||
for (var col = 0; col < nCount; col++) {
|
||||
var bIsDark = oQRCode.isDark(row, col);
|
||||
var nLeft = col * nWidth;
|
||||
var nTop = row * nHeight;
|
||||
_oContext.strokeStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight;
|
||||
_oContext.lineWidth = 1;
|
||||
_oContext.fillStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight;
|
||||
_oContext.fillRect(nLeft, nTop, nWidth, nHeight);
|
||||
|
||||
// 안티 앨리어싱 방지 처리
|
||||
_oContext.strokeRect(
|
||||
Math.floor(nLeft) + 0.5,
|
||||
Math.floor(nTop) + 0.5,
|
||||
nRoundedWidth,
|
||||
nRoundedHeight
|
||||
);
|
||||
|
||||
_oContext.strokeRect(
|
||||
Math.ceil(nLeft) - 0.5,
|
||||
Math.ceil(nTop) - 0.5,
|
||||
nRoundedWidth,
|
||||
nRoundedHeight
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
this._bIsPainted = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Make the image from Canvas if the browser supports Data URI.
|
||||
*/
|
||||
Drawing.prototype.makeImage = function () {
|
||||
if (this._bIsPainted) {
|
||||
_safeSetDataURI.call(this, _onMakeImage);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Return whether the QRCode is painted or not
|
||||
*
|
||||
* @return {Boolean}
|
||||
*/
|
||||
Drawing.prototype.isPainted = function () {
|
||||
return this._bIsPainted;
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear the QRCode
|
||||
*/
|
||||
Drawing.prototype.clear = function () {
|
||||
this._oContext.clearRect(0, 0, this._elCanvas.width, this._elCanvas.height);
|
||||
this._bIsPainted = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {Number} nNumber
|
||||
*/
|
||||
Drawing.prototype.round = function (nNumber) {
|
||||
if (!nNumber) {
|
||||
return nNumber;
|
||||
}
|
||||
|
||||
return Math.floor(nNumber * 1000) / 1000;
|
||||
};
|
||||
|
||||
return Drawing;
|
||||
})();
|
||||
|
||||
/**
|
||||
* Get the type by string length
|
||||
*
|
||||
* @private
|
||||
* @param {String} sText
|
||||
* @param {Number} nCorrectLevel
|
||||
* @return {Number} type
|
||||
*/
|
||||
function _getTypeNumber(sText, nCorrectLevel) {
|
||||
var nType = 1;
|
||||
var length = _getUTF8Length(sText);
|
||||
|
||||
for (var i = 0, len = QRCodeLimitLength.length; i <= len; i++) {
|
||||
var nLimit = 0;
|
||||
|
||||
switch (nCorrectLevel) {
|
||||
case QRErrorCorrectLevel.L :
|
||||
nLimit = QRCodeLimitLength[i][0];
|
||||
break;
|
||||
case QRErrorCorrectLevel.M :
|
||||
nLimit = QRCodeLimitLength[i][1];
|
||||
break;
|
||||
case QRErrorCorrectLevel.Q :
|
||||
nLimit = QRCodeLimitLength[i][2];
|
||||
break;
|
||||
case QRErrorCorrectLevel.H :
|
||||
nLimit = QRCodeLimitLength[i][3];
|
||||
break;
|
||||
}
|
||||
|
||||
if (length <= nLimit) {
|
||||
break;
|
||||
} else {
|
||||
nType++;
|
||||
}
|
||||
}
|
||||
|
||||
if (nType > QRCodeLimitLength.length) {
|
||||
throw new Error("Too long data");
|
||||
}
|
||||
|
||||
return nType;
|
||||
}
|
||||
|
||||
function _getUTF8Length(sText) {
|
||||
var replacedText = encodeURI(sText).toString().replace(/\%[0-9a-fA-F]{2}/g, 'a');
|
||||
return replacedText.length + (replacedText.length != sText ? 3 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @class QRCode
|
||||
* @constructor
|
||||
* @example
|
||||
* new QRCode(document.getElementById("test"), "http://jindo.dev.naver.com/collie");
|
||||
*
|
||||
* @example
|
||||
* var oQRCode = new QRCode("test", {
|
||||
* text : "http://naver.com",
|
||||
* width : 128,
|
||||
* height : 128
|
||||
* });
|
||||
*
|
||||
* oQRCode.clear(); // Clear the QRCode.
|
||||
* oQRCode.makeCode("http://map.naver.com"); // Re-create the QRCode.
|
||||
*
|
||||
* @param {HTMLElement|String} el target element or 'id' attribute of element.
|
||||
* @param {Object|String} vOption
|
||||
* @param {String} vOption.text QRCode link data
|
||||
* @param {Number} [vOption.width=256]
|
||||
* @param {Number} [vOption.height=256]
|
||||
* @param {String} [vOption.colorDark="#000000"]
|
||||
* @param {String} [vOption.colorLight="#ffffff"]
|
||||
* @param {QRCode.CorrectLevel} [vOption.correctLevel=QRCode.CorrectLevel.H] [L|M|Q|H]
|
||||
*/
|
||||
QRCode = function (el, vOption) {
|
||||
this._htOption = {
|
||||
width : 256,
|
||||
height : 256,
|
||||
typeNumber : 4,
|
||||
colorDark : "#000000",
|
||||
colorLight : "#ffffff",
|
||||
correctLevel : QRErrorCorrectLevel.H
|
||||
};
|
||||
|
||||
if (typeof vOption === 'string') {
|
||||
vOption = {
|
||||
text : vOption
|
||||
};
|
||||
}
|
||||
|
||||
// Overwrites options
|
||||
if (vOption) {
|
||||
for (var i in vOption) {
|
||||
this._htOption[i] = vOption[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof el == "string") {
|
||||
el = document.getElementById(el);
|
||||
}
|
||||
|
||||
if (this._htOption.useSVG) {
|
||||
Drawing = svgDrawer;
|
||||
}
|
||||
|
||||
this._android = _getAndroid();
|
||||
this._el = el;
|
||||
this._oQRCode = null;
|
||||
this._oDrawing = new Drawing(this._el, this._htOption);
|
||||
|
||||
if (this._htOption.text) {
|
||||
this.makeCode(this._htOption.text);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Make the QRCode
|
||||
*
|
||||
* @param {String} sText link data
|
||||
*/
|
||||
QRCode.prototype.makeCode = function (sText) {
|
||||
this._oQRCode = new QRCodeModel(_getTypeNumber(sText, this._htOption.correctLevel), this._htOption.correctLevel);
|
||||
this._oQRCode.addData(sText);
|
||||
this._oQRCode.make();
|
||||
this._el.title = sText;
|
||||
this._oDrawing.draw(this._oQRCode);
|
||||
this.makeImage();
|
||||
};
|
||||
|
||||
/**
|
||||
* Make the Image from Canvas element
|
||||
* - It occurs automatically
|
||||
* - Android below 3 doesn't support Data-URI spec.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
QRCode.prototype.makeImage = function () {
|
||||
if (typeof this._oDrawing.makeImage == "function" && (!this._android || this._android >= 3)) {
|
||||
this._oDrawing.makeImage();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear the QRCode
|
||||
*/
|
||||
QRCode.prototype.clear = function () {
|
||||
this._oDrawing.clear();
|
||||
};
|
||||
|
||||
/**
|
||||
* @name QRCode.CorrectLevel
|
||||
*/
|
||||
QRCode.CorrectLevel = QRErrorCorrectLevel;
|
||||
})();
|
||||
@@ -1,107 +0,0 @@
|
||||
-- for development:
|
||||
local p = quarto.log.warning
|
||||
|
||||
---Format string like in bash or python,
|
||||
---e.g. f('Hello ${one}', {one = 'world'})
|
||||
---@param s string The string to format
|
||||
---@param kwargs {[string]: string} A table with key-value replacemen pairs
|
||||
---@return string
|
||||
local function f(s, kwargs)
|
||||
return (s:gsub('($%b{})', function(w) return kwargs[w:sub(3, -2)] or w end))
|
||||
end
|
||||
|
||||
|
||||
---Merge user provided options with defaults
|
||||
---@param userOptions table
|
||||
---@return string JSON string to pass to molstar
|
||||
local function mergeOptions(url, userOptions)
|
||||
local defaultOptions = {
|
||||
text = url,
|
||||
width = 128,
|
||||
height = 128,
|
||||
colorDark = "#000000",
|
||||
colorLight = "#ffffff",
|
||||
}
|
||||
if userOptions == nil then
|
||||
return quarto.json.encode(defaultOptions)
|
||||
end
|
||||
|
||||
for k, v in pairs(userOptions) do
|
||||
local value = pandoc.utils.stringify(v)
|
||||
if value == 'true' then value = true end
|
||||
if value == 'false' then value = false end
|
||||
defaultOptions[k] = value
|
||||
end
|
||||
|
||||
return quarto.json.encode(defaultOptions)
|
||||
end
|
||||
|
||||
|
||||
---@return string
|
||||
local function wrapInlineDiv(options)
|
||||
return [[
|
||||
<div id="${id}" class="qrcode"></div>
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
var script = document.currentScript;
|
||||
var qrcode = script.previousElementSibling;
|
||||
qrcode.qrcode = new QRCode(qrcode, ]] .. options .. [[);
|
||||
script.remove();
|
||||
})();
|
||||
</script>
|
||||
]]
|
||||
end
|
||||
|
||||
---@return string
|
||||
local function wrapInlineTex(url, opts)
|
||||
return [[
|
||||
\qrcode[]] .. opts .. [[]{]] .. url .. [[}
|
||||
]]
|
||||
end
|
||||
|
||||
return {
|
||||
['qrcode'] = function(args, kwargs, _)
|
||||
if quarto.doc.is_format("html:js") then
|
||||
quarto.doc.add_html_dependency {
|
||||
name = 'qrcodejs',
|
||||
version = 'v1.0.0',
|
||||
scripts = { './assets/qrcode.js' },
|
||||
}
|
||||
local url = pandoc.utils.stringify(args[1])
|
||||
local id = ""
|
||||
if args[2] ~= nil then
|
||||
id = f('id="${id}" ', { id = pandoc.utils.stringify(id) })
|
||||
end
|
||||
local options = mergeOptions(url, kwargs)
|
||||
local text = wrapInlineDiv(options)
|
||||
return pandoc.RawBlock(
|
||||
'html',
|
||||
f(text, { id = id })
|
||||
)
|
||||
elseif quarto.doc.is_format("pdf") then
|
||||
quarto.doc.use_latex_package("qrcode")
|
||||
local url = pandoc.utils.stringify(args[1])
|
||||
local opts = ""
|
||||
for k, v in pairs(kwargs) do
|
||||
if string.match(k, "^pdf") then
|
||||
k = string.sub(k, 4)
|
||||
opts = opts .. k .. "=" .. v .. ", "
|
||||
end
|
||||
end
|
||||
for _, v in ipairs(args) do
|
||||
if string.match(v, "^pdf") then
|
||||
v = string.sub(v, 4)
|
||||
opts = opts .. v .. ", "
|
||||
end
|
||||
end
|
||||
if string.len(opts) then
|
||||
opts = string.sub(opts, 1, string.len(opts) - 2)
|
||||
end
|
||||
local text = wrapInlineTex(url, opts)
|
||||
return pandoc.RawBlock(
|
||||
'tex',
|
||||
text
|
||||
)
|
||||
end
|
||||
end,
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 Mickaël Canouil
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1,7 +0,0 @@
|
||||
title: Highlight Text
|
||||
author: Mickaël Canouil
|
||||
version: 0.4.0
|
||||
quarto-required: ">=1.4.550"
|
||||
contributes:
|
||||
filters:
|
||||
- highlight-text.lua
|
||||
@@ -1,164 +0,0 @@
|
||||
--[[
|
||||
# MIT License
|
||||
#
|
||||
# Copyright (c) 2024 Mickaël Canouil
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
]]
|
||||
|
||||
local function highlight_html(span, colour, bg_colour)
|
||||
if span.attributes['style'] == nil then
|
||||
span.attributes['style'] = ''
|
||||
elseif span.attributes['style']:sub(-1) ~= ";" then
|
||||
span.attributes['style'] = span.attributes['style'] .. ";"
|
||||
end
|
||||
|
||||
if colour ~= nil then
|
||||
span.attributes['colour'] = nil
|
||||
span.attributes['color'] = nil
|
||||
span.attributes['style'] = span.attributes['style'] .. 'color: ' .. colour .. ';'
|
||||
end
|
||||
|
||||
if bg_colour ~= nil then
|
||||
span.attributes['bg-colour'] = nil
|
||||
span.attributes['bg-color'] = nil
|
||||
span.attributes['style'] = span.attributes['style'] .. 'border-radius: 0.2rem; padding: 0 0.2rem 0 0.2rem;' .. 'background-color: ' .. bg_colour .. ';'
|
||||
end
|
||||
|
||||
return span
|
||||
end
|
||||
|
||||
local function highlight_latex(span, colour, bg_colour)
|
||||
if colour == nil then
|
||||
colour_open = ''
|
||||
colour_close = ''
|
||||
else
|
||||
colour_open = '\\textcolor[HTML]{' .. colour:gsub("^#", "") .. '}{'
|
||||
colour_close = '}'
|
||||
end
|
||||
if bg_colour == nil then
|
||||
bg_colour_open = ''
|
||||
bg_colour_close = ''
|
||||
else
|
||||
bg_colour_open = '\\colorbox[HTML]{' .. bg_colour:gsub("^#", "") .. '}{'
|
||||
bg_colour_close = '}'
|
||||
end
|
||||
|
||||
table.insert(
|
||||
span.content, 1,
|
||||
pandoc.RawInline('latex', colour_open .. bg_colour_open)
|
||||
)
|
||||
table.insert(span.content, pandoc.RawInline('latex', bg_colour_close .. colour_close))
|
||||
|
||||
return span.content
|
||||
end
|
||||
|
||||
local function highlight_openxml_docx(span, colour, bg_colour)
|
||||
local spec = '<w:r><w:rPr>'
|
||||
if bg_colour ~= nil then
|
||||
spec = spec .. '<w:shd w:val="clear" w:fill="' .. bg_colour:gsub("^#", "") .. '"/>'
|
||||
end
|
||||
if colour ~= nil then
|
||||
spec = spec .. '<w:color w:val="' .. colour:gsub("^#", "") .. '"/>'
|
||||
end
|
||||
spec = spec .. '</w:rPr><w:t>'
|
||||
|
||||
table.insert(span.content, 1, pandoc.RawInline('openxml', spec))
|
||||
table.insert(span.content, pandoc.RawInline('openxml', '</w:t></w:r>'))
|
||||
|
||||
return span.content
|
||||
end
|
||||
|
||||
local function highlight_openxml_pptx(span, colour, bg_colour)
|
||||
local spec = '<a:r><a:rPr dirty="0">'
|
||||
if bg_colour ~= nil then
|
||||
spec = spec .. '<a:highlight><a:srgbClr val="' .. bg_colour:gsub("^#", "") .. '" /></a:highlight>'
|
||||
end
|
||||
if colour ~= nil then
|
||||
spec = spec .. '<a:solidFill><a:srgbClr val="' .. colour:gsub("^#", "") .. '" /></a:solidFill>'
|
||||
end
|
||||
spec = spec .. '</a:rPr><a:t>'
|
||||
|
||||
-- table.insert(span.content, 1, pandoc.RawInline('openxml', spec))
|
||||
-- table.insert(span.content, pandoc.RawInline('openxml', '</a:t></a:r>'))
|
||||
|
||||
local span_content_string = ""
|
||||
for i, inline in ipairs(span.content) do
|
||||
span_content_string = span_content_string .. pandoc.utils.stringify(inline)
|
||||
end
|
||||
|
||||
return pandoc.RawInline('openxml', spec .. span_content_string .. '</a:t></a:r>')
|
||||
end
|
||||
|
||||
local function highlight_typst(span, colour, bg_colour)
|
||||
if colour == nil then
|
||||
colour_open = ''
|
||||
colour_close = ''
|
||||
else
|
||||
colour_open = '#text(rgb("' .. colour .. '"))['
|
||||
colour_close = ']'
|
||||
end
|
||||
|
||||
if bg_colour == nil then
|
||||
bg_colour_open = ''
|
||||
bg_colour_close = ''
|
||||
else
|
||||
bg_colour_open = '#highlight(fill: rgb("' .. bg_colour .. '"))['
|
||||
bg_colour_close = ']'
|
||||
end
|
||||
|
||||
table.insert(
|
||||
span.content, 1,
|
||||
pandoc.RawInline('typst', colour_open .. bg_colour_open)
|
||||
)
|
||||
table.insert(
|
||||
span.content,
|
||||
pandoc.RawInline('typst', bg_colour_close .. colour_close)
|
||||
)
|
||||
|
||||
return span.content
|
||||
end
|
||||
|
||||
function Span(span)
|
||||
local colour = span.attributes['colour']
|
||||
if colour == nil then
|
||||
colour = span.attributes['color']
|
||||
end
|
||||
|
||||
local bg_colour = span.attributes['bg-colour']
|
||||
if bg_colour == nil then
|
||||
bg_colour = span.attributes['bg-color']
|
||||
end
|
||||
|
||||
if colour == nil and bg_colour == nil then return span end
|
||||
|
||||
if FORMAT:match 'html' or FORMAT:match 'revealjs' then
|
||||
return highlight_html(span, colour, bg_colour)
|
||||
elseif FORMAT:match 'latex' or FORMAT:match 'beamer' then
|
||||
return highlight_latex(span, colour, bg_colour)
|
||||
elseif FORMAT:match 'docx' then
|
||||
return highlight_openxml_docx(span, colour, bg_colour)
|
||||
elseif FORMAT:match 'pptx' then
|
||||
return highlight_openxml_pptx(span, colour, bg_colour)
|
||||
elseif FORMAT:match 'typst' then
|
||||
return highlight_typst(span, colour, bg_colour)
|
||||
else
|
||||
return span
|
||||
end
|
||||
end
|
||||
@@ -1,8 +0,0 @@
|
||||
title: Critic-markup
|
||||
author: mloubout
|
||||
version: 1.0.3
|
||||
quarto-required: ">=1.2.198"
|
||||
contributes:
|
||||
filters:
|
||||
- critic-markup.lua
|
||||
|
||||
@@ -1,174 +0,0 @@
|
||||
|
||||
local maybesubs = false
|
||||
local stk_end = false
|
||||
|
||||
add = pandoc.RawInline('html', "<ins>")
|
||||
adde = pandoc.RawInline('html', "</ins>")
|
||||
|
||||
rm = pandoc.RawInline('html', "<del>")
|
||||
rme = pandoc.RawInline('html', "</del>")
|
||||
rmeadd = pandoc.RawInline('html', "</del><ins>")
|
||||
|
||||
mark = pandoc.RawInline('html', "<mark>")
|
||||
marke = pandoc.RawInline('html', "</mark>")
|
||||
|
||||
comm = pandoc.RawInline('html', [[<span class="critic comment">]])
|
||||
comme = pandoc.RawInline('html', "</span>")
|
||||
|
||||
ruless = {['{%+%+']=add, ['{\u{2013}']=rm, ['{==']=mark, ['{>>']=comm, ['{~~']=rm,
|
||||
['%+%+}']=adde, ['\u{2013}}']=rme, ['==}']=marke, ['<<}']=comme, ['~~}']=rme, ['~>']=rmeadd}
|
||||
|
||||
-- Strikeout before/after
|
||||
st_b = '{'
|
||||
st_e = '}'
|
||||
|
||||
local scriptcode = [[
|
||||
|
||||
<div id="criticnav">
|
||||
<ul>
|
||||
<li id="markup-button">Markup</li>
|
||||
<li id="original-button">Original</li>
|
||||
<li id="edited-button">Edited</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
function critic() {
|
||||
|
||||
$('.content').addClass('markup');
|
||||
$('#markup-button').addClass('active');
|
||||
$('ins.break').unwrap();
|
||||
$('span.critic.comment').wrap('<span class="popoverc" /></span>');
|
||||
$('span.critic.comment').before('‡');
|
||||
}
|
||||
|
||||
function original() {
|
||||
$('#original-button').addClass('active');
|
||||
$('#edited-button').removeClass('active');
|
||||
$('#markup-button').removeClass('active');
|
||||
|
||||
$('.content').addClass('original');
|
||||
$('.content').removeClass('edited');
|
||||
$('.content').removeClass('markup');
|
||||
}
|
||||
|
||||
function edited() {
|
||||
$('#original-button').removeClass('active');
|
||||
$('#edited-button').addClass('active');
|
||||
$('#markup-button').removeClass('active');
|
||||
|
||||
$('.content').removeClass('original');
|
||||
$('.content').addClass('edited');
|
||||
$('.content').removeClass('markup');
|
||||
}
|
||||
|
||||
function markup() {
|
||||
$('#original-button').removeClass('active');
|
||||
$('#edited-button').removeClass('active');
|
||||
$('#markup-button').addClass('active');
|
||||
|
||||
$('.content').removeClass('original');
|
||||
$('.content').removeClass('edited');
|
||||
$('.content').addClass('markup');
|
||||
}
|
||||
|
||||
var o = document.getElementById("original-button");
|
||||
var e = document.getElementById("edited-button");
|
||||
var m = document.getElementById("markup-button");
|
||||
|
||||
window.onload = critic();
|
||||
o.onclick = original;
|
||||
e.onclick = edited;
|
||||
m.onclick = markup;
|
||||
</script>
|
||||
]]
|
||||
|
||||
function cirtiblock(blocks, k, v)
|
||||
local newblock = {}
|
||||
for ti,t in pairs(blocks) do
|
||||
if t.text then
|
||||
i, j = t.text:find(k)
|
||||
if i then
|
||||
newblock[#newblock + 1] = pandoc.Str(t.text:sub(1, i-1))
|
||||
newblock[#newblock + 1] = v
|
||||
newblock[#newblock + 1] = pandoc.Str(t.text:sub(j+1, t.text:len()))
|
||||
else
|
||||
newblock[#newblock + 1] = t
|
||||
end
|
||||
else
|
||||
newblock[#newblock + 1] = t
|
||||
end
|
||||
end
|
||||
return newblock
|
||||
end
|
||||
|
||||
|
||||
if FORMAT:match 'html' then
|
||||
|
||||
function Str (el)
|
||||
local replaced = {el}
|
||||
-- Check for standard substitutions
|
||||
for k,v in pairs(ruless) do
|
||||
replaced = cirtiblock(replaced, k, v)
|
||||
end
|
||||
return replaced
|
||||
end
|
||||
|
||||
function Strikeout (strk)
|
||||
return strk.content
|
||||
end
|
||||
|
||||
-- Check Inlines for Strikeout (~~) and remove brackets before/after for replacement
|
||||
function Inlines (inlines)
|
||||
for i = #inlines-1,2,-1 do
|
||||
if inlines[i] and inlines[i].t == 'Strikeout' and inlines[i+1] then
|
||||
if inlines[i+1].t == 'Str' then
|
||||
if inlines[i+1].text == st_e then
|
||||
inlines[i+1] = adde
|
||||
end
|
||||
end
|
||||
end
|
||||
if inlines[i] and inlines[i].t == 'Strikeout' and inlines[i-1] then
|
||||
if inlines[i-1].t == 'Str' then
|
||||
if inlines[i-1].text == st_b then
|
||||
inlines[i-1] = rm
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return inlines
|
||||
end
|
||||
end
|
||||
|
||||
--- From the lightbox filter
|
||||
local function add_header_includes(meta, blocks)
|
||||
|
||||
local header_includes = pandoc.List(blocks)
|
||||
|
||||
-- add any exisiting meta['header-includes']
|
||||
-- it could be a MetaList or a single String
|
||||
if meta['header-includes'] then
|
||||
if type(meta['header-includes']) == 'List' then
|
||||
header_includes:extend(meta['header-includes'])
|
||||
else
|
||||
header_includes:insert(meta['header-includes'])
|
||||
end
|
||||
end
|
||||
|
||||
meta['header-includes'] = pandoc.MetaBlocks(header_includes)
|
||||
return meta
|
||||
end
|
||||
|
||||
|
||||
function criticheader (meta)
|
||||
quarto.doc.add_html_dependency({
|
||||
name = 'critic',
|
||||
scripts = {'critic.min.js'},
|
||||
stylesheets = {'critic.css'}
|
||||
})
|
||||
-- inject the rendering code
|
||||
quarto.doc.include_text("after-body", scriptcode)
|
||||
end
|
||||
|
||||
-- All pass with Meta first
|
||||
return {{Meta = criticheader}, {Inlines = Inlines}, {Strikeout = Strikeout}, {Str = Str}}
|
||||
@@ -1,131 +0,0 @@
|
||||
.fullcontent {
|
||||
padding-top: 30px !important;
|
||||
}
|
||||
|
||||
#criticnav {
|
||||
position: fixed;
|
||||
z-index: 1100;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
border-bottom: solid 1px #696f75;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: rgba(255,255,255,0.95);
|
||||
color: #696f75;
|
||||
font-size: 14px;
|
||||
font-family: "Helvetica Neue", helvetica, arial, sans-serif !important
|
||||
}
|
||||
|
||||
#criticnav ul {
|
||||
list-style-type: none;
|
||||
width: 90%;
|
||||
margin: 0 auto;
|
||||
padding: 0
|
||||
}
|
||||
|
||||
#criticnav ul li {
|
||||
display: block;
|
||||
width: 15%;
|
||||
min-width: 100px;
|
||||
text-align: center;
|
||||
padding: 5px 0 3px !important;
|
||||
margin: 5px 2px !important;
|
||||
line-height: 1em;
|
||||
float: left;
|
||||
text-transform: uppercase;
|
||||
cursor: pointer;
|
||||
-webkit-user-select: none;
|
||||
border-radius: 20px;
|
||||
border: 1px solid rgba(255,255,255,0);
|
||||
color: #777 !important
|
||||
}
|
||||
|
||||
#criticnav ul li:before {
|
||||
content: none !important
|
||||
}
|
||||
|
||||
#criticnav ul li.active {
|
||||
border: 1px solid #696f75
|
||||
}
|
||||
|
||||
.original del {
|
||||
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.original ins,
|
||||
.original span.popoverc,
|
||||
.original ins.break {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.edited ins {
|
||||
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.edited del,
|
||||
.edited span.popoverc,
|
||||
.edited ins.break {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.original mark,
|
||||
.edited mark {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.markup mark {
|
||||
background-color: #fffd38;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.markup del {
|
||||
background-color: rgba(183,47,47,0.4);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.markup ins {
|
||||
background-color: rgba(152,200,86,0.4);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.markup ins.break {
|
||||
display: block;
|
||||
line-height: 2px;
|
||||
padding: 0 !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.markup ins.break span {
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
.markup .popoverc {
|
||||
background-color: #e5b000;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.markup .popoverc .critic.comment {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.markup .popoverc:hover span.critic.comment {
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 200px;
|
||||
left: 30%;
|
||||
font-size: 0.8em;
|
||||
color: #ccc;
|
||||
background-color: #333;
|
||||
z-index: 10;
|
||||
padding: 0.5em 1em;
|
||||
border-radius: 0.5em;
|
||||
}
|
||||
|
||||
@media print {
|
||||
#criticnav {
|
||||
display: none !important
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -1,6 +0,0 @@
|
||||
name: abstract-section
|
||||
author: Albert Krewinkel
|
||||
version: 1.0.0
|
||||
contributes:
|
||||
filters:
|
||||
- abstract-section.lua
|
||||
@@ -1,59 +0,0 @@
|
||||
--[[
|
||||
abstract-to-meta – move an "abstract" section into document metadata
|
||||
|
||||
Copyright: © 2017–2021 Albert Krewinkel
|
||||
License: MIT – see LICENSE file for details
|
||||
]]
|
||||
local abstract = {}
|
||||
|
||||
--- Extract abstract from a list of blocks.
|
||||
function abstract_from_blocklist (blocks)
|
||||
local body_blocks = {}
|
||||
local looking_at_abstract = false
|
||||
|
||||
for _, block in ipairs(blocks) do
|
||||
if block.t == 'Header' and block.level == 1 then
|
||||
if block.identifier == 'abstract' then
|
||||
looking_at_abstract = true
|
||||
else
|
||||
looking_at_abstract = false
|
||||
body_blocks[#body_blocks + 1] = block
|
||||
end
|
||||
elseif looking_at_abstract then
|
||||
if block.t == 'HorizontalRule' then
|
||||
looking_at_abstract = false
|
||||
else
|
||||
abstract[#abstract + 1] = block
|
||||
end
|
||||
else
|
||||
body_blocks[#body_blocks + 1] = block
|
||||
end
|
||||
end
|
||||
|
||||
return body_blocks
|
||||
end
|
||||
|
||||
if PANDOC_VERSION >= {2,9,2} then
|
||||
-- Check all block lists with pandoc 2.9.2 or later
|
||||
return {{
|
||||
Blocks = abstract_from_blocklist,
|
||||
Meta = function (meta)
|
||||
if not meta.abstract and #abstract > 0 then
|
||||
meta.abstract = pandoc.MetaBlocks(abstract)
|
||||
end
|
||||
return meta
|
||||
end
|
||||
}}
|
||||
else
|
||||
-- otherwise, just check the top-level block-list
|
||||
return {{
|
||||
Pandoc = function (doc)
|
||||
local meta = doc.meta
|
||||
local other_blocks = abstract_from_blocklist(doc.blocks)
|
||||
if not meta.abstract and #abstract > 0 then
|
||||
meta.abstract = pandoc.MetaBlocks(abstract)
|
||||
end
|
||||
return pandoc.Pandoc(other_blocks, meta)
|
||||
end,
|
||||
}}
|
||||
end
|
||||
@@ -1,6 +0,0 @@
|
||||
name: scholarly-metadata
|
||||
author: Albert Krewinkel
|
||||
version: 1.0.0
|
||||
contributes:
|
||||
filters:
|
||||
- scholarly-metadata.lua
|
||||
@@ -1,197 +0,0 @@
|
||||
--[[
|
||||
ScholarlyMeta – normalize author/affiliation meta variables
|
||||
|
||||
Copyright (c) 2017-2021 Albert Krewinkel, Robert Winkler
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any purpose
|
||||
with or without fee is hereby granted, provided that the above copyright notice
|
||||
and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
]]
|
||||
local List = require("pandoc.List")
|
||||
|
||||
--- Returns the type of a metadata value.
|
||||
--
|
||||
-- @param v a metadata value
|
||||
-- @treturn string one of `Blocks`, `Inlines`, `List`, `Map`, `string`, `boolean`
|
||||
local function metatype(v)
|
||||
if PANDOC_VERSION <= "2.16.2" then
|
||||
local metatag = type(v) == "table" and v.t and v.t:gsub("^Meta", "")
|
||||
return metatag and metatag ~= "Map" and metatag or type(v)
|
||||
end
|
||||
return pandoc.utils.type(v)
|
||||
end
|
||||
|
||||
local type = pandoc.utils.type or metatype
|
||||
|
||||
-- Split a string at commas.
|
||||
local function comma_separated_values(str)
|
||||
local acc = List:new({})
|
||||
for substr in str:gmatch("([^,]*)") do
|
||||
acc[#acc + 1] = substr:gsub("^%s*", ""):gsub("%s*$", "") -- trim
|
||||
end
|
||||
return acc
|
||||
end
|
||||
|
||||
--- Ensure the return value is a list.
|
||||
local function ensure_list(val)
|
||||
if type(val) == "List" then
|
||||
return val
|
||||
elseif type(val) == "Inlines" then
|
||||
-- check if this is really a comma-separated list
|
||||
local csv = comma_separated_values(pandoc.utils.stringify(val))
|
||||
if #csv >= 2 then
|
||||
return csv
|
||||
end
|
||||
return List:new({ val })
|
||||
elseif type(val) == "table" and #val > 0 then
|
||||
return List:new(val)
|
||||
else
|
||||
-- Anything else, use as a singleton (or empty list if val == nil).
|
||||
return List:new({ val })
|
||||
end
|
||||
end
|
||||
|
||||
--- Returns a function which checks whether an object has the given ID.
|
||||
local function has_id(id)
|
||||
return function(x)
|
||||
return x.id == id
|
||||
end
|
||||
end
|
||||
|
||||
--- Copy all key-value pairs of the first table into the second iff there is no
|
||||
-- such key yet in the second table.
|
||||
-- @returns the second argument
|
||||
function add_missing_entries(a, b)
|
||||
for k, v in pairs(a) do
|
||||
b[k] = b[k] or v
|
||||
end
|
||||
return b
|
||||
end
|
||||
|
||||
--- Create an object with a name. The name is either taken directly from the
|
||||
-- `name` field, or from the *only* field name (i.e., key) if the object is a
|
||||
-- dictionary with just one entry. If neither exists, the name is left unset
|
||||
-- (`nil`).
|
||||
function to_named_object(obj)
|
||||
local named = {}
|
||||
if type(obj) == "Inlines" then
|
||||
-- Treat inlines as the name
|
||||
named.name = obj
|
||||
named.id = pandoc.utils.stringify(obj)
|
||||
elseif type(obj) ~= "table" then
|
||||
-- if the object isn't a table, just use its value as a name.
|
||||
named.name = pandoc.MetaInlines({ pandoc.Str(tostring(obj)) })
|
||||
named.id = tostring(obj)
|
||||
elseif obj.name ~= nil then
|
||||
-- object has name attribute → just create a copy of the object
|
||||
add_missing_entries(obj, named)
|
||||
named.id = pandoc.utils.stringify(named.id or named.name)
|
||||
elseif next(obj) and next(obj, next(obj)) == nil then
|
||||
-- Single-entry table. The entry's key is taken as the name, the value
|
||||
-- contains the attributes.
|
||||
key, attribs = next(obj)
|
||||
if type(attribs) == "string" or type(attribs) == "Inlines" then
|
||||
named.name = attribs
|
||||
else
|
||||
add_missing_entries(attribs, named)
|
||||
named.name = named.name or pandoc.MetaInlines({ pandoc.Str(tostring(key)) })
|
||||
end
|
||||
named.id = named.id and pandoc.utils.stringify(named.id) or key
|
||||
else
|
||||
-- this is not a named object adhering to the usual conventions.
|
||||
error("not a named object: " .. tostring(obj))
|
||||
end
|
||||
return named
|
||||
end
|
||||
|
||||
--- Resolve affiliations placeholders to full named objects
|
||||
local function resolve_affiliations(affiliations, known_affiliations)
|
||||
local unresolved_affiliations
|
||||
if affiliations == nil then
|
||||
unresolved_affiliations = {}
|
||||
elseif type(affiliations) == "string" or type(affiliations) == "number" then
|
||||
unresolved_affiliations = { affiliations }
|
||||
else
|
||||
unresolved_affiliations = affiliations
|
||||
end
|
||||
|
||||
local result = List:new({})
|
||||
for i, inst in ipairs(unresolved_affiliations) do
|
||||
result[i] = known_affiliations[tonumber(inst)]
|
||||
or known_affiliations:find_if(has_id(pandoc.utils.stringify(inst)))
|
||||
or to_named_object(inst)
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
--- Insert a named object into a list; if an object of the same name exists
|
||||
-- already, add all properties only present in the new object to the existing
|
||||
-- item.
|
||||
function merge_on_id(list, namedObj)
|
||||
local elem, idx = list:find_if(has_id(namedObj.id))
|
||||
local res = elem and add_missing_entries(namedObj, elem) or namedObj
|
||||
local obj_idx = idx or (#list + 1)
|
||||
-- return res, obj_idx
|
||||
list[obj_idx] = res
|
||||
return res, #list
|
||||
end
|
||||
|
||||
--- Flatten a list of lists.
|
||||
local function flatten(lists)
|
||||
local result = List:new({})
|
||||
for _, lst in ipairs(lists) do
|
||||
result:extend(lst)
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
--- Canonicalize authors and affiliations
|
||||
local function canonicalize(raw_author, raw_affiliations)
|
||||
local affiliations = ensure_list(raw_affiliations):map(to_named_object)
|
||||
local authors = ensure_list(raw_author):map(to_named_object)
|
||||
|
||||
for _, author in ipairs(authors) do
|
||||
author.affiliations = resolve_affiliations(ensure_list(author.affiliations), affiliations)
|
||||
end
|
||||
|
||||
-- Merge affiliations defined in author objects with those defined in the
|
||||
-- top-level list.
|
||||
local author_insts = flatten(authors:map(function(x)
|
||||
return x.affiliations
|
||||
end))
|
||||
for _, inst in ipairs(author_insts) do
|
||||
merge_on_id(affiliations, inst)
|
||||
end
|
||||
|
||||
-- Add list indices to affiliations for numbering and reference purposes
|
||||
for idx, inst in ipairs(affiliations) do
|
||||
inst.index = pandoc.MetaInlines({ pandoc.Str(tostring(idx)) })
|
||||
end
|
||||
|
||||
-- replace affiliations with their indices
|
||||
local to_index = function(inst)
|
||||
return tostring(select(2, affiliations:find_if(has_id(inst.id))))
|
||||
end
|
||||
for _, author in ipairs(authors) do
|
||||
author.affiliations = pandoc.MetaList(author.affiliations:map(to_index))
|
||||
end
|
||||
|
||||
return authors, affiliations
|
||||
end
|
||||
|
||||
return {
|
||||
{
|
||||
Meta = function(meta)
|
||||
meta.author, meta.affiliations = canonicalize(meta.author, meta.affiliations)
|
||||
return meta
|
||||
end,
|
||||
},
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
title: LaTeX Environment
|
||||
author: RStudio, PBC
|
||||
version: 1.1.0
|
||||
quarto-required: ">=1.2.198"
|
||||
contributes:
|
||||
filters:
|
||||
- latex-environment.lua
|
||||
format:
|
||||
pdf: default
|
||||
@@ -1,133 +0,0 @@
|
||||
-- environment.lua
|
||||
-- Copyright (C) 2020 by RStudio, PBC
|
||||
|
||||
local classEnvironments = pandoc.MetaMap({})
|
||||
local classCommands = pandoc.MetaMap({})
|
||||
|
||||
-- helper that identifies arrays
|
||||
local function tisarray(t)
|
||||
local i = 0
|
||||
for _ in pairs(t) do
|
||||
i = i + 1
|
||||
if t[i] == nil then return false end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
-- reads the environments
|
||||
local function readEnvironments(meta)
|
||||
local env = meta['environments']
|
||||
if env ~= nil then
|
||||
if tisarray(env) then
|
||||
-- read an array of strings
|
||||
for i, v in ipairs(env) do
|
||||
local value = pandoc.utils.stringify(v)
|
||||
classEnvironments[value] = value
|
||||
end
|
||||
else
|
||||
-- read key value pairs
|
||||
for k, v in pairs(env) do
|
||||
local key = pandoc.utils.stringify(k)
|
||||
local value = pandoc.utils.stringify(v)
|
||||
classEnvironments[key] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function readCommands(meta)
|
||||
local env = meta['commands']
|
||||
if env ~= nil then
|
||||
if tisarray(env) then
|
||||
-- read an array of strings
|
||||
for i, v in ipairs(env) do
|
||||
local value = pandoc.utils.stringify(v)
|
||||
classCommands[value] = value
|
||||
end
|
||||
else
|
||||
-- read key value pairs
|
||||
for k, v in pairs(env) do
|
||||
local key = pandoc.utils.stringify(k)
|
||||
local value = pandoc.utils.stringify(v)
|
||||
classCommands[key] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function readEnvsAndCommands(meta)
|
||||
readEnvironments(meta)
|
||||
readCommands(meta)
|
||||
end
|
||||
|
||||
-- use the environments from metadata to
|
||||
-- emit a custom environment for latex
|
||||
local function writeEnvironments(divEl)
|
||||
if quarto.doc.is_format("latex") then
|
||||
for k, v in pairs(classEnvironments) do
|
||||
if divEl.attr.classes:includes(k) then
|
||||
-- process this into a latex environment
|
||||
local beginEnv = '\\begin' .. '{' .. v .. '}'
|
||||
local endEnv = '\n\\end{' .. v .. '}'
|
||||
|
||||
-- check if custom options or arguments are present
|
||||
-- and add them to the environment accordingly
|
||||
local opts = divEl.attr.attributes['options']
|
||||
if opts then
|
||||
beginEnv = beginEnv .. '[' .. opts .. ']'
|
||||
end
|
||||
|
||||
local args = divEl.attr.attributes['arguments']
|
||||
if args then
|
||||
beginEnv = beginEnv .. '{' .. args .. '}'
|
||||
end
|
||||
|
||||
-- if the first and last div blocks are paragraphs then we can
|
||||
-- bring the environment begin/end closer to the content
|
||||
if divEl.content[1].t == "Para" and divEl.content[#divEl.content].t == "Para" then
|
||||
table.insert(divEl.content[1].content, 1, pandoc.RawInline('tex', beginEnv .. "\n"))
|
||||
table.insert(divEl.content[#divEl.content].content, pandoc.RawInline('tex', "\n" .. endEnv))
|
||||
else
|
||||
table.insert(divEl.content, 1, pandoc.RawBlock('tex', beginEnv))
|
||||
table.insert(divEl.content, pandoc.RawBlock('tex', endEnv))
|
||||
end
|
||||
return divEl
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- use the environments from metadata to
|
||||
-- emit a custom environment for latex
|
||||
local function writeCommands(spanEl)
|
||||
if quarto.doc.is_format("latex") then
|
||||
for k, v in pairs(classCommands) do
|
||||
if spanEl.attr.classes:includes(k) then
|
||||
|
||||
-- resolve the begin command
|
||||
local beginCommand = pandoc.RawInline('latex', '\\' .. pandoc.utils.stringify(v) .. '{')
|
||||
local opts = spanEl.attr.attributes['options']
|
||||
if opts then
|
||||
beginCommand = pandoc.RawInline('latex', '\\' .. pandoc.utils.stringify(v) .. '[' .. opts .. ']{')
|
||||
end
|
||||
|
||||
-- the end command
|
||||
local endCommand = pandoc.RawInline('latex', '}')
|
||||
|
||||
-- attach the raw inlines to the span contents
|
||||
local result = spanEl.content
|
||||
table.insert(result, 1, beginCommand)
|
||||
table.insert(result, endCommand)
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Run in two passes so we process metadata
|
||||
-- and then process the divs
|
||||
return {
|
||||
{ Meta = readEnvsAndCommands },
|
||||
{ Div = writeEnvironments, Span = writeCommands }
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
title: Elsevier Journal Format
|
||||
author: Charles Teague
|
||||
version: 0.4.4
|
||||
quarto-required: ">=1.2.198"
|
||||
contributes:
|
||||
formats:
|
||||
common:
|
||||
date-format: full
|
||||
filters:
|
||||
- elsevier.lua
|
||||
pdf:
|
||||
documentclass: elsarticle
|
||||
template-partials: ["partials/before-body.tex", "partials/title.tex"]
|
||||
format-resources:
|
||||
- elsarticle.cls
|
||||
cite-method: natbib
|
||||
number-sections: true
|
||||
html:
|
||||
theme: styles/elsevier.scss
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,239 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<style xmlns="http://purl.org/net/xbiblio/csl" class="in-text" version="1.0" demote-non-dropping-particle="never" default-locale="en-US">
|
||||
<info>
|
||||
<title>Elsevier - Harvard (with titles)</title>
|
||||
<id>http://www.zotero.org/styles/elsevier-harvard</id>
|
||||
<link href="http://www.zotero.org/styles/elsevier-harvard" rel="self"/>
|
||||
<link href="http://www.zotero.org/styles/ecology-letters" rel="template"/>
|
||||
<link href="http://www.elsevier.com/journals/biological-conservation/0006-3207/guide-for-authors#68000" rel="documentation"/>
|
||||
<author>
|
||||
<name>David Kaplan</name>
|
||||
<email>david.kaplan@ird.fr</email>
|
||||
</author>
|
||||
<contributor>
|
||||
<name>Simon Kornblith</name>
|
||||
<email>simon@simonster.com</email>
|
||||
</contributor>
|
||||
<contributor>
|
||||
<name>Bruce D'Arcus</name>
|
||||
</contributor>
|
||||
<contributor>
|
||||
<name>Curtis M. Humphrey</name>
|
||||
</contributor>
|
||||
<contributor>
|
||||
<name>Richard Karnesky</name>
|
||||
<email>karnesky+zotero@gmail.com</email>
|
||||
<uri>http://arc.nucapt.northwestern.edu/Richard_Karnesky</uri>
|
||||
</contributor>
|
||||
<contributor>
|
||||
<name>Sebastian Karcher</name>
|
||||
</contributor>
|
||||
<category citation-format="author-date"/>
|
||||
<category field="biology"/>
|
||||
<category field="generic-base"/>
|
||||
<updated>2019-01-22T15:57:12+00:00</updated>
|
||||
<rights license="http://creativecommons.org/licenses/by-sa/3.0/">This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License</rights>
|
||||
</info>
|
||||
<macro name="container">
|
||||
<choose>
|
||||
<if type="chapter paper-conference" match="any">
|
||||
<text term="in" prefix=", " suffix=": "/>
|
||||
<names variable="editor translator" delimiter=", " suffix=", ">
|
||||
<name name-as-sort-order="all" sort-separator=", " initialize-with="." delimiter=", " delimiter-precedes-last="always"/>
|
||||
<label form="short" text-case="capitalize-first" prefix=" (" suffix=")"/>
|
||||
</names>
|
||||
<group delimiter=", ">
|
||||
<text variable="container-title" text-case="title"/>
|
||||
<text variable="collection-title" text-case="title"/>
|
||||
</group>
|
||||
</if>
|
||||
<else-if type="bill book graphic legal_case legislation motion_picture report song" match="any">
|
||||
<group prefix=", " delimiter=", ">
|
||||
<text variable="container-title"/>
|
||||
<text variable="collection-title"/>
|
||||
</group>
|
||||
</else-if>
|
||||
<else>
|
||||
<group prefix=". " delimiter=", ">
|
||||
<text variable="container-title" form="short"/>
|
||||
<text variable="collection-title"/>
|
||||
</group>
|
||||
</else>
|
||||
</choose>
|
||||
</macro>
|
||||
<macro name="author">
|
||||
<names variable="author">
|
||||
<name name-as-sort-order="all" sort-separator=", " initialize-with="." delimiter=", " delimiter-precedes-last="always"/>
|
||||
<label form="short" prefix=" (" suffix=")" text-case="capitalize-first"/>
|
||||
<substitute>
|
||||
<names variable="editor"/>
|
||||
<names variable="translator"/>
|
||||
<text macro="title"/>
|
||||
</substitute>
|
||||
</names>
|
||||
</macro>
|
||||
<macro name="author-short">
|
||||
<names variable="author">
|
||||
<name form="short" and="text" delimiter=", " initialize-with=". "/>
|
||||
<substitute>
|
||||
<names variable="editor"/>
|
||||
<names variable="translator"/>
|
||||
<choose>
|
||||
<if type="bill book graphic legal_case legislation motion_picture report song" match="any">
|
||||
<text variable="title" form="short" font-style="italic"/>
|
||||
</if>
|
||||
<else>
|
||||
<text variable="title" form="short" quotes="true"/>
|
||||
</else>
|
||||
</choose>
|
||||
</substitute>
|
||||
</names>
|
||||
</macro>
|
||||
<macro name="access">
|
||||
<choose>
|
||||
<if variable="DOI">
|
||||
<text variable="DOI" prefix="https://doi.org/"/>
|
||||
</if>
|
||||
<else-if type="webpage post-weblog" match="any">
|
||||
<group delimiter=" ">
|
||||
<text value="URL"/>
|
||||
<text variable="URL"/>
|
||||
<group prefix="(" suffix=").">
|
||||
<text term="accessed" suffix=" "/>
|
||||
<date variable="accessed">
|
||||
<date-part name="month" form="numeric" suffix="."/>
|
||||
<date-part name="day" suffix="."/>
|
||||
<date-part name="year" form="short"/>
|
||||
</date>
|
||||
</group>
|
||||
</group>
|
||||
</else-if>
|
||||
</choose>
|
||||
</macro>
|
||||
<macro name="title">
|
||||
<choose>
|
||||
<if type="report thesis" match="any">
|
||||
<text variable="title"/>
|
||||
<group prefix=" (" suffix=")" delimiter=" ">
|
||||
<text variable="genre"/>
|
||||
<text variable="number" prefix="No. "/>
|
||||
</group>
|
||||
</if>
|
||||
<else-if type="bill book graphic legal_case legislation motion_picture report song speech" match="any">
|
||||
<text variable="title"/>
|
||||
<text macro="edition" prefix=", "/>
|
||||
</else-if>
|
||||
<else-if type="webpage">
|
||||
<text variable="title"/>
|
||||
<text value="WWW Document" prefix=" [" suffix="]"/>
|
||||
</else-if>
|
||||
<else>
|
||||
<text variable="title"/>
|
||||
</else>
|
||||
</choose>
|
||||
</macro>
|
||||
<macro name="publisher">
|
||||
<group delimiter=", ">
|
||||
<text variable="publisher"/>
|
||||
<text variable="publisher-place"/>
|
||||
</group>
|
||||
</macro>
|
||||
<macro name="event">
|
||||
<choose>
|
||||
<if variable="event">
|
||||
<text term="presented at" text-case="capitalize-first" suffix=" "/>
|
||||
<text variable="event"/>
|
||||
</if>
|
||||
</choose>
|
||||
</macro>
|
||||
<macro name="issued">
|
||||
<choose>
|
||||
<if variable="issued">
|
||||
<date variable="issued">
|
||||
<date-part name="year"/>
|
||||
</date>
|
||||
</if>
|
||||
<else>
|
||||
<text term="no date" form="short"/>
|
||||
</else>
|
||||
</choose>
|
||||
</macro>
|
||||
<macro name="edition">
|
||||
<group delimiter=" ">
|
||||
<choose>
|
||||
<if is-numeric="edition">
|
||||
<number variable="edition" form="ordinal"/>
|
||||
</if>
|
||||
<else>
|
||||
<text variable="edition" suffix="."/>
|
||||
</else>
|
||||
</choose>
|
||||
<text value="ed"/>
|
||||
</group>
|
||||
</macro>
|
||||
<macro name="locators">
|
||||
<choose>
|
||||
<if type="article-journal article-magazine article-newspaper" match="any">
|
||||
<group prefix=" " delimiter=", ">
|
||||
<group>
|
||||
<text variable="volume"/>
|
||||
</group>
|
||||
<text variable="page"/>
|
||||
</group>
|
||||
</if>
|
||||
<else-if type="bill book graphic legal_case legislation motion_picture report song thesis" match="any">
|
||||
<group delimiter=", " prefix=". ">
|
||||
<text macro="event"/>
|
||||
<text macro="publisher"/>
|
||||
</group>
|
||||
</else-if>
|
||||
<else-if type="chapter paper-conference" match="any">
|
||||
<group delimiter=", " prefix=". ">
|
||||
<text macro="event"/>
|
||||
<text macro="publisher"/>
|
||||
<group>
|
||||
<label variable="page" form="short" suffix=" "/>
|
||||
<text variable="page"/>
|
||||
</group>
|
||||
</group>
|
||||
</else-if>
|
||||
<else-if type="patent">
|
||||
<text variable="number" prefix=". "/>
|
||||
</else-if>
|
||||
</choose>
|
||||
</macro>
|
||||
<citation et-al-min="3" et-al-use-first="1" disambiguate-add-givenname="true" disambiguate-add-year-suffix="true" collapse="year" cite-group-delimiter=", ">
|
||||
<sort>
|
||||
<key macro="author"/>
|
||||
<key macro="issued" sort="descending"/>
|
||||
</sort>
|
||||
<layout prefix="(" suffix=")" delimiter="; ">
|
||||
<group delimiter=", ">
|
||||
<text macro="author-short"/>
|
||||
<text macro="issued"/>
|
||||
<group delimiter=" ">
|
||||
<label variable="locator" form="short"/>
|
||||
<text variable="locator"/>
|
||||
</group>
|
||||
</group>
|
||||
</layout>
|
||||
</citation>
|
||||
<bibliography hanging-indent="true" entry-spacing="0" line-spacing="1">
|
||||
<sort>
|
||||
<key macro="author"/>
|
||||
<key macro="issued" sort="descending"/>
|
||||
</sort>
|
||||
<layout>
|
||||
<group suffix=".">
|
||||
<text macro="author" suffix=","/>
|
||||
<text macro="issued" prefix=" "/>
|
||||
<group prefix=". ">
|
||||
<text macro="title"/>
|
||||
<text macro="container"/>
|
||||
<text macro="locators"/>
|
||||
</group>
|
||||
</group>
|
||||
<text macro="access" prefix=". "/>
|
||||
</layout>
|
||||
</bibliography>
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,178 +0,0 @@
|
||||
local kClassOpt = "classoption"
|
||||
|
||||
-- cite style constants
|
||||
local kBibStyleDefault = "number"
|
||||
local kBibStyles = { "number", "numbername", "authoryear" }
|
||||
local kBibStyleAuthYr = "elsarticle-harv"
|
||||
local kBibStyleNumber = "elsarticle-num"
|
||||
local kBibStyleNumberName = "elsarticle-num-names"
|
||||
local kBibStyleUnknown = kBibStyleNumberName
|
||||
|
||||
-- layout and style
|
||||
local kFormatting = pandoc.List({ "preprint", "review", "doubleblind" })
|
||||
local kModels = pandoc.List({ "1p", "3p", "5p" })
|
||||
local kLayouts = pandoc.List({ "onecolumn", "twocolumn" })
|
||||
|
||||
local function setBibStyle(meta, style)
|
||||
-- .bst files are only supported with natbib
|
||||
if quarto.doc.cite_method() ~= "natbib" then
|
||||
return
|
||||
end
|
||||
if meta["biblio-style"] == nil then
|
||||
meta["biblio-style"] = style
|
||||
quarto.doc.add_format_resource("bib/" .. style .. ".bst")
|
||||
end
|
||||
end
|
||||
|
||||
local function hasClassOption(meta, option)
|
||||
if meta[kClassOpt] then
|
||||
for i, v in ipairs(meta[kClassOpt]) do
|
||||
if pandoc.utils.stringify(v) == option then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function addClassOption(meta, option)
|
||||
if meta[kClassOpt] == nil then
|
||||
meta[kClassOpt] = pandoc.List({})
|
||||
elseif pandoc.utils.type(meta[kClassOpt]) == "Inlines" then
|
||||
-- handle classoption: <value> as a string
|
||||
meta[kClassOpt] = pandoc.List({ meta[kClassOpt] })
|
||||
end
|
||||
if not hasClassOption(meta, option) then
|
||||
meta[kClassOpt]:insert({ pandoc.Str(option) })
|
||||
end
|
||||
end
|
||||
|
||||
local function printList(list)
|
||||
local result = ""
|
||||
local sep = ""
|
||||
for i, v in ipairs(list) do
|
||||
result = result .. sep .. v
|
||||
sep = ", "
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
local bibstyle
|
||||
|
||||
return {
|
||||
{
|
||||
Meta = function(meta)
|
||||
-- If citeproc is being used, switch to the proper
|
||||
-- CSL file
|
||||
if quarto.doc.cite_method() == "citeproc" and meta["csl"] == nil then
|
||||
meta["csl"] = quarto.utils.resolve_path("bib/elsevier-harvard.csl")
|
||||
end
|
||||
|
||||
if quarto.doc.is_format("pdf") then
|
||||
-- read the journal settings
|
||||
local journal = meta["journal"]
|
||||
local citestyle = nil
|
||||
local formatting = nil
|
||||
local model = nil
|
||||
local layout = nil
|
||||
local name = nil
|
||||
|
||||
if journal ~= nil then
|
||||
citestyle = journal["cite-style"]
|
||||
formatting = journal["formatting"]
|
||||
model = journal["model"]
|
||||
layout = journal["layout"]
|
||||
name = journal["name"]
|
||||
end
|
||||
|
||||
-- process the site style
|
||||
if citestyle ~= nil then
|
||||
citestyle = pandoc.utils.stringify(citestyle)
|
||||
else
|
||||
citestyle = kBibStyleDefault
|
||||
end
|
||||
-- capture the bibstyle
|
||||
bibstyle = citestyle
|
||||
if citestyle == "numbername" then
|
||||
setBibStyle(meta, kBibStyleNumberName)
|
||||
addClassOption(meta, "number")
|
||||
elseif citestyle == "authoryear" then
|
||||
setBibStyle(meta, kBibStyleAuthYr)
|
||||
addClassOption(meta, "authoryear")
|
||||
elseif citestyle == "number" then
|
||||
setBibStyle(meta, kBibStyleNumber)
|
||||
addClassOption(meta, "number")
|
||||
elseif citestyle == "super" then
|
||||
addClassOption(meta, "super")
|
||||
setBibStyle(meta, kBibStyleNumber)
|
||||
else
|
||||
error("Unknown journal cite-style " .. citestyle .. "\nPlease use one of " .. printList(kBibStyles))
|
||||
setBibStyle(meta, kBibStyleUnknown)
|
||||
end
|
||||
|
||||
-- process the layout
|
||||
if formatting ~= nil then
|
||||
formatting = pandoc.utils.stringify(formatting)
|
||||
if kFormatting:includes(formatting) then
|
||||
addClassOption(meta, formatting)
|
||||
else
|
||||
error(
|
||||
"Unknown journal formatting "
|
||||
.. formatting
|
||||
.. "\nPlease use one of "
|
||||
.. printList(kFormatting)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
-- process the type
|
||||
if model ~= nil then
|
||||
model = pandoc.utils.stringify(model)
|
||||
if kModels:includes(model) then
|
||||
addClassOption(meta, model)
|
||||
else
|
||||
error("Unknown journal model " .. model .. "\nPlease use one of " .. printList(kModels))
|
||||
end
|
||||
end
|
||||
|
||||
-- 5p models should be two column always
|
||||
if model == "5p" and layout == nil then
|
||||
layout = "twocolumn"
|
||||
end
|
||||
|
||||
-- process the type
|
||||
if layout ~= nil then
|
||||
layout = pandoc.utils.stringify(layout)
|
||||
if kLayouts:includes(layout) then
|
||||
addClassOption(meta, layout)
|
||||
if layout == "twocolumn" then
|
||||
quarto.doc.include_file("in-header", "partials/_two-column-longtable.tex")
|
||||
end
|
||||
else
|
||||
error("Unknown journal layout " .. layout .. "\nPlease use one of " .. printList(kLayouts))
|
||||
end
|
||||
end
|
||||
|
||||
-- process the name
|
||||
if name ~= nil then
|
||||
name = pandoc.utils.stringify(name)
|
||||
quarto.doc.include_text("in-header", "\\journal{" .. name .. "}")
|
||||
end
|
||||
end
|
||||
|
||||
return meta
|
||||
end,
|
||||
},
|
||||
{
|
||||
Cite = function(cite)
|
||||
if bibstyle == "number" or bibstyle == "super" then
|
||||
-- If we are numbered, force citations into normal mode
|
||||
-- as the author styles don't make sense
|
||||
for i, v in ipairs(cite.citations) do
|
||||
v.mode = "NormalCitation"
|
||||
end
|
||||
return cite
|
||||
end
|
||||
end,
|
||||
},
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
\usepackage{float}
|
||||
\makeatletter
|
||||
\let\oldlt\longtable
|
||||
\let\endoldlt\endlongtable
|
||||
\def\longtable{\@ifnextchar[\longtable@i \longtable@ii}
|
||||
\def\longtable@i[#1]{\begin{figure}[H]
|
||||
\onecolumn
|
||||
\begin{minipage}{0.5\textwidth}
|
||||
\oldlt[#1]
|
||||
}
|
||||
\def\longtable@ii{\begin{figure}[H]
|
||||
\onecolumn
|
||||
\begin{minipage}{0.5\textwidth}
|
||||
\oldlt
|
||||
}
|
||||
\def\endlongtable{\endoldlt
|
||||
\end{minipage}
|
||||
\twocolumn
|
||||
\end{figure}}
|
||||
\makeatother
|
||||
@@ -1,41 +0,0 @@
|
||||
\begin{frontmatter}
|
||||
\title{$title$ $if(subtitle)$ \\\large{$subtitle$} $endif$ }
|
||||
|
||||
$for(by-author)$\author[$for(by-author.affiliations)$$it.number$$sep$,$endfor$]{$by-author.name.literal$%
|
||||
$if(by-author.attributes.corresponding)$\corref{cor1}$endif$%
|
||||
$if(by-author.note.text)$\fnref{fn$by-author.note.number$}$endif$}
|
||||
$if(by-author.email)$ \ead{$by-author.email$} $endif$
|
||||
$endfor$
|
||||
$for(by-affiliation)$
|
||||
\affiliation[$it.number$]{organization={$it.name$},$if(it.address)$addressline={$it.address$}$endif$$if(it.city)$$if(it.address)$,$endif$city={$it.city$}$endif$$if(it.country)$$if(it.city)$,$elseif(it.address)$,$endif$country={$it.country$}$endif$$if(it.postal-code)$$if(it.country)$,$elseif(it.city)$,$elseif(it.address)$,$endif$postcode={$it.postal-code$}$endif$}
|
||||
$endfor$
|
||||
|
||||
\cortext[cor1]{Corresponding author}
|
||||
$for(by-author)$
|
||||
$if(by-author.note.text)$\fntext[fn$by-author.note.number$]{$by-author.note.text$}$endif$
|
||||
$endfor$
|
||||
|
||||
$if(abstract)$
|
||||
\begin{abstract}
|
||||
$abstract$
|
||||
\end{abstract}
|
||||
$endif$
|
||||
|
||||
$if(journal.graphical-abstract)$\begin{graphicalabstract}
|
||||
$journal.graphical-abstract$
|
||||
\end{graphicalabstract}
|
||||
$endif$
|
||||
|
||||
$if(journal.highlights)$\begin{highlights}
|
||||
$for(journal.highlights)$\item $it$$endfor$
|
||||
\end{highlights}
|
||||
$endif$
|
||||
|
||||
$if(keywords)$
|
||||
\begin{keyword}
|
||||
$for(keywords/allbutlast)$$keywords$ \sep $endfor$
|
||||
$for(keywords/last)$$keywords$$endfor$
|
||||
\end{keyword}
|
||||
$endif$
|
||||
\end{frontmatter}
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
\usepackage{enumitem}
|
||||
\usepackage{fontspec}
|
||||
\usepackage{float}
|
||||
\usepackage[normalem]{ulem}
|
||||
\usepackage{hyperref}
|
||||
\usepackage{nameref} %needed by zref-xr
|
||||
\usepackage{zref-xr,zref-hyperref,zref-user}
|
||||
\usepackage{xr-hyper}
|
||||
|
||||
\makeatletter
|
||||
\renewcommand{\title}[1]{\gdef\@title{\Large\textbf{#1}}} % Adjust \Huge or other font commands
|
||||
% \renewcommand{\author}[1]{\gdef\@author{\normalsize\textrm{#1}}} % Adjust \Huge or other font commands
|
||||
% \renewcommand{\author}[1]{\normalsize\textit{#1}} % Use \normalsize and \textit for customization
|
||||
\makeatother
|
||||
|
||||
\usepackage{adjustbox}
|
||||
% \usepackage{xcolor}
|
||||
\usepackage{mdframed}
|
||||
\newmdenv[topline=false,
|
||||
leftline=true,
|
||||
bottomline=false,
|
||||
rightline=false,
|
||||
linewidth=3pt,
|
||||
%backgroundcolor=lightgray,
|
||||
linecolor=gray!30,
|
||||
backgroundcolor=gray!5,
|
||||
skipabove=\topsep,
|
||||
skipbelow=\topsep,
|
||||
leftmargin=0pt,
|
||||
rightmargin=0pt,
|
||||
innertopmargin=0pt,
|
||||
innerbottommargin=0pt
|
||||
]{refquote}
|
||||
\newmdenv[topline=false,
|
||||
leftline=true,
|
||||
bottomline=false,
|
||||
rightline=false,
|
||||
linewidth=3pt,
|
||||
%backgroundcolor=lightgray,
|
||||
backgroundcolor=red!3!white,
|
||||
linecolor=red!30!white,
|
||||
skipabove=\topsep,
|
||||
skipbelow=\topsep,
|
||||
leftmargin=0pt,
|
||||
rightmargin=0pt,
|
||||
innertopmargin=10pt,
|
||||
innerbottommargin=10pt
|
||||
]{question}
|
||||
% setup hyperlink for page and line number
|
||||
\def\msname{MS}
|
||||
\def\smname{SM}
|
||||
\setenumerate{labelsep=*, leftmargin=1.0pc}
|
||||
%\zexternaldocument*{ManuscriptNew\veraa}
|
||||
\zexternaldocument*{\msname}
|
||||
\zexternaldocument*{\smname}
|
||||
\newcommand{\hlabel}[1]{\label{#1}\hypertarget{#1}{
|
||||
\linelabel{line:#1}}}
|
||||
%\externaldocument[si-]{\smname\veraa}[\smname\veraa.pdf]
|
||||
\makeatletter
|
||||
\newcommand{\clab}[2][]{
|
||||
\protected@write\@auxout{\let\clab\@secondoftwo}{
|
||||
\string\newlabel{r:#1}{{#2}{}}}%
|
||||
\hlabel{#1}#2\hlabel{#1end}}
|
||||
\makeatother
|
||||
\newcommand{\zhypera}[1]{\href[pdfnewwindow]{\msname.pdf\##1}{\\[1ex]\textbf{Page \zpageref{#1}, Line
|
||||
\zref{line:#1}--\zref{line:#1end}:}\\}}
|
||||
\newcommand{\cref}[1]{\begin{refquote}\zhypera{#1}{\zref{r:#1}}\\[-0.5ex]\end{refquote}}
|
||||
% \newenvironment{ra}[1][\unskip]{\par \noindent \\[-1ex] \textbf{Response/Action:}\par\bf}{\ \\}
|
||||
\renewenvironment{quote}{\begin{question}}{\end{question}}
|
||||
% \renewenvironment{verbatim}{\begin{ra}}{\end{ra}}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
\setlength{\parindent}{6pt}
|
||||
@@ -1 +0,0 @@
|
||||
/*-- scss:defaults --*/
|
||||
@@ -1,8 +0,0 @@
|
||||
title: Name Your References
|
||||
author: Shafayet Khan Shafee
|
||||
version: 1.1.0
|
||||
quarto-required: ">=1.2.0"
|
||||
contributes:
|
||||
filters:
|
||||
- nameref.lua
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
local str = pandoc.utils.stringify
|
||||
local p = quarto.log.output
|
||||
|
||||
function get_header_data(data, numbered)
|
||||
local get_headers = {
|
||||
-- get the Header text and header id from headers and
|
||||
-- insert them into table `data` passed into `get_header_data`
|
||||
Header = function(el)
|
||||
local id = el.identifier
|
||||
local number = numbered=="true" and el.attributes['number'] or ""
|
||||
local text = str(el.content):gsub("^[%d.]+ ", "")
|
||||
text = number .. " " .. text
|
||||
table.insert(data, {id = id, text = text})
|
||||
end,
|
||||
|
||||
-- get the id and title attribute from pandoc div, so the
|
||||
-- generated output has this id and can be referred with.
|
||||
Div = function(el)
|
||||
if el.attributes["link-id"] then
|
||||
local id = el.attributes["link-id"]
|
||||
local text = el.attributes["link-title"]
|
||||
table.insert(data, {id = id, text = text})
|
||||
end
|
||||
end
|
||||
}
|
||||
return get_headers
|
||||
end
|
||||
|
||||
|
||||
function change_ref(data)
|
||||
local change_rawinline = {
|
||||
-- change the nameref instance with pandoc.Link
|
||||
RawInline = function(el)
|
||||
for key, value in pairs(data) do
|
||||
if el.text:match("\\nameref{(.*)}") == value.id then
|
||||
local target = "#" .. value.id
|
||||
local link = pandoc.Link(value.text, target)
|
||||
return link
|
||||
end
|
||||
end
|
||||
end
|
||||
}
|
||||
return change_rawinline
|
||||
end
|
||||
|
||||
|
||||
local function add_div_id(div)
|
||||
return {
|
||||
-- add id to div with `cell-output-stdout` or
|
||||
-- `cell-output-display`
|
||||
Div = function(elem)
|
||||
if elem.classes:includes("cell-output-display")
|
||||
or elem.classes:includes("cell-output-stdout") then
|
||||
elem.identifier = div.attributes["link-id"]
|
||||
return elem
|
||||
end
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
function Div(el)
|
||||
-- target those div with attribute `link-id`
|
||||
if el.attributes["link-id"] then
|
||||
-- for markdown syntax (image or table) wrapped withing
|
||||
-- div with `link`
|
||||
if el.classes:includes('link') then
|
||||
el.identifier = el.attributes["link-id"]
|
||||
end
|
||||
return el:walk(add_div_id(el))
|
||||
end
|
||||
end
|
||||
|
||||
function Pandoc(doc)
|
||||
local meta = doc.meta
|
||||
local numbered
|
||||
local numbered = meta.nameref and str(meta.nameref['section-number'])
|
||||
local header_data = {}
|
||||
-- populate the header_data table
|
||||
doc:walk(get_header_data(header_data, numbered))
|
||||
-- generate named link inplaces with `\nameref`
|
||||
return doc:walk(change_ref(header_data))
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user