Skip to content

Commit

Permalink
feat(export): supprime l'utilisation de Pandoc pour se baser sur styl…
Browse files Browse the repository at this point in the history
…o-export
  • Loading branch information
thom4parisot committed Oct 14, 2024
1 parent 99e62bb commit 163d1d8
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 208 deletions.
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,13 @@ Plus d'informations sur [la documentation](http://stylo-doc.ecrituresnumeriques.

- Node.js v18+
- MongoDB
- (optionnel) Pandoc, pour le [service d'export](./export)

## Sous MacOS

```bash
brew tap mongodb/brew

brew install pandoc mongodb-community nvm
brew install mongodb-community nvm
brew install --cask docker

nvm install v18 --default
Expand Down
47 changes: 1 addition & 46 deletions export/dockerfile
Original file line number Diff line number Diff line change
@@ -1,49 +1,4 @@
FROM node:18-bullseye

WORKDIR /usr/src/app

# install graphviz
RUN export DEBIAN_FRONTEND=noninteractive \
&& apt-get update -y \
&& apt-get upgrade -y \
&& apt-get install -y \
abcm2ps \
ca-certificates \
cm-super \
curl \
fontconfig \
fonts-liberation \
git \
graphviz \
imagemagick \
inotify-tools \
make \
python3-pygraphviz \
python3 \
wget \
&& apt-get clean -y \
&& rm -rf /var/lib/apt/lists/*

#install pandoc
ENV PKGREL 1
ENV VERSION 2.12
ARG TARGETARCH=amd64
ADD https://github.com/jgm/pandoc/releases/download/${VERSION}/pandoc-${VERSION}-${PKGREL}-${TARGETARCH}.deb /pandoc.deb
RUN export DEBIAN_FRONTEND=noninteractive \
&& dpkg -i /pandoc.deb \
&& rm /pandoc.deb

RUN git clone --single-branch --branch 1.4.3 https://github.com/jgm/pandocfilters.git /pandocfilters \
&& cd /pandocfilters \
&& python3 setup.py install \
&& cp examples/*.py /usr/bin \
&& ls examples/*.py > /installed-pandocfilters.txt \
&& rm -rf /pandocfilters

ADD vendors/git-diff.py /usr/bin/git-diff.py
RUN echo "examples/git-diff.py" >> /installed-pandocfilters.txt

RUN sed -i 's#examples#/usr/bin#' /installed-pandocfilters.txt
FROM node:18-alpine

# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
Expand Down
124 changes: 34 additions & 90 deletions export/src/export.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
const fs = require('node:fs').promises
const path = require('node:path')
const os = require('node:os')
const util = require('node:util')
const exec = util.promisify(require('node:child_process').exec)

const config = require('./config.js')
const archiver = require('archiver')

Expand All @@ -13,6 +7,7 @@ const { normalize } = require('./helpers/filename')
const { getArticleById, getVersionById, getCorpusById } = require('./graphql')

const canonicalBaseUrl = config.get('export.canonicalBaseUrl')
const exportEndpoint = config.get('export.urlEndpoint')

const exportZip = async ({ bib, yaml, md, id, versionId, title }, res, _) => {
const filename = `${normalize(title)}.zip`
Expand All @@ -25,101 +20,50 @@ const exportZip = async ({ bib, yaml, md, id, versionId, title }, res, _) => {
return archive.finalize()
}

function generatePandocCommand (
preview,
markdownFilePath,
bibliographyFilePath,
metadataFilePath
) {
const templatesDirPath = path.join(__dirname, 'templates')
let templateArg = `--template=${path.join(
templatesDirPath,
'publish.html'
)}`
if (preview) {
templateArg = `--template=${path.join(
templatesDirPath,
'preview.html'
)} --include-in-header=${path.join(templatesDirPath, 'preview-styles.html')}`
}
const cslFilePath = path.join(templatesDirPath, 'chicagomodified.csl')
// https://github.com/jgm/pandoc/blob/main/MANUAL.txt
// `pandoc` [*options*] [*input-file*]...
return `pandoc \
--metadata-file=${metadataFilePath} \
--bibliography=${bibliographyFilePath} \
--standalone \
${templateArg} \
--section-divs \
--ascii \
--toc \
--csl=${cslFilePath} \
--citeproc \
--from=markdown \
-to=html5 \
${markdownFilePath}`
async function getExportPreview (bodyOptions) {
const body = new FormData()
Object.entries(bodyOptions).forEach(([key, value]) => body.append(key, value))

return fetch(`${exportEndpoint}/api/article_preview`, {
method: 'POST',
body
}).then(response => response.text())
}

const exportHtml = async ({ bib, yaml, md, id, versionId, title }, res, req) => {
const preview = req.query.preview
const originalUrl = req.originalUrl

let tmpDirectory
try {
tmpDirectory = await fs.mkdtemp(path.join(os.tmpdir(), 'stylo-'))

// write files into the temporary directory
const markdownFilePath = path.join(tmpDirectory, `${id}.md`)
const bibliographyFilePath = path.join(tmpDirectory, `${id}.bib`)
const metadataFilePath = path.join(tmpDirectory, `${id}.yaml`)

await Promise.all([
fs.writeFile(markdownFilePath, md, 'utf8'),
fs.writeFile(bibliographyFilePath, bib, 'utf8'),
fs.writeFile(metadataFilePath, yaml, 'utf8'),
])
let html5 = await getExportPreview({
md_content: md,
bib_content: bib,
yaml_content: yaml,
bibliography_style: 'chicagomodified'
})

// pandoc command
const pandocCommand = generatePandocCommand(
preview,
markdownFilePath,
bibliographyFilePath,
metadataFilePath
if (canonicalBaseUrl && !html5.includes('<link rel="canonical"')) {
// HACK! we add the link tag in the head!
html5 = html5.replace(
/(<head>\s?)/gs,
`$1<link rel="canonical" href="${canonicalBaseUrl + originalUrl}">`
)
const FIFTEEN_MEGABYTES = 15 * 1024 * 1024
const { stdout, stderr } = await exec(pandocCommand, { maxBuffer: FIFTEEN_MEGABYTES })
if (stderr) {
logger.warn(stderr)
}
let html5 = stdout
if (canonicalBaseUrl && !html5.includes('<link rel="canonical"')) {
// HACK! we add the link tag in the head!
html5 = html5.replace(
/(<head>\s?)/gs,
`$1<link rel="canonical" href="${canonicalBaseUrl + originalUrl}">`
)
}

if (preview) {
html5 = html5.replace(/<\/body>/, () => {
return `<script type="application/json" class="js-hypothesis-config">
{
"openSidebar": true
}
</script>
<script src="https://hypothes.is/embed.js" async></script>
</body>`
})
} else {
res.attachment(`${normalize(title)}.html`)
}
}

res.send(html5)
} finally {
if (tmpDirectory) {
await fs.rm(tmpDirectory, { recursive: true, maxRetries: 3 })
if (preview) {
html5 = html5.replace(/<\/body>/, () => {
return `<script type="application/json" class="js-hypothesis-config">
{
"openSidebar": true
}
</script>
<script src="https://hypothes.is/embed.js" async></script>
</body>`
})
} else {
res.attachment(`${normalize(title)}.html`)
}

res.send(html5)
}

const getArticleExportContext = async (articleId) => {
Expand Down
70 changes: 0 additions & 70 deletions export/vendors/git-diff.py

This file was deleted.

0 comments on commit 163d1d8

Please sign in to comment.