Merge branch 'develop' into 'main'
Develop See merge request jevalideca/fabriquedoc!1
This commit is contained in:
commit
494d7de387
9 changed files with 561 additions and 69 deletions
29
centered.lua
Normal file
29
centered.lua
Normal file
|
@ -0,0 +1,29 @@
|
|||
-- centered.lua
|
||||
-- Copyright (c) bpj on GitHub
|
||||
-- https://github.com/jgm/pandoc/issues/719#issuecomment-922019826
|
||||
-- GPL-2+ license
|
||||
|
||||
local center_for = {
|
||||
latex = {
|
||||
pre = pandoc.RawBlock('latex', '\\begin{center}'),
|
||||
post = pandoc.RawBlock('latex', '\\end{center}'),
|
||||
},
|
||||
-- add more as needed...
|
||||
}
|
||||
|
||||
function Div (div)
|
||||
if div.classes:includes('center') then
|
||||
if center_for[FORMAT] then
|
||||
local rv = {}
|
||||
if center_for[FORMAT].pre then
|
||||
rv[#rv+1] = center_for[FORMAT].pre
|
||||
end
|
||||
rv[#rv+1] = div
|
||||
if center_for[FORMAT].post then
|
||||
rv[#rv+1] = center_for[FORMAT].post
|
||||
end
|
||||
return rv
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
248
latex-emoji.lua
Normal file
248
latex-emoji.lua
Normal file
|
@ -0,0 +1,248 @@
|
|||
-- latex-emoji.lua
|
||||
--
|
||||
-- @copyright 2020 Takayuki YATO (aka. "ZR")
|
||||
-- GitHub: https://github.com/zr-tex8r
|
||||
-- Twitter: @zr_tex8r
|
||||
-- This program is distributed under the MIT License.
|
||||
--
|
||||
local filter_name = 'latex-emoji'
|
||||
---------------------------------------- helpers
|
||||
|
||||
--- Show debug log?
|
||||
local show_log = true
|
||||
--- The default emoji font
|
||||
local default_emojifont = 'TwemojiMozilla.ttf'
|
||||
|
||||
--- Use bxcoloremoji package?
|
||||
local bxcoloremoji = false
|
||||
--- The emoji font to use
|
||||
local emojifont, emojifontoptions = nil
|
||||
--- All used codepoints
|
||||
local ucs_used = {}
|
||||
--- The number of emoji text spans.
|
||||
local text_count = 0
|
||||
|
||||
local utils = require 'pandoc.utils'
|
||||
local concat, insert, pack, unpack =
|
||||
table.concat, table.insert, table.pack, table.unpack
|
||||
|
||||
--- Shows a debug log.
|
||||
local function log(fmt, ...)
|
||||
if not show_log then return end
|
||||
io.stderr:write(filter_name..": "..fmt:format(...).."\n")
|
||||
end
|
||||
|
||||
--- Aborts with an error message.
|
||||
local function abort(fmt, ...)
|
||||
error(filter_name..": "..fmt:format(...))
|
||||
end
|
||||
|
||||
--- Returns the Pandoc-or-ordinary type of v.
|
||||
-- @return A string that says type name.
|
||||
local function pantype(v)
|
||||
local t = type(v)
|
||||
return (t == 'table') and v.t or t
|
||||
end
|
||||
|
||||
--- Makes a comma-separated value string.
|
||||
-- @return A string.
|
||||
local function clist(...)
|
||||
local t, u = pack(...), {}
|
||||
for i = 1, t.n do
|
||||
local v = (t[i] == nil) and '' or tostring(t[i])
|
||||
if v ~= '' then insert(u, v) end
|
||||
end
|
||||
return concat(u, ',')
|
||||
end
|
||||
|
||||
--- Makes the sorted sequence of all keys of a given table.
|
||||
-- @return A sequence of strings.
|
||||
local function keys(t)
|
||||
local u = {}
|
||||
for k in pairs(t) do insert(u, k) end
|
||||
table.sort(u)
|
||||
return u
|
||||
end
|
||||
|
||||
--- Converts a singleton sequence to its element.
|
||||
-- @return The sole element of v if v is a singleton;
|
||||
-- v if v is not a table; otherwise an error is issued.
|
||||
local function tosingle(v, l)
|
||||
if type(v) ~= 'table' then return v end
|
||||
if #v == 1 then return tosingle(v[1], l) end
|
||||
abort("multiple values given: %s", l)
|
||||
end
|
||||
|
||||
--- Converts a value to a singleton sequence.
|
||||
-- @return The empty table if v is nil; v if v is a table;
|
||||
-- otherwise the singleton of v.
|
||||
local function toseq(v)
|
||||
if v == nil then return {}
|
||||
elseif type(v) == 'table' then return v
|
||||
else return {v}
|
||||
end
|
||||
end
|
||||
|
||||
--- Converts MetaInlines values inside a MetaValue to strings.
|
||||
-- @return The converted value. (v is not modified.)
|
||||
local function tostring_meta(v, l)
|
||||
if type(v) ~= 'table' then return v end
|
||||
if v.t == 'MetaList' or v.t == nil then
|
||||
local r = {}
|
||||
for k, e in pairs(v) do r[k] = tostring_meta(e, l) end
|
||||
return r
|
||||
elseif v.t == 'MetaInlines' then
|
||||
return utils.stringify(v)
|
||||
else abort("cannot stringify: %s", v.t, l)
|
||||
end
|
||||
end
|
||||
|
||||
--- Gets the source to go into the header.
|
||||
-- @return LaTeX source string
|
||||
local function get_header()
|
||||
if not bxcoloremoji or not next(ucs_used) then
|
||||
return nil
|
||||
end
|
||||
return ([[
|
||||
\usepackage[%s]{bxcoloremoji}
|
||||
\newcommand*{\panEmoji}{\coloremoji}
|
||||
]]):format(clist(emojifont, unpack(emojifontoptions)))
|
||||
end
|
||||
|
||||
--- Gets the source to go into the head of body.
|
||||
-- @return LaTeX source string
|
||||
local function get_prologue()
|
||||
if bxcoloremoji or not next(ucs_used) then
|
||||
return nil
|
||||
end
|
||||
local fname = emojifont or default_emojifont
|
||||
local fopts = clist('Renderer=HarfBuzz', unpack(emojifontoptions));
|
||||
local ucs = keys(ucs_used)
|
||||
for i = 1, #ucs do
|
||||
ucs[i] = ('"%X'):format(ucs[i])
|
||||
end
|
||||
local dcrsrc = concat(ucs, ',\n')
|
||||
return ([[
|
||||
\makeatletter
|
||||
\ifnum0\ifdefined\directlua\directlua{
|
||||
if ("\luaescapestring{\luatexbanner}"):match("LuaHBTeX") then tex.write("1") end
|
||||
}\fi>\z@ %% LuaHBTeX is ok
|
||||
\setfontface\p@emoji@font{%s}[%s]
|
||||
\else
|
||||
\@latex@error{You must install a new TeX system (TeX Live 2020)\MessageBreak
|
||||
and then use 'lualatex' engine to print emoji}
|
||||
{The compilation will be aborted.}
|
||||
\let\p@emoji@font\relax
|
||||
\fi
|
||||
\ifdefined\ltjdefcharrange
|
||||
\ltjdefcharrange{208}{
|
||||
%s}
|
||||
\ltjsetparameter{jacharrange={-208}}
|
||||
\fi
|
||||
\newcommand*{\panEmoji}[1]{{\p@emoji@font#1}}
|
||||
\makeatother
|
||||
]]):format(fname, fopts, dcrsrc)
|
||||
end
|
||||
|
||||
--- For debug.
|
||||
local function inspect(v)
|
||||
local t = type(v)
|
||||
if t == 'userdata' or t == 'function' or t == 'nil' then return t
|
||||
elseif t == 'table' then
|
||||
local u, tag = {}, (v.t or 'table')
|
||||
if tag == 'Str' then return tag..'{'..v.text..'}' end
|
||||
for i = 1, #v do u[i] = inspect(v[i]) end
|
||||
return tag..'{'..concat(u, ';')..'}'
|
||||
else return tostring(v)
|
||||
end
|
||||
end
|
||||
|
||||
---------------------------------------- phase 'readmeta'
|
||||
|
||||
--- For Meta elements.
|
||||
local function readmeta_Meta (meta)
|
||||
-- bxcoloremoji
|
||||
if meta.bxcoloremoji == nil then
|
||||
bxcoloremoji = false
|
||||
elseif type(meta.bxcoloremoji) == 'boolean' then
|
||||
bxcoloremoji = meta.bxcoloremoji
|
||||
else
|
||||
abort("not a boolean value: bxcoloremoji")
|
||||
end
|
||||
log('bxcoloremoji = %s', bxcoloremoji)
|
||||
-- emojifont
|
||||
emojifont = tostring_meta(meta.emojifont, "emojifont")
|
||||
emojifont = tosingle(emojifont, "emojifont")
|
||||
log('emojifont = %s', emojifont)
|
||||
-- emojifontoptions
|
||||
emojifontoptions = tostring_meta(meta.emojifontoptions, "emojifontoptions")
|
||||
emojifontoptions = toseq(emojifontoptions)
|
||||
for i in ipairs(emojifontoptions) do
|
||||
emojifontoptions[i] = tosingle(emojifontoptions[i], "emojifontoptions element")
|
||||
log('emojifontoptions = %s', emojifontoptions[i])
|
||||
end
|
||||
end
|
||||
|
||||
---------------------------------------- phase 'mainproc'
|
||||
|
||||
--- For Span element.
|
||||
local function mainproc_Span(span)
|
||||
if span.classes:includes('emoji', 1) then
|
||||
text_count = text_count + 1
|
||||
local str = utils.stringify(span.content)
|
||||
for p, uc in utf8.codes(str) do
|
||||
if not ucs_used[uc] and uc >= 0x100 then
|
||||
log("emoji character: U+%04X", uc)
|
||||
ucs_used[uc] = true
|
||||
end
|
||||
end
|
||||
insert(span.content, 1, pandoc.RawInline('latex', [[\panEmoji{]]))
|
||||
insert(span.content, pandoc.RawInline('latex', [[}]]))
|
||||
return span.content
|
||||
end
|
||||
end
|
||||
|
||||
--- For Meta elements.
|
||||
local function mainproc_Meta(meta)
|
||||
local src = get_header()
|
||||
if src then
|
||||
local headers = meta['header-includes']
|
||||
if headers == nil then
|
||||
headers = pandoc.MetaList({})
|
||||
elseif pantype(headers) == 'MetaList' then
|
||||
abort("unexpected metavalue type: header-includes")
|
||||
end
|
||||
insert(headers, pandoc.MetaBlocks{pandoc.RawBlock('latex', src)})
|
||||
meta['header-includes'] = headers
|
||||
log("header successfully appended")
|
||||
return meta
|
||||
end
|
||||
end
|
||||
|
||||
--- For the whole document.
|
||||
local function mainproc_Pandoc(doc)
|
||||
log("number of emoji spans: %s", text_count)
|
||||
local src = get_prologue()
|
||||
if src then
|
||||
insert(doc.blocks, 1, pandoc.RawBlock('latex', src))
|
||||
log("prologue successfully inserted")
|
||||
return doc
|
||||
end
|
||||
end
|
||||
|
||||
---------------------------------------- the filter
|
||||
if FORMAT == 'latex' then
|
||||
return {
|
||||
{-- phase 'readmeta'
|
||||
Meta = readmeta_Meta;
|
||||
};
|
||||
{-- phase 'mainproc'
|
||||
Span = mainproc_Span;
|
||||
Meta = mainproc_Meta;
|
||||
Pandoc = mainproc_Pandoc;
|
||||
};
|
||||
}
|
||||
else
|
||||
log("format '%s' in not supported", FORMAT)
|
||||
end
|
||||
---------------------------------------- done
|
110
main.py
110
main.py
|
@ -12,6 +12,7 @@ import os
|
|||
from wand.image import Image
|
||||
from wand.color import Color
|
||||
import shutil
|
||||
import cv2
|
||||
|
||||
|
||||
class DocumentSpecs(BaseModel):
|
||||
|
@ -24,9 +25,12 @@ class DocumentSpecs(BaseModel):
|
|||
fontsize: int
|
||||
paperwidth: int
|
||||
paperheight: int
|
||||
ratio: int
|
||||
margin: int
|
||||
vmargin: int
|
||||
extension: str
|
||||
fps: int
|
||||
stilltime: int
|
||||
|
||||
|
||||
class FormatParameters(BaseModel):
|
||||
|
@ -36,9 +40,12 @@ class FormatParameters(BaseModel):
|
|||
fontsize: int
|
||||
paperwidth: int
|
||||
paperheight: int
|
||||
ratio: int
|
||||
margin: int
|
||||
vmargin: int
|
||||
extension: str
|
||||
fps: int
|
||||
stilltime: int
|
||||
|
||||
|
||||
class Styles(BaseModel):
|
||||
|
@ -70,12 +77,54 @@ def convert_pdf(filename, filetype, output_path, resolution=300):
|
|||
img.alpha_channel = 'remove'
|
||||
|
||||
image_filename = os.path.splitext(os.path.basename(filename))[0]
|
||||
image_filename = f'{image_filename}-{i}.{filetype}'
|
||||
image_filename = f'{image_filename}-{i:03}.{filetype}'
|
||||
image_filename = os.path.join(output_path, image_filename)
|
||||
|
||||
img.save(filename=image_filename)
|
||||
|
||||
|
||||
def convert_video(images_path, output_path, width, height, fps, stilltime):
|
||||
"""
|
||||
Convert images in output_path into a mp4 file usine OpenCV.
|
||||
:param images_path:
|
||||
:param output_path:
|
||||
:param images_path:
|
||||
:param width:
|
||||
:param height:
|
||||
:return:
|
||||
"""
|
||||
|
||||
# define a frame array
|
||||
frame_array = []
|
||||
|
||||
# list all files in images_path
|
||||
files = [f for f in os.listdir(images_path) if os.path.isfile(os.path.join(images_path, f))]
|
||||
# sort the files
|
||||
files.sort()
|
||||
|
||||
# create a video writer object
|
||||
|
||||
for i in range(len(files)):
|
||||
file = os.path.join(images_path, files[i])
|
||||
logging.log(logging.INFO, f'Converting {file} to mp4')
|
||||
img = cv2.imread(file)
|
||||
for j in range(fps*stilltime):
|
||||
frame_array.append(img)
|
||||
|
||||
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
|
||||
video_writer = cv2.VideoWriter(output_path,
|
||||
fourcc,
|
||||
fps,
|
||||
(width, height))
|
||||
|
||||
for i in range(len(frame_array)):
|
||||
# writing to a image array
|
||||
video_writer.write(frame_array[i])
|
||||
|
||||
video_writer.release()
|
||||
logging.log(logging.INFO, f'Finished converting {output_path}')
|
||||
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
|
@ -117,10 +166,9 @@ async def get_format_parameters(style: str, format: str):
|
|||
async def generer(specs: DocumentSpecs):
|
||||
header_file = f'{os.getcwd()}/styles/{specs.style}/{specs.format}/header.tex'
|
||||
cover_file = f'{os.getcwd()}/styles/{specs.style}/{specs.format}/cover.tex'
|
||||
datef = datetime.datetime.now().strftime("%m-%d-%Y")
|
||||
datef = datetime.datetime.now().strftime("%Y-%m-%d")
|
||||
os.makedirs("out", exist_ok=True)
|
||||
output_file = f"./out/{specs.style}-{specs.format}-{datef}-output.pdf"
|
||||
filters = []
|
||||
filters = ['latex-emoji.lua', 'centered.lua']
|
||||
pdoc_args = [
|
||||
f'--include-in-header={header_file}',
|
||||
f'--include-after-body={cover_file}',
|
||||
|
@ -130,42 +178,64 @@ async def generer(specs: DocumentSpecs):
|
|||
f'--pdf-engine={specs.pdfengine}',
|
||||
'-V', f'linkcolor={specs.linkcolor}',
|
||||
'-V', f'fontsize={specs.fontsize}pt',
|
||||
'-V', f'geometry:paperwidth={specs.paperwidth / 300}in',
|
||||
'-V', f'geometry:paperheight={specs.paperheight / 300}in',
|
||||
'-V', f'geometry:margin={specs.margin / 300}in',
|
||||
'-V', f'geometry:vmargin={specs.vmargin / 300}in'
|
||||
'-V', f'geometry:paperwidth={round(specs.paperwidth * specs.ratio / 100, -1) / 300}in',
|
||||
'-V', f'geometry:paperheight={round(specs.paperheight * specs.ratio / 100, -1) / 300}in',
|
||||
'-V', f'geometry:left={specs.margin / 300}in',
|
||||
'-V', f'geometry:right={specs.margin / 300}in',
|
||||
'-V', f'geometry:top={specs.vmargin / 300}in',
|
||||
'-V', f'geometry:bottom={specs.vmargin / 300}in'
|
||||
]
|
||||
pdf_file_path = f"./out/{specs.style}-{specs.format}-{datef}-output.pdf"
|
||||
images_path = f"./out/{specs.style}-{specs.format}-{datef}-images"
|
||||
try:
|
||||
logging.info("Dossier courant = " + os.getcwd())
|
||||
|
||||
result = pypandoc.convert_text(source=specs.content,
|
||||
to='pdf',
|
||||
format='markdown+implicit_figures+smart',
|
||||
format='markdown+implicit_figures+smart+emoji',
|
||||
encoding='utf-8',
|
||||
extra_args=pdoc_args,
|
||||
filters=filters,
|
||||
cworkdir=os.getcwd(),
|
||||
outputfile=output_file
|
||||
outputfile=pdf_file_path
|
||||
)
|
||||
|
||||
except RuntimeError as rerr:
|
||||
logging.exception(rerr)
|
||||
except OSError as oerr:
|
||||
logging.exception(oerr)
|
||||
if specs.extension in ["png", "jpg"]:
|
||||
zip_filename = os.path.splitext(os.path.basename(output_file))[0]
|
||||
png_output_dir = "./png_output"
|
||||
if not os.path.exists(png_output_dir):
|
||||
os.mkdir(png_output_dir)
|
||||
if specs.extension in ["png", "jpg", "mp4"]:
|
||||
filename = os.path.join("out", os.path.splitext(os.path.basename(pdf_file_path))[0])
|
||||
if not os.path.exists(images_path):
|
||||
os.mkdir(images_path)
|
||||
conversion_extension = specs.extension
|
||||
output_extension = specs.extension
|
||||
if specs.extension in ["mp4"]:
|
||||
conversion_extension = "jpg"
|
||||
try:
|
||||
convert_pdf(output_file, specs.extension, png_output_dir, resolution=300)
|
||||
shutil.make_archive(zip_filename, 'zip', png_output_dir)
|
||||
shutil.rmtree(png_output_dir)
|
||||
convert_pdf(pdf_file_path,
|
||||
conversion_extension,
|
||||
images_path,
|
||||
resolution=300)
|
||||
if specs.extension in ["png", "jpg"]:
|
||||
shutil.make_archive(base_name=filename,
|
||||
format='zip',
|
||||
root_dir=images_path)
|
||||
output_extension = "zip"
|
||||
shutil.rmtree(images_path)
|
||||
if specs.extension in ["mp4"]:
|
||||
output_extension = "mp4"
|
||||
convert_video(images_path=images_path,
|
||||
output_path=f"{filename}.{output_extension}",
|
||||
width=specs.paperwidth,
|
||||
height=specs.paperheight,
|
||||
fps=specs.fps,
|
||||
stilltime=specs.stilltime)
|
||||
except Exception as e:
|
||||
logging.exception(e)
|
||||
return FileResponse(zip_filename + ".zip")
|
||||
return FileResponse(f"{filename}.{output_extension}")
|
||||
elif specs.extension == "pdf":
|
||||
return FileResponse(output_file)
|
||||
return FileResponse(pdf_file_path)
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
|
|
@ -1,26 +1,24 @@
|
|||
h11~=0.14.0
|
||||
pip~=21.3.1
|
||||
wheel~=0.37.1
|
||||
PyYAML~=6.0
|
||||
anyio~=3.6.2
|
||||
sniffio~=1.3.0
|
||||
click~=8.1.3
|
||||
httpcore~=0.16.3
|
||||
idna~=3.4
|
||||
rfc3986~=1.5.0
|
||||
certifi~=2022.12.7
|
||||
pandoc~=2.3
|
||||
ply~=3.11
|
||||
plumbum~=1.8.0
|
||||
uvloop~=0.17.0
|
||||
fastapi~=0.88.0
|
||||
starlette~=0.22.0
|
||||
fastapi~=0.91.0
|
||||
starlette~=0.24.0
|
||||
pydantic~=1.10.2
|
||||
websockets~=10.4
|
||||
uvicorn~=0.20.0
|
||||
httptools~=0.5.0
|
||||
watchfiles~=0.18.1
|
||||
httpx~=0.23.1
|
||||
setuptools~=60.2.0
|
||||
setuptools~=67.2.0
|
||||
pypandoc~=1.10
|
||||
Wand~=0.6.10
|
||||
Wand~=0.6.10
|
||||
opencv-python~=4.7.0.68
|
|
@ -6,8 +6,11 @@
|
|||
"fontsize": 12,
|
||||
"paperwidth": 2480,
|
||||
"paperheight": 3507,
|
||||
"ratio": 100,
|
||||
"margin": 248,
|
||||
"vmargin": 350,
|
||||
"vmargin": 525,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "pdf"
|
||||
},
|
||||
"lettre": {
|
||||
|
@ -17,8 +20,11 @@
|
|||
"fontsize": 12,
|
||||
"paperwidth": 2550,
|
||||
"paperheight": 3300,
|
||||
"ratio": 100,
|
||||
"margin": 255,
|
||||
"vmargin": 330,
|
||||
"vmargin": 495,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "pdf"
|
||||
},
|
||||
"linkedin": {
|
||||
|
@ -28,8 +34,11 @@
|
|||
"fontsize": 16,
|
||||
"paperwidth": 1200,
|
||||
"paperheight": 1200,
|
||||
"margin": 120,
|
||||
"vmargin": 120,
|
||||
"ratio": 100,
|
||||
"margin": 180,
|
||||
"vmargin": 180,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "jpg"
|
||||
},
|
||||
"instagram": {
|
||||
|
@ -39,8 +48,11 @@
|
|||
"fontsize": 16,
|
||||
"paperwidth": 1080,
|
||||
"paperheight": 1920,
|
||||
"ratio": 100,
|
||||
"margin": 108,
|
||||
"vmargin": 192,
|
||||
"vmargin": 244,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "jpg"
|
||||
},
|
||||
"pinterest": {
|
||||
|
@ -50,8 +62,11 @@
|
|||
"fontsize": 16,
|
||||
"paperwidth": 735,
|
||||
"paperheight": 1102,
|
||||
"ratio": 100,
|
||||
"margin": 75,
|
||||
"vmargin": 110,
|
||||
"vmargin": 165,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "jpg"
|
||||
},
|
||||
"slide43": {
|
||||
|
@ -61,8 +76,11 @@
|
|||
"fontsize": 16,
|
||||
"paperwidth": 2560,
|
||||
"paperheight": 1920,
|
||||
"ratio": 100,
|
||||
"margin": 256,
|
||||
"vmargin": 192,
|
||||
"vmargin": 288,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "pdf"
|
||||
},
|
||||
"slide169": {
|
||||
|
@ -72,8 +90,11 @@
|
|||
"fontsize": 16,
|
||||
"paperwidth": 2560,
|
||||
"paperheight": 1440,
|
||||
"ratio": 100,
|
||||
"margin": 256,
|
||||
"vmargin": 144,
|
||||
"vmargin": 216,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "pdf"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,11 @@
|
|||
"fontsize": 12,
|
||||
"paperwidth": 2480,
|
||||
"paperheight": 3507,
|
||||
"ratio": 100,
|
||||
"margin": 248,
|
||||
"vmargin": 350,
|
||||
"vmargin": 525,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "pdf"
|
||||
},
|
||||
"lettre": {
|
||||
|
@ -17,8 +20,11 @@
|
|||
"fontsize": 12,
|
||||
"paperwidth": 2550,
|
||||
"paperheight": 3300,
|
||||
"ratio": 100,
|
||||
"margin": 255,
|
||||
"vmargin": 330,
|
||||
"vmargin": 495,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "pdf"
|
||||
},
|
||||
"linkedin": {
|
||||
|
@ -28,8 +34,11 @@
|
|||
"fontsize": 16,
|
||||
"paperwidth": 1200,
|
||||
"paperheight": 1200,
|
||||
"margin": 120,
|
||||
"vmargin": 120,
|
||||
"ratio": 100,
|
||||
"margin": 180,
|
||||
"vmargin": 180,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "jpg"
|
||||
},
|
||||
"instagram": {
|
||||
|
@ -39,8 +48,11 @@
|
|||
"fontsize": 16,
|
||||
"paperwidth": 1080,
|
||||
"paperheight": 1920,
|
||||
"ratio": 100,
|
||||
"margin": 108,
|
||||
"vmargin": 192,
|
||||
"vmargin": 244,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "jpg"
|
||||
},
|
||||
"pinterest": {
|
||||
|
@ -50,8 +62,11 @@
|
|||
"fontsize": 16,
|
||||
"paperwidth": 735,
|
||||
"paperheight": 1102,
|
||||
"ratio": 100,
|
||||
"margin": 75,
|
||||
"vmargin": 110,
|
||||
"vmargin": 165,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "jpg"
|
||||
},
|
||||
"slide43": {
|
||||
|
@ -61,8 +76,11 @@
|
|||
"fontsize": 16,
|
||||
"paperwidth": 2560,
|
||||
"paperheight": 1920,
|
||||
"ratio": 100,
|
||||
"margin": 256,
|
||||
"vmargin": 192,
|
||||
"vmargin": 288,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "pdf"
|
||||
},
|
||||
"slide169": {
|
||||
|
@ -72,8 +90,11 @@
|
|||
"fontsize": 16,
|
||||
"paperwidth": 2560,
|
||||
"paperheight": 1440,
|
||||
"ratio": 100,
|
||||
"margin": 256,
|
||||
"vmargin": 144,
|
||||
"vmargin": 216,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "pdf"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,11 @@
|
|||
"fontsize": 12,
|
||||
"paperwidth": 2480,
|
||||
"paperheight": 3507,
|
||||
"ratio": 100,
|
||||
"margin": 248,
|
||||
"vmargin": 350,
|
||||
"vmargin": 525,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "pdf"
|
||||
},
|
||||
"lettre": {
|
||||
|
@ -17,8 +20,11 @@
|
|||
"fontsize": 12,
|
||||
"paperwidth": 2550,
|
||||
"paperheight": 3300,
|
||||
"ratio": 100,
|
||||
"margin": 255,
|
||||
"vmargin": 330,
|
||||
"vmargin": 495,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "pdf"
|
||||
},
|
||||
"linkedin": {
|
||||
|
@ -28,8 +34,11 @@
|
|||
"fontsize": 16,
|
||||
"paperwidth": 1200,
|
||||
"paperheight": 1200,
|
||||
"margin": 120,
|
||||
"vmargin": 120,
|
||||
"ratio": 100,
|
||||
"margin": 180,
|
||||
"vmargin": 180,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "jpg"
|
||||
},
|
||||
"instagram": {
|
||||
|
@ -39,8 +48,11 @@
|
|||
"fontsize": 16,
|
||||
"paperwidth": 1080,
|
||||
"paperheight": 1920,
|
||||
"ratio": 100,
|
||||
"margin": 108,
|
||||
"vmargin": 192,
|
||||
"vmargin": 244,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "jpg"
|
||||
},
|
||||
"pinterest": {
|
||||
|
@ -50,8 +62,11 @@
|
|||
"fontsize": 16,
|
||||
"paperwidth": 735,
|
||||
"paperheight": 1102,
|
||||
"ratio": 100,
|
||||
"margin": 75,
|
||||
"vmargin": 110,
|
||||
"vmargin": 165,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "jpg"
|
||||
},
|
||||
"slide43": {
|
||||
|
@ -61,8 +76,11 @@
|
|||
"fontsize": 16,
|
||||
"paperwidth": 2560,
|
||||
"paperheight": 1920,
|
||||
"ratio": 100,
|
||||
"margin": 256,
|
||||
"vmargin": 192,
|
||||
"vmargin": 288,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "pdf"
|
||||
},
|
||||
"slide169": {
|
||||
|
@ -72,8 +90,11 @@
|
|||
"fontsize": 16,
|
||||
"paperwidth": 2560,
|
||||
"paperheight": 1440,
|
||||
"ratio": 100,
|
||||
"margin": 256,
|
||||
"vmargin": 144,
|
||||
"vmargin": 216,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "pdf"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,11 @@
|
|||
"fontsize": 12,
|
||||
"paperwidth": 2480,
|
||||
"paperheight": 3507,
|
||||
"ratio": 100,
|
||||
"margin": 248,
|
||||
"vmargin": 350,
|
||||
"vmargin": 525,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "pdf"
|
||||
},
|
||||
"lettre": {
|
||||
|
@ -17,8 +20,11 @@
|
|||
"fontsize": 12,
|
||||
"paperwidth": 2550,
|
||||
"paperheight": 3300,
|
||||
"ratio": 100,
|
||||
"margin": 255,
|
||||
"vmargin": 330,
|
||||
"vmargin": 495,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "pdf"
|
||||
},
|
||||
"linkedin": {
|
||||
|
@ -28,8 +34,11 @@
|
|||
"fontsize": 16,
|
||||
"paperwidth": 1200,
|
||||
"paperheight": 1200,
|
||||
"margin": 120,
|
||||
"vmargin": 120,
|
||||
"ratio": 100,
|
||||
"margin": 180,
|
||||
"vmargin": 180,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "jpg"
|
||||
},
|
||||
"instagram": {
|
||||
|
@ -39,8 +48,11 @@
|
|||
"fontsize": 16,
|
||||
"paperwidth": 1080,
|
||||
"paperheight": 1920,
|
||||
"ratio": 100,
|
||||
"margin": 108,
|
||||
"vmargin": 192,
|
||||
"vmargin": 244,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "jpg"
|
||||
},
|
||||
"pinterest": {
|
||||
|
@ -50,8 +62,11 @@
|
|||
"fontsize": 16,
|
||||
"paperwidth": 735,
|
||||
"paperheight": 1102,
|
||||
"ratio": 100,
|
||||
"margin": 75,
|
||||
"vmargin": 110,
|
||||
"vmargin": 165,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "jpg"
|
||||
},
|
||||
"slide43": {
|
||||
|
@ -61,8 +76,11 @@
|
|||
"fontsize": 16,
|
||||
"paperwidth": 2560,
|
||||
"paperheight": 1920,
|
||||
"ratio": 100,
|
||||
"margin": 256,
|
||||
"vmargin": 192,
|
||||
"vmargin": 288,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "pdf"
|
||||
},
|
||||
"slide169": {
|
||||
|
@ -72,8 +90,11 @@
|
|||
"fontsize": 16,
|
||||
"paperwidth": 2560,
|
||||
"paperheight": 1440,
|
||||
"ratio": 100,
|
||||
"margin": 256,
|
||||
"vmargin": 144,
|
||||
"vmargin": 216,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "pdf"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,16 +10,44 @@ Accept: application/zip
|
|||
"linkcolor": "blue",
|
||||
"tocdepth": 2,
|
||||
"pdfengine": "lualatex",
|
||||
"content": "# Ceci est un titre\n## Ceci est un sous-titre\n\nCeci est un paragraphe\n\n## Ceci est un autre sous-titre\n\n> Ceci est du code",
|
||||
"content": "# Ceci est un titre\n## Ceci est un sous-titre\n\nCeci est un paragraphe\n\n## Ceci est un autre sous-titre\n\n> Ceci est du code\n\nCeci est un emoji :heart_eyes:\n\n::: {.center}\nCeci est centré\n:::",
|
||||
"fontsize": 14,
|
||||
"paperwidth": 1080,
|
||||
"paperheight": 1920,
|
||||
"ratio": 100,
|
||||
"margin": 180,
|
||||
"vmargin": 180,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "jpg"
|
||||
}
|
||||
|
||||
###
|
||||
|
||||
GET http://127.0.0.1:8000/generer/
|
||||
Content-Type: application/json
|
||||
Accept: application/zip
|
||||
|
||||
{
|
||||
"format": "instagram",
|
||||
"style": "jevalideca",
|
||||
"linkcolor": "blue",
|
||||
"tocdepth": 2,
|
||||
"pdfengine": "lualatex",
|
||||
"content": "# Ceci est un titre\n## Ceci est un sous-titre\n\nCeci est un paragraphe\n\n## Ceci est un autre sous-titre\n\n> Ceci est du code\n\nCeci est un emoji :heart_eyes:\n\n::: {.center}\nCeci est centré\n:::",
|
||||
"fontsize": 14,
|
||||
"paperwidth": 1080,
|
||||
"paperheight": 1920,
|
||||
"ratio": 100,
|
||||
"margin": 180,
|
||||
"vmargin": 180,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "mp4"
|
||||
}
|
||||
|
||||
###
|
||||
|
||||
GET http://127.0.0.1:8000/generer/
|
||||
Content-Type: application/json
|
||||
Accept: application/pdf
|
||||
|
@ -30,11 +58,15 @@ Accept: application/pdf
|
|||
"linkcolor": "blue",
|
||||
"tocdepth": 2,
|
||||
"pdfengine": "lualatex",
|
||||
"content": "# Ceci est un titre\n## Ceci est un sous-titre\n\nCeci est un paragraphe\n\n## Ceci est un autre sous-titre\n\n> Ceci est du code",
|
||||
"content": "# Ceci est un titre\n## Ceci est un sous-titre\n\nCeci est un paragraphe\n\n## Ceci est un autre sous-titre\n\n> Ceci est du code\n\nCeci est un emoji :heart_eyes:\n\n::: {.center}\nCeci est centré\n:::",
|
||||
"fontsize": 14,
|
||||
"paperwidth": 1080,
|
||||
"paperheight": 1080,
|
||||
"ratio": 100,
|
||||
"margin": 90,
|
||||
"vmargin": 90,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "pdf"
|
||||
}
|
||||
|
||||
|
@ -50,13 +82,16 @@ Accept: application/pdf
|
|||
"linkcolor": "blue",
|
||||
"tocdepth": 2,
|
||||
"pdfengine": "lualatex",
|
||||
"content": "# Comment améliorer ma sécurité informatique\n\n20 défis gratuits de 2 minutes chacun !",
|
||||
"content": "# Ceci est un titre\n## Ceci est un sous-titre\n\nCeci est un paragraphe\n\n## Ceci est un autre sous-titre\n\n> Ceci est du code\n\nCeci est un emoji :heart_eyes:\n\n::: {.center}\nCeci est centré\n:::",
|
||||
"fontsize": 20,
|
||||
"paperwidth": 1080,
|
||||
"paperheight": 1080,
|
||||
"ratio": 100,
|
||||
"margin": 180,
|
||||
"extension": "jpg",
|
||||
"vmargin": 300
|
||||
"vmargin": 300,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "jpg"
|
||||
}
|
||||
|
||||
###
|
||||
|
@ -67,20 +102,48 @@ Accept: application/pdf
|
|||
|
||||
{
|
||||
"format": "slide169",
|
||||
"style": "jevalideca",
|
||||
"style": "lcm",
|
||||
"linkcolor": "blue",
|
||||
"tocdepth": 2,
|
||||
"pdfengine": "lualatex",
|
||||
"content": "# Ceci est un titre\n## Ceci est un sous-titre\n\nCeci est un paragraphe\n\n## Ceci est un autre sous-titre\n\n> Ceci est du code",
|
||||
"content": "# Ceci est un titre\n## Ceci est un sous-titre\n\nCeci est un paragraphe\n\n## Ceci est un autre sous-titre\n\n> Ceci est du code\n\nCeci est un emoji :heart_eyes:\n\n::: {.center}\nCeci est centré\n:::",
|
||||
"fontsize": 14,
|
||||
"paperwidth": 1920,
|
||||
"paperheight": 1080,
|
||||
"margin": 90,
|
||||
"paperwidth": 2560,
|
||||
"paperheight": 1440,
|
||||
"ratio": 100,
|
||||
"margin": 256,
|
||||
"vmargin": 216,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "jpg"
|
||||
}
|
||||
|
||||
###
|
||||
|
||||
GET http://127.0.0.1:8000/generer/
|
||||
Content-Type: application/json
|
||||
Accept: application/pdf
|
||||
|
||||
{
|
||||
"format": "slide169",
|
||||
"style": "lcm",
|
||||
"linkcolor": "blue",
|
||||
"tocdepth": 2,
|
||||
"pdfengine": "lualatex",
|
||||
"content": "# Ceci est un titre\n## Ceci est un sous-titre\n\nCeci est un paragraphe\n\n## Ceci est un autre sous-titre\n\n> Ceci est du code\n\nCeci est un emoji :heart_eyes:\n\n::: {.center}\nCeci est centré\n:::",
|
||||
"fontsize": 14,
|
||||
"paperwidth": 2560,
|
||||
"paperheight": 1440,
|
||||
"ratio": 100,
|
||||
"margin": 256,
|
||||
"vmargin": 216,
|
||||
"fps": 15,
|
||||
"stilltime": 2,
|
||||
"extension": "mp4"
|
||||
}
|
||||
|
||||
###
|
||||
|
||||
GET http://127.0.0.1:8000/format_parameters/jevalideca/slide169/
|
||||
Content-Type: application/json
|
||||
Accept: application/pdf
|
Loading…
Reference in a new issue