Initial ChatGPT code and docs.
This commit is contained in:
parent
93368211de
commit
96235c83db
|
|
@ -0,0 +1,25 @@
|
|||
name: Build PolyPaper (Forgejo)
|
||||
on: [push, pull_request, workflow_dispatch]
|
||||
jobs:
|
||||
build:
|
||||
runs-on: docker
|
||||
strategy: { fail-fast: false, matrix: { venue: [arxiv, ieee, elsevier, acm] } }
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build Docker image
|
||||
run: docker build -f Dockerfile.full -t polypaper:full .
|
||||
- name: Validate metadata
|
||||
run: docker run --rm -v $GITHUB_WORKSPACE:/work -w /work polypaper:full bash -lc 'chmod +x scripts/check_metadata.py && scripts/check_metadata.py'
|
||||
- name: Build PDFs and HTML (${{ matrix.venue }})
|
||||
run: |
|
||||
docker run --rm -v $GITHUB_WORKSPACE:/work -w /work polypaper:full bash -lc 'make VENUE=${{ matrix.venue }}'
|
||||
docker run --rm -v $GITHUB_WORKSPACE:/work -w /work polypaper:full bash -lc 'make supplement VENUE=${{ matrix.venue }}'
|
||||
docker run --rm -v $GITHUB_WORKSPACE:/work -w /work polypaper:full bash -lc 'make camera-ready VENUE=${{ matrix.venue }}'
|
||||
docker run --rm -v $GITHUB_WORKSPACE:/work -w /work polypaper:full bash -lc 'make site VENUE=${{ matrix.venue }}'
|
||||
- name: Archive outputs
|
||||
run: |
|
||||
mkdir -p artifacts/${{ matrix.venue }}
|
||||
mv paper-${{ matrix.venue }}.pdf artifacts/${{ matrix.venue }}/ || true
|
||||
mv paper-supplement-${{ matrix.venue }}.pdf artifacts/${{ matrix.venue }}/ || true
|
||||
mv paper-camera-ready-${{ matrix.venue }}.pdf artifacts/${{ matrix.venue }}/ || true
|
||||
cp -a public artifacts/${{ matrix.venue }}/ || true
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
cff-version: 1.2.0
|
||||
message: "If you use this project, please cite it as below."
|
||||
title: "PolyPaper"
|
||||
authors:
|
||||
- family-names: "Elsberry"
|
||||
given-names: "Wesley R."
|
||||
orcid: "https://orcid.org/0000-0000-0000-0000"
|
||||
identifiers:
|
||||
- type: doi
|
||||
value: 10.5281/zenodo.0000000
|
||||
repository-code: "https://example.org/polypaper"
|
||||
license: MIT
|
||||
version: "0.1.0"
|
||||
date-released: "2025-10-04"
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Code of Conduct
|
||||
|
||||
We follow the Contributor Covenant. Be kind.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Contributing
|
||||
|
||||
Thanks for considering a contribution! See issues for ideas.
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
# syntax=docker/dockerfile:1
|
||||
FROM ubuntu:24.04
|
||||
ENV DEBIAN_FRONTEND=noninteractive PYTHONUNBUFFERED=1 LC_ALL=C.UTF-8 LANG=C.UTF-8
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
ca-certificates curl git make emacs-nox python3 python3-pip python3-matplotlib \
|
||||
latexmk biber texlive-full && rm -rf /var/lib/apt/lists/*
|
||||
RUN useradd -m -u 1000 builder
|
||||
WORKDIR /work
|
||||
USER builder
|
||||
CMD ["bash", "-lc", "make VENUE=arxiv"]
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
# syntax=docker/dockerfile:1
|
||||
FROM ubuntu:24.04
|
||||
ENV DEBIAN_FRONTEND=noninteractive PYTHONUNBUFFERED=1 LC_ALL=C.UTF-8 LANG=C.UTF-8 PATH=/opt/TinyTeX/bin/x86_64-linux:$PATH
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
ca-certificates curl git make emacs-nox python3 python3-pip python3-matplotlib perl && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
RUN curl -sL https://yihui.org/tinytex/install-unx.sh | sh -s - --admin --no-path && \
|
||||
/opt/TinyTeX/bin/*/tlmgr path add && \
|
||||
tlmgr install latexmk biber latex-bin biblatex hyperref geometry microtype etoolbox enumitem xcolor listings IEEEtran acmart elsarticle && \
|
||||
tlmgr path add
|
||||
RUN useradd -m -u 1000 builder
|
||||
WORKDIR /work
|
||||
USER builder
|
||||
CMD ["bash", "-lc", "make VENUE=arxiv"]
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
VENUE ?= arxiv
|
||||
JOB ?= paper-$(VENUE)
|
||||
|
||||
all: $(JOB).pdf
|
||||
|
||||
$(JOB).pdf: paper.org setup/venue-$(VENUE).org build.el biblio.bib
|
||||
emacs -Q --batch -l build.el --eval "(setenv \"VENUE\" \"$(VENUE)\")" --funcall wes/export-pdf-cli
|
||||
|
||||
site:
|
||||
emacs -Q --batch -l build.el --eval "(setenv \"VENUE\" \"$(VENUE)\")" --funcall wes/publish-site-cli
|
||||
@echo "HTML written to public/ (paper.org → public/paper.html)"
|
||||
|
||||
supplement:
|
||||
emacs -Q --batch -l build.el --eval "(setenv \"VENUE\" \"$(VENUE)\")" --funcall wes/export-supplement-pdf-cli
|
||||
|
||||
camera-ready:
|
||||
emacs -Q --batch -l build.el --eval "(setenv \"VENUE\" \"$(VENUE)\")" --funcall wes/export-camera-ready-pdf-cli
|
||||
|
||||
clean:
|
||||
latexmk -C
|
||||
rm -f paper-*.pdf
|
||||
|
||||
# Dockerized builds
|
||||
DOCKER_IMAGE ?= polypaper:full
|
||||
DOCKERFILE ?= Dockerfile.full
|
||||
|
||||
build-image:
|
||||
docker build -f $(DOCKERFILE) -t $(DOCKER_IMAGE) .
|
||||
|
||||
docker:
|
||||
docker run --rm -u $$(id -u):$$(id -g) -v $$(pwd):/work -w /work $(DOCKER_IMAGE) bash -lc "make VENUE=$(VENUE)"
|
||||
|
||||
docker-supplement:
|
||||
docker run --rm -u $$(id -u):$$(id -g) -v $$(pwd):/work -w /work $(DOCKER_IMAGE) bash -lc "make supplement VENUE=$(VENUE)"
|
||||
|
||||
docker-camera-ready:
|
||||
docker run --rm -u $$(id -u):$$(id -g) -v $$(pwd):/work -w /work $(DOCKER_IMAGE) bash -lc "make camera-ready VENUE=$(VENUE)"
|
||||
|
||||
docker-site:
|
||||
docker run --rm -u $$(id -u):$$(id -g) -v $$(pwd):/work -w /work $(DOCKER_IMAGE) bash -lc "make site VENUE=$(VENUE)"
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
@article{demo2020,
|
||||
title = {A Demo Reference for PolyPaper},
|
||||
author = {Example, Ada and Example, Alan},
|
||||
journal = {Journal of Demos},
|
||||
year = {2020},
|
||||
volume = {1},
|
||||
number = {1},
|
||||
pages = {1--10}
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
;; Batch export & site publish
|
||||
(setq org-confirm-babel-evaluate nil)
|
||||
(setq org-latex-pdf-process '("latexmk -pdf -interaction=nonstopmode -shell-escape %f"))
|
||||
|
||||
(defun wes/export-pdf (&optional venue)
|
||||
(let* ((v (or venue (or (getenv "VENUE") "arxiv")))
|
||||
(outfile (format "paper-%s.pdf" v)))
|
||||
(with-current-buffer (find-file-noselect "paper.org")
|
||||
(setenv "VENUE" v)
|
||||
(org-latex-export-to-pdf nil nil nil t)
|
||||
(when (file-exists-p "paper.pdf")
|
||||
(rename-file "paper.pdf" outfile t))
|
||||
(message "Wrote %s" outfile))))
|
||||
|
||||
(defun wes/export-pdf-cli () (wes/export-pdf))
|
||||
|
||||
(require 'ox) (require 'ox-publish)
|
||||
(defun wes/publish-site (&optional venue)
|
||||
(let* ((v (or venue (or (getenv "VENUE") "arxiv"))))
|
||||
(setenv "VENUE" v)
|
||||
(setq org-publish-project-alist
|
||||
`(("site-html"
|
||||
:base-directory "."
|
||||
:publishing-directory "public"
|
||||
:publishing-function org-html-publish-to-html
|
||||
:with-author t :with-toc t :section-numbers t
|
||||
:html-head "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"
|
||||
:recursive nil
|
||||
:exclude "setup/\\|code/\\|figs/\\|public/\\|data/"
|
||||
:include ("paper.org")
|
||||
:select-tags ("export")
|
||||
:exclude-tags ,(if (member v '("ieee" "acm"))
|
||||
'("noexport" "appendix" "notes")
|
||||
'("noexport")))))
|
||||
(org-publish "site-html" t)
|
||||
(message "Published HTML site for %s" v)))
|
||||
|
||||
(defun wes/publish-site-cli () (wes/publish-site))
|
||||
|
||||
(defun wes--cam-tight-latex ()
|
||||
(mapconcat #'identity
|
||||
'("\\usepackage{microtype}"
|
||||
"\\flushbottom"
|
||||
"\\setlength{\\textfloatsep}{10pt}"
|
||||
"\\setlength{\\floatsep}{8pt}"
|
||||
"\\setlength{\\intextsep}{8pt}"
|
||||
"\\usepackage{enumitem}"
|
||||
"\\setlist{nosep}"
|
||||
"\\usepackage{balance}")
|
||||
"\n"))
|
||||
|
||||
(defun wes/export-camera-ready-pdf (&optional venue)
|
||||
(let* ((v (or venue (or (getenv "VENUE") "arxiv")))
|
||||
(base-setup (expand-file-name (format "setup/venue-%s.org" v)))
|
||||
(tmp-name (format ".tmp-venue-%s-camera" v))
|
||||
(tmp-setup (expand-file-name (format "setup/%s.org" tmp-name)))
|
||||
(outfile (format "paper-camera-ready-%s.pdf" v)))
|
||||
(unless (file-exists-p base-setup)
|
||||
(error "Base setup file not found for venue %s" v))
|
||||
(with-temp-buffer
|
||||
(insert-file-contents base-setup)
|
||||
(goto-char (point-max))
|
||||
(insert "\n# Camera-ready overrides\n#+BIND: paper-anon nil\n")
|
||||
(insert (format "#+latex_header: %s\n" (wes--cam-tight-latex)))
|
||||
(write-region (point-min) (point-max) tmp-setup))
|
||||
(unwind-protect
|
||||
(progn
|
||||
(with-current-buffer (find-file-noselect "paper.org")
|
||||
(setenv "VENUE" tmp-name)
|
||||
(org-latex-export-to-pdf nil nil nil t)
|
||||
(when (file-exists-p "paper.pdf")
|
||||
(rename-file "paper.pdf" outfile t))
|
||||
(message "Wrote %s" outfile)))
|
||||
(ignore-errors (delete-file tmp-setup)))))
|
||||
|
||||
(defun wes/export-camera-ready-pdf-cli () (wes/export-camera-ready-pdf))
|
||||
|
||||
(defun wes/export-supplement-pdf (&optional venue)
|
||||
(let* ((v (or venue (or (getenv "VENUE") "arxiv")))
|
||||
(outfile (format "paper-supplement-%s.pdf" v))
|
||||
(paper-short nil) (paper-anon nil) (paper-limit-figs nil)
|
||||
(org-export-select-tags '("export"))
|
||||
(org-export-exclude-tags '("noexport")))
|
||||
(with-current-buffer (find-file-noselect "paper.org")
|
||||
(setenv "VENUE" v)
|
||||
(org-latex-export-to-pdf nil nil nil t)
|
||||
(when (file-exists-p "paper.pdf")
|
||||
(rename-file "paper.pdf" outfile t))
|
||||
(message "Wrote %s" outfile))))
|
||||
|
||||
(defun wes/export-supplement-pdf-cli () (wes/export-supplement-pdf))
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
services:
|
||||
paper:
|
||||
build: { context: ., dockerfile: Dockerfile.full }
|
||||
image: polypaper:full
|
||||
working_dir: /work
|
||||
volumes: [ ".:/work" ]
|
||||
command: bash -lc "make VENUE=${VENUE:-arxiv}"
|
||||
|
||||
paper-tiny:
|
||||
build: { context: ., dockerfile: Dockerfile.tinytex }
|
||||
image: polypaper:tinytex
|
||||
working_dir: /work
|
||||
volumes: [ ".:/work" ]
|
||||
command: bash -lc "make VENUE=${VENUE:-arxiv}"
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
# -*- org-export-allow-bind: t; -*-
|
||||
#+TITLE: Demo Paper (PolyPaper)
|
||||
#+AUTHOR: {{{NAME}}}
|
||||
#+FILETAGS: :export:
|
||||
#+OPTIONS: toc:2 num:t broken-links:auto
|
||||
#+PROPERTY: header-args:python :session py :results file graphics :exports results :cache yes
|
||||
#+PROPERTY: header-args: :mkdirp yes
|
||||
|
||||
#+MACRO: VENUE (eval (or (getenv "VENUE") "arxiv"))
|
||||
#+SETUPFILE: setup/venue-{{{VENUE}}}.org
|
||||
|
||||
#+MACRO: IF-SHORT (eval (when (bound-and-true-p paper-short) ""))
|
||||
#+MACRO: IF-LONG (eval (unless (bound-and-true-p paper-short) ""))
|
||||
#+MACRO: IF-ANON (eval (when (bound-and-true-p paper-anon) ""))
|
||||
#+MACRO: IF-LIMITFIG (eval (when (bound-and-true-p paper-limit-figs) ""))
|
||||
|
||||
* Abstract :export:
|
||||
PolyPaper demonstrates building venue-specific PDFs from a single Org source.
|
||||
|
||||
* Introduction :export:
|
||||
- One literate Org source.
|
||||
- Venue profiles in =setup/=.
|
||||
- Reproducible figures via Org Babel.
|
||||
- Conditional content via tags/macros.
|
||||
|
||||
{{{IF-ANON}}}
|
||||
Double-blind mode replaces author name and redacts URLs.
|
||||
{{{end}}}
|
||||
|
||||
* Methods :export:
|
||||
We generate a simple figure via Python/Matplotlib.
|
||||
|
||||
#+name: fig-core
|
||||
#+begin_src python :var seed=123
|
||||
import numpy as np, matplotlib.pyplot as plt
|
||||
np.random.seed(seed)
|
||||
x=np.linspace(0,10,200); y=np.sin(x)+0.15*np.random.randn(200)
|
||||
plt.figure(); plt.plot(x,y); plt.xlabel("x"); plt.ylabel("y")
|
||||
out="figs/sine-core.pdf"; plt.savefig(out, bbox_inches="tight"); out
|
||||
#+end_src
|
||||
|
||||
#+caption: Core figure used in all venues.
|
||||
#+attr_latex: :width 0.8\linewidth
|
||||
#+RESULTS: fig-core
|
||||
file:figs/sine-core.pdf
|
||||
|
||||
* Results :export:
|
||||
Here is a citation [cite:@demo2020].
|
||||
|
||||
{{{IF-LIMITFIG}}}
|
||||
** Extra figures (excluded when figure-limited) :noexport:
|
||||
Text here won't export when =paper-limit-figs=t=.
|
||||
{{{end}}}
|
||||
|
||||
{{{IF-LONG}}}
|
||||
* Appendix :export:
|
||||
Extended content appears only for non-short profiles.
|
||||
{{{end}}}
|
||||
|
||||
* Data and Code Availability :export:
|
||||
# This section is auto-generated from repo_meta.json.
|
||||
|
||||
#+name: availability
|
||||
#+begin_src python :var meta_file="repo_meta.json" :results raw :exports results :cache yes
|
||||
import json, textwrap
|
||||
m=json.load(open(meta_file, "r", encoding="utf-8"))
|
||||
lines = []
|
||||
lines.append("*Data and Code Availability*")
|
||||
if m.get("url"):
|
||||
lines.append(f"- Code repository: [[{m['url']}][{m.get('repo_name', m['url'])}]]")
|
||||
if m.get("license"):
|
||||
lines.append(f"- License: {m['license']} (see LICENSE file)")
|
||||
if m.get("code_archive_doi"):
|
||||
lines.append(f"- Code archive DOI: {m['code_archive_doi']}")
|
||||
if m.get("data_availability"):
|
||||
lines.append(f"- Data availability: {m['data_availability']}")
|
||||
dls = m.get("data_links", [])
|
||||
if dls:
|
||||
lines.append("- Data links:")
|
||||
for d in dls:
|
||||
if 'url' in d:
|
||||
label = d.get('label', d['url'])
|
||||
lines.append(f" - [[{d['url']}][{label}]]")
|
||||
steps = m.get("repro_instructions", [])
|
||||
if steps:
|
||||
lines.append("- Reproducibility:")
|
||||
for st in steps:
|
||||
lines.append(f" - {st}")
|
||||
if m.get("contact_email"):
|
||||
lines.append(f"- Contact: {m['contact_email']}")
|
||||
print("\n".join(lines))
|
||||
#+end_src
|
||||
|
||||
#+RESULTS: availability
|
||||
|
||||
* References :export:
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 200">
|
||||
<rect width="640" height="200" fill="#0b132b"/>
|
||||
<g font-family="Segoe UI, Roboto, Helvetica, Arial, sans-serif" font-weight="700">
|
||||
<text x="40" y="110" font-size="72" fill="#e0fbfc">Poly</text>
|
||||
<text x="230" y="110" font-size="72" fill="#98c1d9">Paper</text>
|
||||
</g>
|
||||
<g font-family="Segoe UI, Roboto, Helvetica, Arial, sans-serif" font-weight="400">
|
||||
<text x="42" y="160" font-size="22" fill="#e0fbfc">One manuscript, many venues — Org-mode → LaTeX, reproducibly.</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 607 B |
|
|
@ -0,0 +1,25 @@
|
|||
name: Build PolyPaper (Forgejo)
|
||||
on: [push, pull_request, workflow_dispatch]
|
||||
jobs:
|
||||
build:
|
||||
runs-on: docker
|
||||
strategy: { fail-fast: false, matrix: { venue: [arxiv, ieee, elsevier, acm] } }
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build Docker image
|
||||
run: docker build -f Dockerfile.full -t polypaper:full .
|
||||
- name: Validate metadata
|
||||
run: docker run --rm -v $GITHUB_WORKSPACE:/work -w /work polypaper:full bash -lc 'chmod +x scripts/check_metadata.py && scripts/check_metadata.py'
|
||||
- name: Build PDFs and HTML (${{ matrix.venue }})
|
||||
run: |
|
||||
docker run --rm -v $GITHUB_WORKSPACE:/work -w /work polypaper:full bash -lc 'make VENUE=${{ matrix.venue }}'
|
||||
docker run --rm -v $GITHUB_WORKSPACE:/work -w /work polypaper:full bash -lc 'make supplement VENUE=${{ matrix.venue }}'
|
||||
docker run --rm -v $GITHUB_WORKSPACE:/work -w /work polypaper:full bash -lc 'make camera-ready VENUE=${{ matrix.venue }}'
|
||||
docker run --rm -v $GITHUB_WORKSPACE:/work -w /work polypaper:full bash -lc 'make site VENUE=${{ matrix.venue }}'
|
||||
- name: Archive outputs
|
||||
run: |
|
||||
mkdir -p artifacts/${{ matrix.venue }}
|
||||
mv paper-${{ matrix.venue }}.pdf artifacts/${{ matrix.venue }}/ || true
|
||||
mv paper-supplement-${{ matrix.venue }}.pdf artifacts/${{ matrix.venue }}/ || true
|
||||
mv paper-camera-ready-${{ matrix.venue }}.pdf artifacts/${{ matrix.venue }}/ || true
|
||||
cp -a public artifacts/${{ matrix.venue }}/ || true
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
name: Build PolyPaper
|
||||
|
||||
on: [push, pull_request, workflow_dispatch]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix: { venue: [arxiv, ieee, elsevier, acm] }
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build Docker image
|
||||
run: docker build -f Dockerfile.full -t polypaper:full .
|
||||
- name: Validate metadata (in container)
|
||||
run: docker run --rm -v ${{ github.workspace }}:/work -w /work polypaper:full bash -lc 'chmod +x scripts/check_metadata.py && scripts/check_metadata.py'
|
||||
- name: Build PDFs and HTML (${{ matrix.venue }})
|
||||
run: |
|
||||
docker run --rm -v ${{ github.workspace }}:/work -w /work polypaper:full bash -lc 'make VENUE=${{ matrix.venue }}'
|
||||
docker run --rm -v ${{ github.workspace }}:/work -w /work polypaper:full bash -lc 'make supplement VENUE=${{ matrix.venue }}'
|
||||
docker run --rm -v ${{ github.workspace }}:/work -w /work polypaper:full bash -lc 'make camera-ready VENUE=${{ matrix.venue }}'
|
||||
docker run --rm -v ${{ github.workspace }}:/work -w /work polypaper:full bash -lc 'make site VENUE=${{ matrix.venue }}'
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: polypaper-${{ matrix.venue }}
|
||||
path: |
|
||||
paper-${{ matrix.venue }}.pdf
|
||||
paper-supplement-${{ matrix.venue }}.pdf
|
||||
paper-camera-ready-${{ matrix.venue }}.pdf
|
||||
public/paper.html
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
.DS_Store
|
||||
*.aux
|
||||
*.bbl
|
||||
*.bcf
|
||||
*.blg
|
||||
*.fdb_latexmk
|
||||
*.fls
|
||||
*.log
|
||||
*.out
|
||||
*.run.xml
|
||||
*.toc
|
||||
*.synctex.gz
|
||||
build/
|
||||
public/
|
||||
figs/
|
||||
code/
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.venv/
|
||||
env/
|
||||
*~
|
||||
\#*\#
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
cff-version: 1.2.0
|
||||
message: "If you use this project, please cite it as below."
|
||||
title: "PolyPaper"
|
||||
authors:
|
||||
- family-names: "Elsberry"
|
||||
given-names: "Wesley R."
|
||||
orcid: "https://orcid.org/0000-0000-0000-0000"
|
||||
identifiers:
|
||||
- type: doi
|
||||
value: 10.5281/zenodo.0000000
|
||||
repository-code: "https://example.org/polypaper"
|
||||
license: MIT
|
||||
version: "0.1.0"
|
||||
date-released: "2025-10-04"
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Code of Conduct
|
||||
|
||||
We follow the Contributor Covenant. Be kind.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Contributing
|
||||
|
||||
Thanks for considering a contribution! See issues for ideas.
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
# syntax=docker/dockerfile:1
|
||||
FROM ubuntu:24.04
|
||||
ENV DEBIAN_FRONTEND=noninteractive PYTHONUNBUFFERED=1 LC_ALL=C.UTF-8 LANG=C.UTF-8
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
ca-certificates curl git make emacs-nox python3 python3-pip python3-matplotlib \
|
||||
latexmk biber texlive-full && rm -rf /var/lib/apt/lists/*
|
||||
RUN useradd -m -u 1000 builder
|
||||
WORKDIR /work
|
||||
USER builder
|
||||
CMD ["bash", "-lc", "make VENUE=arxiv"]
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
# syntax=docker/dockerfile:1
|
||||
FROM ubuntu:24.04
|
||||
ENV DEBIAN_FRONTEND=noninteractive PYTHONUNBUFFERED=1 LC_ALL=C.UTF-8 LANG=C.UTF-8 PATH=/opt/TinyTeX/bin/x86_64-linux:$PATH
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
ca-certificates curl git make emacs-nox python3 python3-pip python3-matplotlib perl && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
RUN curl -sL https://yihui.org/tinytex/install-unx.sh | sh -s - --admin --no-path && \
|
||||
/opt/TinyTeX/bin/*/tlmgr path add && \
|
||||
tlmgr install latexmk biber latex-bin biblatex hyperref geometry microtype etoolbox enumitem xcolor listings IEEEtran acmart elsarticle && \
|
||||
tlmgr path add
|
||||
RUN useradd -m -u 1000 builder
|
||||
WORKDIR /work
|
||||
USER builder
|
||||
CMD ["bash", "-lc", "make VENUE=arxiv"]
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2025 Your Name
|
||||
|
||||
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.
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
VENUE ?= arxiv
|
||||
JOB ?= paper-$(VENUE)
|
||||
|
||||
all: $(JOB).pdf
|
||||
|
||||
$(JOB).pdf: paper.org setup/venue-$(VENUE).org build.el biblio.bib
|
||||
emacs -Q --batch -l build.el --eval "(setenv \"VENUE\" \"$(VENUE)\")" --funcall wes/export-pdf-cli
|
||||
|
||||
site:
|
||||
emacs -Q --batch -l build.el --eval "(setenv \"VENUE\" \"$(VENUE)\")" --funcall wes/publish-site-cli
|
||||
@echo "HTML written to public/ (paper.org → public/paper.html)"
|
||||
|
||||
supplement:
|
||||
emacs -Q --batch -l build.el --eval "(setenv \"VENUE\" \"$(VENUE)\")" --funcall wes/export-supplement-pdf-cli
|
||||
|
||||
camera-ready:
|
||||
emacs -Q --batch -l build.el --eval "(setenv \"VENUE\" \"$(VENUE)\")" --funcall wes/export-camera-ready-pdf-cli
|
||||
|
||||
clean:
|
||||
latexmk -C
|
||||
rm -f paper-*.pdf
|
||||
|
||||
# Dockerized builds
|
||||
DOCKER_IMAGE ?= polypaper:full
|
||||
DOCKERFILE ?= Dockerfile.full
|
||||
|
||||
build-image:
|
||||
docker build -f $(DOCKERFILE) -t $(DOCKER_IMAGE) .
|
||||
|
||||
docker:
|
||||
docker run --rm -u $$(id -u):$$(id -g) -v $$(pwd):/work -w /work $(DOCKER_IMAGE) bash -lc "make VENUE=$(VENUE)"
|
||||
|
||||
docker-supplement:
|
||||
docker run --rm -u $$(id -u):$$(id -g) -v $$(pwd):/work -w /work $(DOCKER_IMAGE) bash -lc "make supplement VENUE=$(VENUE)"
|
||||
|
||||
docker-camera-ready:
|
||||
docker run --rm -u $$(id -u):$$(id -g) -v $$(pwd):/work -w /work $(DOCKER_IMAGE) bash -lc "make camera-ready VENUE=$(VENUE)"
|
||||
|
||||
docker-site:
|
||||
docker run --rm -u $$(id -u):$$(id -g) -v $$(pwd):/work -w /work $(DOCKER_IMAGE) bash -lc "make site VENUE=$(VENUE)"
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
<div align="center">
|
||||
|
||||
<img src="polypaper-logo.svg" alt="PolyPaper logo" width="540"/>
|
||||
|
||||
**PolyPaper**
|
||||
*One manuscript, many venues — Org-mode → LaTeX, reproducibly.*
|
||||
|
||||
[](#)
|
||||
[](LICENSE)
|
||||
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
# PolyPaper: Org → Multi-venue LaTeX Toolkit
|
||||
|
||||
This is a literate, *single-source* paper template that exports venue-specific PDFs and HTML.
|
||||
|
||||
## Requirements
|
||||
- Emacs with Org-mode
|
||||
- TeX toolchain (`latexmk`, `biber`)
|
||||
- Python + Matplotlib
|
||||
|
||||
## Quick start
|
||||
```bash
|
||||
make VENUE=arxiv
|
||||
make VENUE=ieee
|
||||
make VENUE=elsevier
|
||||
make VENUE=acm
|
||||
make supplement VENUE=arxiv
|
||||
make camera-ready VENUE=ieee
|
||||
make site VENUE=arxiv
|
||||
```
|
||||
|
||||
## Data & Code Availability Appendix
|
||||
Edit `repo_meta.json` and rebuild. Validate with:
|
||||
```bash
|
||||
scripts/check_metadata.py
|
||||
```
|
||||
|
||||
## Dockerized builds
|
||||
```bash
|
||||
make build-image DOCKERFILE=Dockerfile.full DOCKER_IMAGE=polypaper:full
|
||||
make docker VENUE=arxiv
|
||||
```
|
||||
|
||||
## Continuous Integration
|
||||
- GitHub: `.github/workflows/build.yml`
|
||||
- Forgejo: `.forgejo/workflows/build.yml`
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
@article{demo2020,
|
||||
title = {A Demo Reference for PolyPaper},
|
||||
author = {Example, Ada and Example, Alan},
|
||||
journal = {Journal of Demos},
|
||||
year = {2020},
|
||||
volume = {1},
|
||||
number = {1},
|
||||
pages = {1--10}
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
;; Batch export & site publish
|
||||
(setq org-confirm-babel-evaluate nil)
|
||||
(setq org-latex-pdf-process '("latexmk -pdf -interaction=nonstopmode -shell-escape %f"))
|
||||
|
||||
(defun wes/export-pdf (&optional venue)
|
||||
(let* ((v (or venue (or (getenv "VENUE") "arxiv")))
|
||||
(outfile (format "paper-%s.pdf" v)))
|
||||
(with-current-buffer (find-file-noselect "paper.org")
|
||||
(setenv "VENUE" v)
|
||||
(org-latex-export-to-pdf nil nil nil t)
|
||||
(when (file-exists-p "paper.pdf")
|
||||
(rename-file "paper.pdf" outfile t))
|
||||
(message "Wrote %s" outfile))))
|
||||
|
||||
(defun wes/export-pdf-cli () (wes/export-pdf))
|
||||
|
||||
(require 'ox) (require 'ox-publish)
|
||||
(defun wes/publish-site (&optional venue)
|
||||
(let* ((v (or venue (or (getenv "VENUE") "arxiv"))))
|
||||
(setenv "VENUE" v)
|
||||
(setq org-publish-project-alist
|
||||
`(("site-html"
|
||||
:base-directory "."
|
||||
:publishing-directory "public"
|
||||
:publishing-function org-html-publish-to-html
|
||||
:with-author t :with-toc t :section-numbers t
|
||||
:html-head "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"
|
||||
:recursive nil
|
||||
:exclude "setup/\\|code/\\|figs/\\|public/\\|data/"
|
||||
:include ("paper.org")
|
||||
:select-tags ("export")
|
||||
:exclude-tags ,(if (member v '("ieee" "acm"))
|
||||
'("noexport" "appendix" "notes")
|
||||
'("noexport")))))
|
||||
(org-publish "site-html" t)
|
||||
(message "Published HTML site for %s" v)))
|
||||
|
||||
(defun wes/publish-site-cli () (wes/publish-site))
|
||||
|
||||
(defun wes--cam-tight-latex ()
|
||||
(mapconcat #'identity
|
||||
'("\\usepackage{microtype}"
|
||||
"\\flushbottom"
|
||||
"\\setlength{\\textfloatsep}{10pt}"
|
||||
"\\setlength{\\floatsep}{8pt}"
|
||||
"\\setlength{\\intextsep}{8pt}"
|
||||
"\\usepackage{enumitem}"
|
||||
"\\setlist{nosep}"
|
||||
"\\usepackage{balance}")
|
||||
"\n"))
|
||||
|
||||
(defun wes/export-camera-ready-pdf (&optional venue)
|
||||
(let* ((v (or venue (or (getenv "VENUE") "arxiv")))
|
||||
(base-setup (expand-file-name (format "setup/venue-%s.org" v)))
|
||||
(tmp-name (format ".tmp-venue-%s-camera" v))
|
||||
(tmp-setup (expand-file-name (format "setup/%s.org" tmp-name)))
|
||||
(outfile (format "paper-camera-ready-%s.pdf" v)))
|
||||
(unless (file-exists-p base-setup)
|
||||
(error "Base setup file not found for venue %s" v))
|
||||
(with-temp-buffer
|
||||
(insert-file-contents base-setup)
|
||||
(goto-char (point-max))
|
||||
(insert "\n# Camera-ready overrides\n#+BIND: paper-anon nil\n")
|
||||
(insert (format "#+latex_header: %s\n" (wes--cam-tight-latex)))
|
||||
(write-region (point-min) (point-max) tmp-setup))
|
||||
(unwind-protect
|
||||
(progn
|
||||
(with-current-buffer (find-file-noselect "paper.org")
|
||||
(setenv "VENUE" tmp-name)
|
||||
(org-latex-export-to-pdf nil nil nil t)
|
||||
(when (file-exists-p "paper.pdf")
|
||||
(rename-file "paper.pdf" outfile t))
|
||||
(message "Wrote %s" outfile)))
|
||||
(ignore-errors (delete-file tmp-setup)))))
|
||||
|
||||
(defun wes/export-camera-ready-pdf-cli () (wes/export-camera-ready-pdf))
|
||||
|
||||
(defun wes/export-supplement-pdf (&optional venue)
|
||||
(let* ((v (or venue (or (getenv "VENUE") "arxiv")))
|
||||
(outfile (format "paper-supplement-%s.pdf" v))
|
||||
(paper-short nil) (paper-anon nil) (paper-limit-figs nil)
|
||||
(org-export-select-tags '("export"))
|
||||
(org-export-exclude-tags '("noexport")))
|
||||
(with-current-buffer (find-file-noselect "paper.org")
|
||||
(setenv "VENUE" v)
|
||||
(org-latex-export-to-pdf nil nil nil t)
|
||||
(when (file-exists-p "paper.pdf")
|
||||
(rename-file "paper.pdf" outfile t))
|
||||
(message "Wrote %s" outfile))))
|
||||
|
||||
(defun wes/export-supplement-pdf-cli () (wes/export-supplement-pdf))
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
services:
|
||||
paper:
|
||||
build: { context: ., dockerfile: Dockerfile.full }
|
||||
image: polypaper:full
|
||||
working_dir: /work
|
||||
volumes: [ ".:/work" ]
|
||||
command: bash -lc "make VENUE=${VENUE:-arxiv}"
|
||||
|
||||
paper-tiny:
|
||||
build: { context: ., dockerfile: Dockerfile.tinytex }
|
||||
image: polypaper:tinytex
|
||||
working_dir: /work
|
||||
volumes: [ ".:/work" ]
|
||||
command: bash -lc "make VENUE=${VENUE:-arxiv}"
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
# -*- org-export-allow-bind: t; -*-
|
||||
#+TITLE: Demo Paper (PolyPaper)
|
||||
#+AUTHOR: {{{NAME}}}
|
||||
#+FILETAGS: :export:
|
||||
#+OPTIONS: toc:2 num:t broken-links:auto
|
||||
#+PROPERTY: header-args:python :session py :results file graphics :exports results :cache yes
|
||||
#+PROPERTY: header-args: :mkdirp yes
|
||||
|
||||
#+MACRO: VENUE (eval (or (getenv "VENUE") "arxiv"))
|
||||
#+SETUPFILE: setup/venue-{{{VENUE}}}.org
|
||||
|
||||
#+MACRO: IF-SHORT (eval (when (bound-and-true-p paper-short) ""))
|
||||
#+MACRO: IF-LONG (eval (unless (bound-and-true-p paper-short) ""))
|
||||
#+MACRO: IF-ANON (eval (when (bound-and-true-p paper-anon) ""))
|
||||
#+MACRO: IF-LIMITFIG (eval (when (bound-and-true-p paper-limit-figs) ""))
|
||||
|
||||
* Abstract :export:
|
||||
PolyPaper demonstrates building venue-specific PDFs from a single Org source.
|
||||
|
||||
* Introduction :export:
|
||||
- One literate Org source.
|
||||
- Venue profiles in =setup/=.
|
||||
- Reproducible figures via Org Babel.
|
||||
- Conditional content via tags/macros.
|
||||
|
||||
{{{IF-ANON}}}
|
||||
Double-blind mode replaces author name and redacts URLs.
|
||||
{{{end}}}
|
||||
|
||||
* Methods :export:
|
||||
We generate a simple figure via Python/Matplotlib.
|
||||
|
||||
#+name: fig-core
|
||||
#+begin_src python :var seed=123
|
||||
import numpy as np, matplotlib.pyplot as plt
|
||||
np.random.seed(seed)
|
||||
x=np.linspace(0,10,200); y=np.sin(x)+0.15*np.random.randn(200)
|
||||
plt.figure(); plt.plot(x,y); plt.xlabel("x"); plt.ylabel("y")
|
||||
out="figs/sine-core.pdf"; plt.savefig(out, bbox_inches="tight"); out
|
||||
#+end_src
|
||||
|
||||
#+caption: Core figure used in all venues.
|
||||
#+attr_latex: :width 0.8\linewidth
|
||||
#+RESULTS: fig-core
|
||||
file:figs/sine-core.pdf
|
||||
|
||||
* Results :export:
|
||||
Here is a citation [cite:@demo2020].
|
||||
|
||||
{{{IF-LIMITFIG}}}
|
||||
** Extra figures (excluded when figure-limited) :noexport:
|
||||
Text here won't export when =paper-limit-figs=t=.
|
||||
{{{end}}}
|
||||
|
||||
{{{IF-LONG}}}
|
||||
* Appendix :export:
|
||||
Extended content appears only for non-short profiles.
|
||||
{{{end}}}
|
||||
|
||||
* Data and Code Availability :export:
|
||||
# This section is auto-generated from repo_meta.json.
|
||||
|
||||
#+name: availability
|
||||
#+begin_src python :var meta_file="repo_meta.json" :results raw :exports results :cache yes
|
||||
import json, textwrap
|
||||
m=json.load(open(meta_file, "r", encoding="utf-8"))
|
||||
lines = []
|
||||
lines.append("*Data and Code Availability*")
|
||||
if m.get("url"):
|
||||
lines.append(f"- Code repository: [[{m['url']}][{m.get('repo_name', m['url'])}]]")
|
||||
if m.get("license"):
|
||||
lines.append(f"- License: {m['license']} (see LICENSE file)")
|
||||
if m.get("code_archive_doi"):
|
||||
lines.append(f"- Code archive DOI: {m['code_archive_doi']}")
|
||||
if m.get("data_availability"):
|
||||
lines.append(f"- Data availability: {m['data_availability']}")
|
||||
dls = m.get("data_links", [])
|
||||
if dls:
|
||||
lines.append("- Data links:")
|
||||
for d in dls:
|
||||
if 'url' in d:
|
||||
label = d.get('label', d['url'])
|
||||
lines.append(f" - [[{d['url']}][{label}]]")
|
||||
steps = m.get("repro_instructions", [])
|
||||
if steps:
|
||||
lines.append("- Reproducibility:")
|
||||
for st in steps:
|
||||
lines.append(f" - {st}")
|
||||
if m.get("contact_email"):
|
||||
lines.append(f"- Contact: {m['contact_email']}")
|
||||
print("\n".join(lines))
|
||||
#+end_src
|
||||
|
||||
#+RESULTS: availability
|
||||
|
||||
* References :export:
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 200">
|
||||
<rect width="640" height="200" fill="#0b132b"/>
|
||||
<g font-family="Segoe UI, Roboto, Helvetica, Arial, sans-serif" font-weight="700">
|
||||
<text x="40" y="110" font-size="72" fill="#e0fbfc">Poly</text>
|
||||
<text x="230" y="110" font-size="72" fill="#98c1d9">Paper</text>
|
||||
</g>
|
||||
<g font-family="Segoe UI, Roboto, Helvetica, Arial, sans-serif" font-weight="400">
|
||||
<text x="42" y="160" font-size="22" fill="#e0fbfc">One manuscript, many venues — Org-mode → LaTeX, reproducibly.</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 607 B |
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"brand": "PolyPaper",
|
||||
"repo_name": "PolyPaper",
|
||||
"url": "https://example.org/polypaper",
|
||||
"contact_email": "you@example.org",
|
||||
"license": "MIT",
|
||||
"code_archive_doi": "10.5281/zenodo.0000000",
|
||||
"data_availability": "All data needed to evaluate the conclusions are available within the paper and its Supplementary Materials.",
|
||||
"data_links": [
|
||||
{
|
||||
"label": "Zenodo dataset",
|
||||
"url": "https://zenodo.org/record/0000000"
|
||||
},
|
||||
{
|
||||
"label": "OSF project",
|
||||
"url": "https://osf.io/xxxxx/"
|
||||
}
|
||||
],
|
||||
"software_env": {
|
||||
"python": ">=3.10",
|
||||
"packages": [
|
||||
"matplotlib",
|
||||
"numpy"
|
||||
],
|
||||
"latex": [
|
||||
"latexmk",
|
||||
"biber"
|
||||
]
|
||||
},
|
||||
"repro_instructions": [
|
||||
"Install TeX (with latexmk and biber).",
|
||||
"Ensure Python and Matplotlib are installed.",
|
||||
"Run `make VENUE=arxiv` to build the paper.",
|
||||
"Run `make supplement VENUE=arxiv` to build the supplement."
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
#!/usr/bin/env python3
|
||||
import sys, json, os
|
||||
META = "repo_meta.json"
|
||||
REQ = ["url", "license"]
|
||||
def fail(msg): print(f"[meta-check] {msg}", file=sys.stderr); sys.exit(1)
|
||||
if not os.path.exists(META): fail(f"{META} not found.")
|
||||
m = json.load(open(META, "r", encoding="utf-8"))
|
||||
missing = [k for k in REQ if not m.get(k)]
|
||||
if missing: fail("Missing required fields: " + ", ".join(missing))
|
||||
print("[meta-check] repo_meta.json looks OK.")
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
#+latex_class: acmart
|
||||
#+latex_class_options: [sigconf]
|
||||
#+latex_header: \citestyle{acmauthoryear}
|
||||
#+latex_header: \usepackage{microtype}
|
||||
#+latex_header: \usepackage[hidelinks]{hyperref}
|
||||
|
||||
#+latex_header: \usepackage[backend=biber,style=acmauthoryear,sorting=nyt]{biblatex}
|
||||
#+latex_header: \addbibresource{biblio.bib}
|
||||
#+latex_header: \AtEndDocument{\printbibliography}
|
||||
|
||||
#+select_tags: export
|
||||
#+exclude_tags: noexport appendix notes
|
||||
|
||||
#+BIND: paper-short t
|
||||
#+BIND: paper-anon t
|
||||
#+BIND: paper-limit-figs t
|
||||
|
||||
#+MACRO: NAME (eval (if (bound-and-true-p paper-anon) "Anonymous" "Wesley R. Elsberry"))
|
||||
|
||||
# ACM CCS taxonomy placeholders
|
||||
#+latex_header: \begin{CCSXML}
|
||||
#+latex_header: <ccs2012>
|
||||
#+latex_header: <concept>
|
||||
#+latex_header: <concept_id>10010147.10010257</concept_id>
|
||||
#+latex_header: <concept_desc>Computing methodologies~Machine learning</concept_desc>
|
||||
#+latex_header: <concept_significance>500</concept_significance>
|
||||
#+latex_header: </concept>
|
||||
#+latex_header: </ccs2012>
|
||||
#+latex_header: \end{CCSXML}
|
||||
#+latex_header: \ccsdesc[500]{Computing methodologies~Machine learning}
|
||||
#+latex_header: \keywords{add, your, keywords}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#+latex_class: article
|
||||
#+latex_class_options: [10pt]
|
||||
#+latex_header: \usepackage[margin=1in]{geometry}
|
||||
#+latex_header: \usepackage{microtype}
|
||||
#+latex_header: \usepackage[hidelinks]{hyperref}
|
||||
|
||||
#+latex_header: \usepackage[backend=biber,style=authoryear,maxbibnames=99]{biblatex}
|
||||
#+latex_header: \addbibresource{biblio.bib}
|
||||
#+latex_header: \AtEndDocument{\printbibliography}
|
||||
|
||||
#+select_tags: export
|
||||
#+exclude_tags: noexport
|
||||
|
||||
#+BIND: paper-short nil
|
||||
#+BIND: paper-anon nil
|
||||
#+BIND: paper-limit-figs nil
|
||||
|
||||
#+MACRO: NAME (eval (if (bound-and-true-p paper-anon) "Anonymous" "Wesley R. Elsberry"))
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
#+latex_class: elsarticle
|
||||
#+latex_class_options: [preprint,12pt]
|
||||
#+latex_header: \usepackage{microtype}
|
||||
#+latex_header: \usepackage[hidelinks]{hyperref}
|
||||
#+latex_header: \usepackage{lineno}
|
||||
#+latex_header: \usepackage[margin=1in]{geometry}
|
||||
|
||||
#+latex_header: \usepackage[backend=biber,style=authoryear,maxbibnames=99]{biblatex}
|
||||
#+latex_header: \addbibresource{biblio.bib}
|
||||
#+latex_header: \AtEndDocument{\printbibliography}
|
||||
|
||||
#+select_tags: export
|
||||
#+exclude_tags: noexport
|
||||
|
||||
#+BIND: paper-short nil
|
||||
#+BIND: paper-anon nil
|
||||
#+BIND: paper-limit-figs nil
|
||||
|
||||
#+MACRO: NAME (eval (if (bound-and-true-p paper-anon) "Anonymous" "Wesley R. Elsberry"))
|
||||
|
||||
# Elsevier author/affiliation placeholders
|
||||
#+latex_header: \author[1]{Wesley R. Elsberry\corref{cor1}}
|
||||
#+latex_header: \ead{welsberr@example.org}
|
||||
#+latex_header: \author[2]{Coauthor A. Name}
|
||||
#+latex_header: \address[1]{Department, University, City, Country}
|
||||
#+latex_header: \address[2]{Institute, Organization, City, Country}
|
||||
#+latex_header: \cortext[cor1]{Corresponding author.}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
#+latex_class: IEEEtran
|
||||
#+latex_class_options: [conference]
|
||||
#+latex_header: \usepackage{microtype}
|
||||
#+latex_header: \usepackage[hidelinks]{hyperref}
|
||||
|
||||
#+latex_header: \usepackage[backend=biber,style=ieee,sorting=none]{biblatex}
|
||||
#+latex_header: \addbibresource{biblio.bib}
|
||||
#+latex_header: \AtEndDocument{\printbibliography}
|
||||
|
||||
#+select_tags: export
|
||||
#+exclude_tags: noexport appendix notes
|
||||
|
||||
#+BIND: paper-short t
|
||||
#+BIND: paper-anon t
|
||||
#+BIND: paper-limit-figs t
|
||||
|
||||
#+MACRO: NAME (eval (if (bound-and-true-p paper-anon) "Anonymous" "Wesley R. Elsberry"))
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"brand": "PolyPaper",
|
||||
"repo_name": "PolyPaper",
|
||||
"url": "https://example.org/polypaper",
|
||||
"contact_email": "you@example.org",
|
||||
"license": "MIT",
|
||||
"code_archive_doi": "10.5281/zenodo.0000000",
|
||||
"data_availability": "All data needed to evaluate the conclusions are available within the paper and its Supplementary Materials.",
|
||||
"data_links": [
|
||||
{
|
||||
"label": "Zenodo dataset",
|
||||
"url": "https://zenodo.org/record/0000000"
|
||||
},
|
||||
{
|
||||
"label": "OSF project",
|
||||
"url": "https://osf.io/xxxxx/"
|
||||
}
|
||||
],
|
||||
"software_env": {
|
||||
"python": ">=3.10",
|
||||
"packages": [
|
||||
"matplotlib",
|
||||
"numpy"
|
||||
],
|
||||
"latex": [
|
||||
"latexmk",
|
||||
"biber"
|
||||
]
|
||||
},
|
||||
"repro_instructions": [
|
||||
"Install TeX (with latexmk and biber).",
|
||||
"Ensure Python and Matplotlib are installed.",
|
||||
"Run `make VENUE=arxiv` to build the paper.",
|
||||
"Run `make supplement VENUE=arxiv` to build the supplement."
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
#!/usr/bin/env python3
|
||||
import sys, json, os
|
||||
META = "repo_meta.json"
|
||||
REQ = ["url", "license"]
|
||||
def fail(msg): print(f"[meta-check] {msg}", file=sys.stderr); sys.exit(1)
|
||||
if not os.path.exists(META): fail(f"{META} not found.")
|
||||
m = json.load(open(META, "r", encoding="utf-8"))
|
||||
missing = [k for k in REQ if not m.get(k)]
|
||||
if missing: fail("Missing required fields: " + ", ".join(missing))
|
||||
print("[meta-check] repo_meta.json looks OK.")
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
#+latex_class: acmart
|
||||
#+latex_class_options: [sigconf]
|
||||
#+latex_header: \citestyle{acmauthoryear}
|
||||
#+latex_header: \usepackage{microtype}
|
||||
#+latex_header: \usepackage[hidelinks]{hyperref}
|
||||
|
||||
#+latex_header: \usepackage[backend=biber,style=acmauthoryear,sorting=nyt]{biblatex}
|
||||
#+latex_header: \addbibresource{biblio.bib}
|
||||
#+latex_header: \AtEndDocument{\printbibliography}
|
||||
|
||||
#+select_tags: export
|
||||
#+exclude_tags: noexport appendix notes
|
||||
|
||||
#+BIND: paper-short t
|
||||
#+BIND: paper-anon t
|
||||
#+BIND: paper-limit-figs t
|
||||
|
||||
#+MACRO: NAME (eval (if (bound-and-true-p paper-anon) "Anonymous" "Wesley R. Elsberry"))
|
||||
|
||||
# ACM CCS taxonomy placeholders
|
||||
#+latex_header: \begin{CCSXML}
|
||||
#+latex_header: <ccs2012>
|
||||
#+latex_header: <concept>
|
||||
#+latex_header: <concept_id>10010147.10010257</concept_id>
|
||||
#+latex_header: <concept_desc>Computing methodologies~Machine learning</concept_desc>
|
||||
#+latex_header: <concept_significance>500</concept_significance>
|
||||
#+latex_header: </concept>
|
||||
#+latex_header: </ccs2012>
|
||||
#+latex_header: \end{CCSXML}
|
||||
#+latex_header: \ccsdesc[500]{Computing methodologies~Machine learning}
|
||||
#+latex_header: \keywords{add, your, keywords}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#+latex_class: article
|
||||
#+latex_class_options: [10pt]
|
||||
#+latex_header: \usepackage[margin=1in]{geometry}
|
||||
#+latex_header: \usepackage{microtype}
|
||||
#+latex_header: \usepackage[hidelinks]{hyperref}
|
||||
|
||||
#+latex_header: \usepackage[backend=biber,style=authoryear,maxbibnames=99]{biblatex}
|
||||
#+latex_header: \addbibresource{biblio.bib}
|
||||
#+latex_header: \AtEndDocument{\printbibliography}
|
||||
|
||||
#+select_tags: export
|
||||
#+exclude_tags: noexport
|
||||
|
||||
#+BIND: paper-short nil
|
||||
#+BIND: paper-anon nil
|
||||
#+BIND: paper-limit-figs nil
|
||||
|
||||
#+MACRO: NAME (eval (if (bound-and-true-p paper-anon) "Anonymous" "Wesley R. Elsberry"))
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
#+latex_class: elsarticle
|
||||
#+latex_class_options: [preprint,12pt]
|
||||
#+latex_header: \usepackage{microtype}
|
||||
#+latex_header: \usepackage[hidelinks]{hyperref}
|
||||
#+latex_header: \usepackage{lineno}
|
||||
#+latex_header: \usepackage[margin=1in]{geometry}
|
||||
|
||||
#+latex_header: \usepackage[backend=biber,style=authoryear,maxbibnames=99]{biblatex}
|
||||
#+latex_header: \addbibresource{biblio.bib}
|
||||
#+latex_header: \AtEndDocument{\printbibliography}
|
||||
|
||||
#+select_tags: export
|
||||
#+exclude_tags: noexport
|
||||
|
||||
#+BIND: paper-short nil
|
||||
#+BIND: paper-anon nil
|
||||
#+BIND: paper-limit-figs nil
|
||||
|
||||
#+MACRO: NAME (eval (if (bound-and-true-p paper-anon) "Anonymous" "Wesley R. Elsberry"))
|
||||
|
||||
# Elsevier author/affiliation placeholders
|
||||
#+latex_header: \author[1]{Wesley R. Elsberry\corref{cor1}}
|
||||
#+latex_header: \ead{welsberr@example.org}
|
||||
#+latex_header: \author[2]{Coauthor A. Name}
|
||||
#+latex_header: \address[1]{Department, University, City, Country}
|
||||
#+latex_header: \address[2]{Institute, Organization, City, Country}
|
||||
#+latex_header: \cortext[cor1]{Corresponding author.}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
#+latex_class: IEEEtran
|
||||
#+latex_class_options: [conference]
|
||||
#+latex_header: \usepackage{microtype}
|
||||
#+latex_header: \usepackage[hidelinks]{hyperref}
|
||||
|
||||
#+latex_header: \usepackage[backend=biber,style=ieee,sorting=none]{biblatex}
|
||||
#+latex_header: \addbibresource{biblio.bib}
|
||||
#+latex_header: \AtEndDocument{\printbibliography}
|
||||
|
||||
#+select_tags: export
|
||||
#+exclude_tags: noexport appendix notes
|
||||
|
||||
#+BIND: paper-short t
|
||||
#+BIND: paper-anon t
|
||||
#+BIND: paper-limit-figs t
|
||||
|
||||
#+MACRO: NAME (eval (if (bound-and-true-p paper-anon) "Anonymous" "Wesley R. Elsberry"))
|
||||
Loading…
Reference in New Issue