diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index bd80da8ab..3f1863ce7 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -60,7 +60,6 @@ jobs: - uses: actions/checkout@v4 with: ref: ${{ (inputs.release-version && format('v{0}', inputs.release-version)) || github.ref }} - submodules: true - uses: docker/setup-buildx-action@v3 - run: cp stylo-example.env .env diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2b4ea6baa..914a54547 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,8 +13,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - with: - submodules: true - run: | node -e "const pkg = require('./package.json'); pkg.version = '$RELEASE_VERSION'; require('fs').writeFileSync('./package.json', JSON.stringify(pkg, null, ' '), 'utf8')" node -e "const pkg = require('./front/package.json'); pkg.version = '$RELEASE_VERSION'; require('fs').writeFileSync('./front/package.json', JSON.stringify(pkg, null, ' '), 'utf8')" @@ -22,13 +20,13 @@ jobs: npm i --package-lock-only npm i --prefix=graphql --package-lock-only npm i --prefix=front --package-lock-only - + RELEASE_GIT_NAME=$(curl -s https://api.github.com/users/$GITHUB_ACTOR | jq -r .name) RELEASE_GIT_EMAIL=$RELEASE_USER@users.noreply.github.com - + git config --local user.name "$RELEASE_GIT_NAME" git config --local user.email "$RELEASE_GIT_EMAIL" - + git commit -a -m "Release $RELEASE_VERSION" git tag "v$RELEASE_VERSION" git push origin master diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 20f7973d6..000000000 --- a/.gitmodules +++ /dev/null @@ -1,4 +0,0 @@ -[submodule "export/src/templates-stylo"] - path = export/src/templates-stylo - url = https://framagit.org/stylo-editeur/templates-stylo.git - branch = master diff --git a/HOWTO.md b/HOWTO.md index 85507e839..df47bf354 100644 --- a/HOWTO.md +++ b/HOWTO.md @@ -17,14 +17,6 @@ First step is to clone the project, you can use either the HTTPS or SSH version $ git clone git@github.com:EcrituresNumeriques/stylo.git -Stylo uses submodules to pull templates (and those templates are hosted on framagit). -If you have an account with ssh enabled on framagit, you can pull all submodules using the following commands: - - - $ git submodule init - $ git submodule update - - ## Run with Docker Useful to run a fully fledged Stylo in no time. diff --git a/README.md b/README.md index 4ab4ca53d..a42405ba7 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/SERVER.md b/SERVER.md index 1c1d93842..8ef38214b 100644 --- a/SERVER.md +++ b/SERVER.md @@ -54,14 +54,6 @@ cd ~ git clone https://github.com/EcrituresNumeriques/stylo.git ``` -Update the submodule: - -```bash -cd stylo -git submodule init -git submodule update -``` - Copy the `stylo-example.env` file and edit the variables: ```bash diff --git a/docs/src/en/exports.md b/docs/src/en/exports.md index 90b6740dd..ddf5ae5fa 100644 --- a/docs/src/en/exports.md +++ b/docs/src/en/exports.md @@ -1,5 +1,5 @@ --- -title: Export Page +title: Export Page --- ## Export en article @@ -29,7 +29,7 @@ It is possible to choose from several bibliographic styles: some embed the refer The export module takes care of formatting references, adding or removing spaces, inserting "Ibids." according to the style, etc. -Exports are produced using the conversion tool [Pandoc](https://pandoc.org/) based on the templates available [here](https://framagit.org/stylo-editor/templates-stylo). +Exports are produced using the conversion tool [Pandoc](https://pandoc.org/) based on the [`stylo-export` templates](https://gitlab.huma-num.fr/ecrinum/stylo/stylo-export/-/tree/main/templates/generique). The export also allows you to download the source files of Stylo (.md,.bib,.yaml) and the media inserted in the article if there are any. @@ -43,11 +43,11 @@ For more information on how to use templates, see this [tutorial](https://gitlab ## Export page -The current version of the Stylo export module ([https://export.stylo.huma-num.fr/](https://export.stylo.huma-num.fr/)) supports generic export and integrated export into the editorial cheange of Métopes (XML-TEI Commons Publisihing schema for Métopes or OpenEdition). +The current version of the Stylo export module ([https://export.stylo.huma-num.fr/](https://export.stylo.huma-num.fr/)) supports generic export and integrated export into the editorial cheange of Métopes (XML-TEI Commons Publisihing schema for Métopes or OpenEdition). Stylo's *old* export module (https://stylo-export.ecrituresnumeriques.ca) lists the other custom exports from Stylo, including: -- exports for journals that use Stylo in their editorial chains: +- exports for journals that use Stylo in their editorial chains: - [Sens public](http://sens-public.org/) - [Scriptura](https://www.facebook.com/RevueScriptura/) - [Nouvelles vues](https://nouvellesvues.org/presentation-de-la-revue/) @@ -56,16 +56,16 @@ Stylo's *old* export module (https://stylo-export.ecrituresnumeriques.ca) lists ## Special exports -### University of Montreal Template Exports +### University of Montreal Template Exports -The Stylo exports page for [University of Montreal Templates](https://stylo-export.ecrituresnumeriques.ca/exportudem.html) was created to allow students at the University of Montreal to produce their renderings directly with the regulatory formatting. +The Stylo exports page for [University of Montreal Templates](https://stylo-export.ecrituresnumeriques.ca/exportudem.html) was created to allow students at the University of Montreal to produce their renderings directly with the regulatory formatting. -Three templates are available: +Three templates are available: - The Département des littératures de langue fraçaise (DLLF) template - with /or/ without table of contents (coming soon) -- The Lesson template +- The Lesson template @@ -112,13 +112,13 @@ year: '2021' ``` 2. Register a version (major or minor) and select it 3. Select in the version url the version key (the last digits after "/version/") -4. Copy the version key +4. Copy the version key 5. In the Lesson Plan export page, paste the version key in the dedicated location 6. Then enter a name for the export, select the Lesson Plan template and click on "Submit" -#### EBSI template +#### EBSI template -To export your document according to the EBSI template, you need to: +To export your document according to the EBSI template, you need to: 1. Edit the following metadata in the metadata pane in "RAW" mode @@ -139,7 +139,7 @@ day: '05' course: - id: acronym title: Course title -teachers: +teachers: - forname: First name surname: Name lang: fr @@ -155,8 +155,8 @@ typeWork: TP2 2. Save a version (major or minor) and select it 3. Select in the version url the version key (i.e. the last digits after "/version/") -4. Copy the version key +4. Copy the version key 5. In the EBSI export page, paste the version key in the dedicated location 6. Then enter a name for the export, select the EBSI model and click on "Submit" -**Warning**: do not forget to refresh the export page if you make several exports in a row. +**Warning**: do not forget to refresh the export page if you make several exports in a row. diff --git a/docs/src/en/firststeps.md b/docs/src/en/firststeps.md index 3719b2cda..01ae80078 100644 --- a/docs/src/en/firststeps.md +++ b/docs/src/en/firststeps.md @@ -91,7 +91,7 @@ During this operation, you can also choose the tags related to the article: ![Add Tags](/uploads/images/AddTag.png) -The article will then appear in your list of articles. +The article will then appear in your list of articles. Click on the button @@ -117,12 +117,12 @@ The Stylo article must be written in Markdown, an easy-to-learn markup language. Markdown language allows a syntax structure that is easy to both read and write. Here are the main writing rules for Markdown: -- Title: the levels of the title (level 1 for the title of the article, level 2 for the titles of the section, etc.) are organised using ```#```, like this: +- Title: the levels of the title (level 1 for the title of the article, level 2 for the titles of the section, etc.) are organised using ```#```, like this: - ```# Title of the article```, ```## Introduction```, etc. Careful: The article's body text does not support titles for level 1; titles for level 1 are only used for the *Title* fields in the metadata. -- **Italics**: italics can be created in two ways: ```_word_``` or ```*word*``` +- **Italics**: italics can be created in two ways: ```_word_``` or ```*word*``` - **Bold**: bold can be created like this: ```**word**``` - **Long citation**: long citations are created like this: ```> long citation``` - **Footnote**: a footnote can be created with or without a number: @@ -179,7 +179,7 @@ It is possible to choose from several bibliographic styles: some embed the refer The export module takes care of formatting references, adding or removing spaces, inserting "Ibids." according to the style, etc. -Exports are produced using the conversion tool [Pandoc](https://pandoc.org/) based on the templates available [here](https://framagit.org/stylo-editor/templates-stylo). +Exports are produced using the conversion tool [Pandoc](https://pandoc.org/) based on the templates available [here](export/templates). For more information on Stylo exporting, you can see this [page](/en/exports/) @@ -228,7 +228,7 @@ The [Metadata] button opens the metadata pane. Three editing modes are available For more information on metadata editing, you can see this [page](). -**Careful**: In the metadata pane is the "Bibliography" division, including the *Display* option, which allows you to choose to view the bibliography either in its entirety ("All citations"), or just the references which have been cited in the body of the article ("Only used"). +**Careful**: In the metadata pane is the "Bibliography" division, including the *Display* option, which allows you to choose to view the bibliography either in its entirety ("All citations"), or just the references which have been cited in the body of the article ("Only used"). ![All citation](/uploads/images/allCitation.png) diff --git a/docs/src/en/myarticles.md b/docs/src/en/myarticles.md index 97c9be26a..518d47fed 100644 --- a/docs/src/en/myarticles.md +++ b/docs/src/en/myarticles.md @@ -134,9 +134,9 @@ This function also allows you to send the article with the same system: The [Send a Copy] option is not sharing the article; only the last version of the article will be visible for the user and the changes will not be visible to other users. In the [Send a Copy] process, two versions of the article are created and the users each work on a version that is not visible to the other. -## Take over +## Take over -When an article is shared (via a workspace or the share button) with another user, the article editing function is only available to one person at a time. You'll see by the red dot in the box that a collaborator is editing the article or has not properly closed his editing session. If you also want to edit the article, you can take over the editing session by pressing ![Edit](/uploads/images/edit-red.png) and confirm. The other collaborator will then be in read-only mode and you will be able to edit the article. +When an article is shared (via a workspace or the share button) with another user, the article editing function is only available to one person at a time. You'll see by the red dot in the box that a collaborator is editing the article or has not properly closed his editing session. If you also want to edit the article, you can take over the editing session by pressing ![Edit](/uploads/images/edit-red.png) and confirm. The other collaborator will then be in read-only mode and you will be able to edit the article. To properly close an editing session, simply return to the *Articles* page when you've finished your work. @@ -156,7 +156,7 @@ To export an article, you must click on the "Export" button, then the page "My a ![Export](/uploads/images/Download.png) -The export menu allows you to choose the export format. It also contains the option to include or exclude a table of contents. +The export menu allows you to choose the export format. It also contains the option to include or exclude a table of contents. ![Export](uploads/images/ExportConfig-V2.PNG) @@ -177,7 +177,7 @@ It is possible to choose from several bibliographic styles, some of which integr The export module manages the reference formatting, adding or removing spaces, and inserting "ibid" according to the style, etc. -Exports are produced thanks to the [pandoc](https://pandoc.org/) conversion tool, based on templates available [here](https://framagit.org/stylo-editeur/templates-stylo). +Exports are produced thanks to the [pandoc](https://pandoc.org/) conversion tool, based on [`stylo-export` templates](https://gitlab.huma-num.fr/ecrinum/stylo/stylo-export/-/tree/main/templates/generique). The export also downloads the Stylo source files (.md, .bib, .yaml) and the media inserted in the article, if this is the case. diff --git a/docs/src/fr/exports.md b/docs/src/fr/exports.md index b09304d6c..421b2f2ac 100644 --- a/docs/src/fr/exports.md +++ b/docs/src/fr/exports.md @@ -29,7 +29,7 @@ Il est possible de choisir parmi plusieurs styles bibliographiques : certains i Le module d'export se charge de mettre en forme les références, d'ajouter ou d'enlever les espaces, d'insérer des "Ibid." en accord avec le style, etc. -Les exports sont produits grâce à l'outil de conversion [Pandoc](https://pandoc.org/) sur la base des templates disponibles [ici](https://framagit.org/stylo-editeur/templates-stylo). +Les exports sont produits grâce à l'outil de conversion [Pandoc](https://pandoc.org/) sur la base des [templates `stylo-export`](https://gitlab.huma-num.fr/ecrinum/stylo/stylo-export/-/tree/main/templates/generique). L'export permet aussi de télécharger les fichiers source de Stylo (.md, .bib, .yaml) et les médias insérés dans l'article s'il y en a. @@ -45,9 +45,9 @@ Pour plus d'informations sur l'emploi des templates, voir ce [tutoriel](https:// La version actuelle du module d'export de Stylo ([https://export.stylo.huma-num.fr/](https://export.stylo.huma-num.fr/)) propose un export générique et un export pour une intégration dans la chaîne d'édition de Métopes (schéma XML-TEI Commons Publishing pour Métopes ou OpenEdition). -La version _legacy_ de l'export de Stylo ([https://stylo-export.ecrituresnumeriques.ca](https://stylo-export.ecrituresnumeriques.ca/)) liste d'autres exports personnalisés de Stylo dont : +La version _legacy_ de l'export de Stylo ([https://stylo-export.ecrituresnumeriques.ca](https://stylo-export.ecrituresnumeriques.ca/)) liste d'autres exports personnalisés de Stylo dont : -- les exports pour les revues qui utilisent Stylo dans leurs chaînes éditoriales : +- les exports pour les revues qui utilisent Stylo dans leurs chaînes éditoriales : - [Sens public](http://sens-public.org/) - [Scriptura](https://www.facebook.com/RevueScriptura/) - [Nouvelles Vues](https://nouvellesvues.org/presentation-de-la-revue/) @@ -56,22 +56,22 @@ La version _legacy_ de l'export de Stylo ([https://stylo-export.ecrituresnumeriq ## Les exports spéciaux -### Exports modèles de l'Université de Montréal +### Exports modèles de l'Université de Montréal -La page des exports Stylo [Modèles de l'Université de Montréal](https://stylo-export.ecrituresnumeriques.ca/exportudem.html) a été créée pour permettre aux étudiant.es de l'Université de Montréal de produire leurs rendus directement avec la mise en forme réglementaire. +La page des exports Stylo [Modèles de l'Université de Montréal](https://stylo-export.ecrituresnumeriques.ca/exportudem.html) a été créée pour permettre aux étudiant.es de l'Université de Montréal de produire leurs rendus directement avec la mise en forme réglementaire. -Trois modèles sont proposés : +Trois modèles sont proposés : - Le modèle du Département des littératures de langue française (DLLF) - avec /ou/ sans table des matières (en cours d'implémentation) -- Le modèle du Plan de cours +- Le modèle du Plan de cours - Le modèle de L'École de bibliothéconomie et des sciences de l'information (EBSI) - + #### Modèle DLLF (à venir) @@ -116,9 +116,9 @@ year: '2021' 5. Dans la page d'export du Plan de cours, coller la clef de version à l'emplacement dédié; 6. Puis attribuer un nom à l'export, sélectionner le modèle du Plan de cours et cliquer sur "Submit". -#### Modèle EBSI +#### Modèle EBSI -Pour exporter votre document selon le modèle de l'EBSI, il faut : +Pour exporter votre document selon le modèle de l'EBSI, il faut : 1. Éditer les métadonnées suivantes dans le volet des métadonnées en mode "RAW" : @@ -139,7 +139,7 @@ day: '05' cours: - id: Sigle title: Titre du cours -teachers: +teachers: - forname: Prénom surname: Nom lang: fr diff --git a/docs/src/fr/premierspas.md b/docs/src/fr/premierspas.md index 84fb69319..cc56059c8 100644 --- a/docs/src/fr/premierspas.md +++ b/docs/src/fr/premierspas.md @@ -75,7 +75,7 @@ L'interface d'édition d'un article présente plusieurs modules : La fonction **[Share]** permet d'inviter des co-auteur·rice·s à travailler sur le même article. Ces utilisateur·ice·s ont alors accès à tout l'historique. Les versions de l'article se synchronisent pour tous les utilisateurs au fur et à mesure des modifications effectuées sur le document. -**Attention** : partager un article avec un autre utilisateur est possible uniquement en renseignant l'adresse courriel qui a servi à créer son compte utilisateur sur Stylo. +**Attention** : partager un article avec un autre utilisateur est possible uniquement en renseignant l'adresse courriel qui a servi à créer son compte utilisateur sur Stylo. ## Nouvel article @@ -151,7 +151,7 @@ Pour approfondir vos connaissances en syntaxe Markdown, vous pouvez consulter la ![Active](/uploads/images/Nom-Version-V2.PNG) -Une version du document correspond à une sauvegarde de votre travail. Une version contient toujours les trois éléments de l'article : métadonnées, bibliographie, corps de texte. En chargeant une ancienne version, ce sont donc ces trois éléments qui sont mis à jour. +Une version du document correspond à une sauvegarde de votre travail. Une version contient toujours les trois éléments de l'article : métadonnées, bibliographie, corps de texte. En chargeant une ancienne version, ce sont donc ces trois éléments qui sont mis à jour. Votre travail est par défaut automatiquement sauvegardé sur Stylo, mais vous devez créer vous-mêmes les versions. Pour ce faire, vous pouvez donc -- et cela est conseillé -- utiliser la fonction de sauvegarde [New Version] qui permet de générer une nouvelle version du travail. @@ -184,7 +184,7 @@ Il est possible de choisir parmi plusieurs styles bibliographiques : certains i Le module d'export se charge de mettre en forme les références, d'ajouter ou d'enlever les espaces, d'insérer des "Ibid." en accord avec le style, etc. -Les exports sont produits grâce à l'outil de conversion [Pandoc](https://pandoc.org/) sur la base des templates disponibles [ici](https://framagit.org/stylo-editeur/templates-stylo). +Les exports sont produits grâce à l'outil de conversion [Pandoc](https://pandoc.org/) sur la base des [templates `stylo-export`](https://gitlab.huma-num.fr/ecrinum/stylo/stylo-export/-/tree/main/templates/generique). Pour davantage d'informations sur l'export Stylo, vous pouvez consulter la [page dédiée](/fr/exports). @@ -228,7 +228,7 @@ Le bouton [**Metadata**] permet d'ouvrir le volet des métadonnées. Trois modes **Important** : afin d'exporter un article, les champs "Title" et "Authors" doivent obligatoirement être renseignés. -**Attention** : dans le volet des métadonnées se trouve la division sur la "Bibliographie" dont l'option *Display* permet de choisir la visualisation de la bibliographie dans son entièreté ("All citations") ou uniquement des références qui ont été citées dans le corps de l'article ("Only used"). +**Attention** : dans le volet des métadonnées se trouve la division sur la "Bibliographie" dont l'option *Display* permet de choisir la visualisation de la bibliographie dans son entièreté ("All citations") ou uniquement des références qui ont été citées dans le corps de l'article ("Only used"). ![Bibliography-Display](/uploads/images/Bibliography-Display-V2.PNG) diff --git a/export/dockerfile b/export/dockerfile index 78ba39891..1fed22917 100644 --- a/export/dockerfile +++ b/export/dockerfile @@ -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 diff --git a/export/src/assets/preview.css b/export/src/assets/preview.css new file mode 100644 index 000000000..b637111ef --- /dev/null +++ b/export/src/assets/preview.css @@ -0,0 +1,611 @@ +/* +* I add this to html files generated with pandoc. +*/ + +@media only screen and (max-width: 1000px) { + nav { + display: none; + } +} + +html { + font-size: 100%; + overflow-y: scroll; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} + +body { + color: #444; + font-family: Georgia, Palatino, 'Palatino Linotype', Times, 'Times New Roman', serif; + font-size: 12px; + line-height: 1.7; + padding: 1em; + margin: auto; + max-width: 42em; + background: #fefefe; +} + +a { + color: #0645ad; + text-decoration: none; +} + +a:visited { + color: #0b0080; +} + +a:hover { + color: #06e; +} + +a:active { + color: #faa700; +} + +a:focus { + outline: thin dotted; +} + +*::-moz-selection { + background: rgba(255, 255, 0, 0.3); + color: #000; +} + +*::selection { + background: rgba(255, 255, 0, 0.3); + color: #000; +} + +a::-moz-selection { + background: rgba(255, 255, 0, 0.3); + color: #0645ad; +} + +a::selection { + background: rgba(255, 255, 0, 0.3); + color: #0645ad; +} + +p { + margin: 1em 0; +} + +img { + max-width: 100%; +} + +h1, h2, h3, h4, h5, h6 { + color: #111; + line-height: 125%; + margin-top: 2em; + font-weight: normal; +} + +h4, h5, h6 { + font-weight: bold; +} + +h1 { + font-size: 2.5em; +} + +h2 { + font-size: 2em; +} + +h3 { + font-size: 1.5em; +} + +h4 { + font-size: 1.2em; +} + +h5 { + font-size: 1em; +} + +h6 { + font-size: 0.9em; +} + +blockquote { + color: #666666; + margin: 0; + padding-left: 3em; + border-left: 0.5em #EEE solid; +} + +hr { + display: block; + height: 2px; + border: 0; + border-top: 1px solid #aaa; + border-bottom: 1px solid #eee; + margin: 1em 0; + padding: 0; +} + +pre, code, kbd, samp { + color: #000; + font-family: monospace, monospace; + _font-family: 'courier new', monospace; + font-size: 0.98em; +} + +pre { + white-space: pre; + white-space: pre-wrap; + word-wrap: break-word; +} + +b, strong { + font-weight: bold; +} + +dfn { + font-style: italic; +} + +ins { + background: #ff9; + color: #000; + text-decoration: none; +} + +mark { + background: #ff0; + color: #000; + font-style: italic; + font-weight: bold; +} + +sub, sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +ul, ol { + margin: 1em 0; + padding: 0 0 0 2em; +} + +li p:last-child { + margin-bottom: 0; +} + +ul ul, ol ol { + margin: .3em 0; +} + +dl { + margin-bottom: 1em; +} + +dt { + font-weight: bold; + margin-bottom: .8em; +} + +dd { + margin: 0 0 .8em 2em; +} + +dd:last-child { + margin-bottom: 0; +} + +img { + border: 0; + -ms-interpolation-mode: bicubic; + vertical-align: middle; +} + +figure { + display: block; + text-align: center; + margin: 1em 0; +} + +figure img { + border: none; + margin: 0 auto; +} + +figcaption { + font-size: 0.8em; + font-style: italic; + margin: 0 0 .8em; +} + +table { + margin-bottom: 2em; + border-bottom: 1px solid #ddd; + border-right: 1px solid #ddd; + border-spacing: 0; + border-collapse: collapse; +} + +table th { + padding: .2em 1em; + background-color: #eee; + border-top: 1px solid #ddd; + border-left: 1px solid #ddd; +} + +table td { + padding: .2em 1em; + border-top: 1px solid #ddd; + border-left: 1px solid #ddd; + vertical-align: top; +} + +.author { + font-size: 1.2em; + text-align: center; +} + +@media only screen and (min-width: 480px) { + body { + font-size: 14px; + } +} +@media only screen and (min-width: 768px) { + body { + font-size: 16px; + } +} +@media print { + * { + background: transparent !important; + color: black !important; + filter: none !important; + -ms-filter: none !important; + } + + body { + font-size: 12pt; + max-width: 100%; + } + + a, a:visited { + text-decoration: underline; + } + + hr { + height: 1px; + border: 0; + border-bottom: 1px solid black; + } + + a[href]:after { + content: " (" attr(href) ")"; + } + + abbr[title]:after { + content: " (" attr(title) ")"; + } + + .ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { + content: ""; + } + + pre, blockquote { + border: 1px solid #999; + padding-right: 1em; + page-break-inside: avoid; + } + + tr, img { + page-break-inside: avoid; + } + + img { + max-width: 100% !important; + } + + @page :left { + margin: 15mm 20mm 15mm 10mm; +} + + @page :right { + margin: 15mm 10mm 15mm 20mm; +} + + p, h2, h3 { + orphans: 3; + widows: 3; + } + + h2, h3 { + page-break-after: avoid; + } +} + +nav::before { + content: 'Table des matières'; + font-weight: bold; + padding-left: 2em; +} + +nav { +position: fixed; +top: 0; +left: 0; +font-weight: 500; +padding-top: 3em; +width: 20%; +overflow-y: auto; +height: 100%; +} + +nav li { + list-style-type: none; + padding-top: 0.8em; + line-height: 1.3em; + +} + +header { + border: 1px solid rgb(200,200,200); + padding:10px; + background-color: rgb(240,240,240); + +} + +#schema-scholarly-article > span[property=name]:nth-child(1){ + font-size: xx-large; + line-height: 2em; + text-align: center; +} + +#schema-scholarly-article > span[property=name]:nth-child(3){ + font-size: larger; + line-height: 2em; + text-align: center; +} + + +#schema-scholarly-article > span[property=author]{ + font-size: large; + padding-top: 20px; + line-height: 2em; +} + +div.resume { + margin-top: 10px; +} + +div.resume[lang=en]::before { + content:"Abstract: "; + font-weight: bold; + } + +div.resume[lang=fr]::before { + content:"Résumé : "; + font-weight: bold; + } + +div.resume[lang=es]::before { + content:"Resumen: "; + font-weight: bold; + } + +div.resume[lang=pt]::before { + content:"Abstrato: "; + font-weight: bold; + } + +div.resume[lang=uk]::before { + content:"Pеферат: "; + font-weight: bold; + } + +div.resume[lang=de]::before { + content:"Abstrakt: "; + font-weight: bold; + } + +div.resume[lang=it]::before { + content:"Astratto: "; + font-weight: bold; + } + +.keywords::before { + content:"Catégories :"; + font-weight: bold; + } + +div.keywords { + margin-top: 10px; +} + +.keywords > div { + display: inline-block; +} + +.keywords > div::after { + content: " / "; +} + +.keywords > div:last-child::after { + content: "."; +} + +div.authorKeywords_fr { + margin-top: 10px; +} + +div.authorKeywords_fr span::before { + content: 'Mots-clés auteur : '; + font-weight: bold; +} + +div.authorKeywords_fr span::after { + content: '.'; +} + +div.authorKeywords_en span::before { + content: 'Keywords: '; + font-weight: bold; +} + +div.authorKeywords_en span::after { + content: '.'; +} + +hr#startArticle { + margin-top: 4em; + height: 1px; + border-top : 1px solid rgb(200,200,200) +} + +p span.epigraphe { + margin-left: 10%; + margin-right: 20%; + text-align: left; + margin-bottom: 2em; + float: right; + font-style: italic; +} + +p span.epigraphe span.source { + content: '— '; +} + +p span.dedicace { + margin-left: 10%; + text-align: left; + margin-bottom: 2em; + float: right; + font-style: italic; +} + +p span.note { + margin-left: 10%; + text-align: left; + margin-bottom: 2em; + float: right; + font-style: italic; +} + +span.these { + text-decoration: underline double #a91e58; +} + +span.these:hover::before { + content: "[These: "; + position:relative; + color: #a91e58; + font-size: 1em; + padding-left:5px; + padding-right:5px; +} + +span.these:hover::after { + content: "]"; + position:relative; + color: #a91e58; + font-size: 1em; + padding-left:5px; + padding-right:5px; +} + +span.exemple { + text-decoration: underline double #b37114; +} + +span.exemple:hover::before { + content: "[Exemple: "; + position:relative; + color: #b37114; + font-size: 1em; + padding-left:5px; + padding-right:5px; +} + +span.exemple:hover::after { + content: "]"; + position:relative; + color: #b37114; + font-size: 1em; + padding-left:5px; + padding-right:5px; +} + +span.concept { + text-decoration: underline double #14b371; +} + +span.concept:hover::before { + content: "[Concept: "; + position:relative; + color: #14b371; + font-size: 1em; + padding-left:5px; + padding-right:5px; +} + +span.concept:hover::after { + content: "]"; + position:relative; + color: #14b371; + font-size: 1em; + padding-left:5px; + padding-right:5px; +} + +span.definition { + text-decoration: underline double #1456b3; +} + +span.definition:hover::before { + content: "[Definition: "; + position:relative; + color: #1456b3; + font-size: 1em; + padding-left:5px; + padding-right:5px; +} + +span.definition:hover::after { + content: "]"; + position:relative; + color: #1456b3; + font-size: 1em; + padding-left:5px; + padding-right:5px; +} + +span.question { + text-decoration: underline double #ff7214 ; +} + +span.question:hover::before { + content: "[Question: "; + position:relative; + color: #ff7214; + font-size: 1em; + padding-left:5px; + padding-right:5px; +} + +span.question:hover::after { + content: "]"; + position:relative; + color: #ff7214; + font-size: 1em; + padding-left:5px; + padding-right:5px; +} diff --git a/export/src/export.js b/export/src/export.js index bd39913fc..faa59d0d2 100644 --- a/export/src/export.js +++ b/export/src/export.js @@ -1,18 +1,14 @@ -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') - +const { readFile } = require('node:fs/promises') +const { join } = require('node:path') const { logger } = require('./logger') const { FindByIdNotFoundError } = require('./helpers/errors') 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` @@ -25,101 +21,65 @@ 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-stylo') - let templateArg = `--template=${path.join( - templatesDirPath, - 'templateHtml5.html5' - )}` - if (preview) { - templateArg = `--template=${path.join( - templatesDirPath, - 'templateHtml5-preview.html5' - )} -H ${path.join(templatesDirPath, 'preview.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 \ --f markdown \ --t html5 \ -${markdownFilePath}` +/** + * + * @param {{md_content: String, bib_content: String, yaml_content: String, bibliography_style: String, with_toc: Boolean}} bodyOptions + * @returns {Promise} + */ +async function getStyloExportHtmlOutput (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 preview = Boolean(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'), - ]) - - // pandoc command - const pandocCommand = generatePandocCommand( - preview, - markdownFilePath, - bibliographyFilePath, - metadataFilePath + let html5 = await getStyloExportHtmlOutput({ + md_content: md, + bib_content: bib, + yaml_content: yaml, + with_toc: preview, + bibliography_style: 'chicagomodified' + }) + + if (canonicalBaseUrl && !html5.includes('\s?)/gs, + `$1` ) - 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('\s?)/gs, - `$1` - ) - } + } - if (preview) { - html5 = html5.replace(/<\/body>/, () => { - return ` - - ` - }) - } else { - res.attachment(`${normalize(title)}.html`) - } + /** + * HTML Preview can be both for an Article export and the Article Preview (read: proofread with Hypothesis annotations) + * The `preview` argument controls in which context we display the output + */ + if (preview) { + const previewStylesheet = await readFile(join(__dirname, 'assets', 'preview.css'), { encoding: 'utf8' }) - res.send(html5) - } finally { - if (tmpDirectory) { - await fs.rm(tmpDirectory, { recursive: true, maxRetries: 3 }) + html5 = html5.replace(/(<\/head>\s?)/gs, ` + + $1` + ) + + html5 = html5.replace(/<\/body>/, ` + + `) + + return res.send(html5) } + + res.attachment(`${normalize(title)}.html`) } const getArticleExportContext = async (articleId) => { diff --git a/export/src/templates-stylo b/export/src/templates-stylo deleted file mode 160000 index e5fb2834d..000000000 --- a/export/src/templates-stylo +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e5fb2834d724d8afd0f8ecb86e064ddf54067c96 diff --git a/export/vendors/git-diff.py b/export/vendors/git-diff.py deleted file mode 100644 index 6492a0d4b..000000000 --- a/export/vendors/git-diff.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env python3 - -""" - Pandoc filter to process a code block with class "git-diff" to present the - diff of a file between two commits. - - class variables: - * dir: Directory from (optional, defaults to ".") - * objects: Which object in `dir` (optional defaults to ".") - * commit-range: commitrange (like: "HEAD..v1.0", optional, defaults to HEAD) - * diffoptions: git diff options (like: -U0, optional, defaults to "") - - Example: (git -C /devel/jog diff ..23fe4 -- README.md) - ```{.git-diff commit-range="..23fe4" dir="/devel/jog" object="README.md"} - - Example: (git diff ..v1.0) - ```{.git-diff commit-range="..v1.0"} - - Example: - ```{.git-diff commit-range="..v1.0" objects="README.md src/u src/c" diffoptions="-U0"} - """ - -from pandocfilters import toJSONFilter, RawBlock, CodeBlock -import subprocess; - -def gitdiff(key, value, format, meta): - if key == "CodeBlock": - [[ident, classes, keyvals], contents] = value - if "git-diff" in classes: - folder = "." - commra = "" - obj = "" - objdiv = "" - options = "" - - # its a diff - view - if not "diff" in classes: - classes.append("diff") - - for el in keyvals: - if "commit-range" in el: - commra = el[1] - - if "dir" in el: - folder = el[1] - - if "objects" in el or "object" in el: - objdiv = "--" - obj = "%s %s" % (obj, el[1]) - - if "diffoptions" == el[0]: - options = el[1] - - command_string = "git -C %s diff %s %s %s %s" % (folder, options, commra, objdiv, obj) - out = "" - try: - l = list(filter(None, command_string.split(" "))) - out = subprocess.check_output(l) - except subprocess.CalledProcessError as err: - return None - - if out != None or out != "": - out = out.decode("utf-8"); - return [CodeBlock([ident, classes, keyvals], out), CodeBlock([ident, classes, keyvals], contents)] - else: - return None - -if __name__ == "__main__": - toJSONFilter(gitdiff) -