|
1 | | -name: Draft PDF and Preprint Package |
2 | | - |
3 | | -on: |
4 | | - push: |
5 | | - branches: [main] |
6 | | - |
7 | | -env: |
8 | | - FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true |
9 | | - |
10 | | -jobs: |
11 | | - build-paper: |
12 | | - runs-on: ubuntu-latest |
13 | | - name: Build Preprint PDF and Package |
14 | | - |
15 | | - steps: |
16 | | - - name: Checkout repository |
17 | | - uses: actions/checkout@v6 |
18 | | - |
19 | | - - name: Install apt packages |
20 | | - run: | |
21 | | - sudo apt-get update |
22 | | - sudo apt-get install -y pandoc texlive texlive-latex-extra texlive-fonts-recommended texlive-xetex texlive-fonts-extra zip python3-yaml |
23 | | -
|
24 | | - - name: Extract JOSS frontmatter and build LaTeX assets |
| 1 | +- name: Extract Metadata and Build LaTeX Title |
25 | 2 | run: | |
26 | 3 | python3 - << 'PYEOF' |
27 | | - import yaml, re |
| 4 | + import yaml |
28 | 5 |
|
29 | 6 | with open('paper/paper.md', 'r') as f: |
30 | 7 | content = f.read() |
31 | 8 |
|
32 | 9 | parts = content.split('---\n') |
33 | 10 | fm = yaml.safe_load(parts[1]) |
34 | 11 |
|
35 | | - authors = fm.get('authors', []) |
36 | | - affiliations = {a['index']: a['name'] for a in fm.get('affiliations', [])} |
| 12 | + authors = fm.get('authors', []) |
| 13 | + affiliations = fm.get('affiliations', []) |
| 14 | + aff_map = {str(a['index']): a for a in affiliations} |
37 | 15 |
|
38 | | - # ── Pandoc metadata ─────────────────────────────────────────────────── |
39 | | - # Pass hyperref colours and geometry as Pandoc variables so they reach |
40 | | - # the template *before* \usepackage{hyperref} is emitted — avoids the |
41 | | - # option-clash that occurs when loading hyperref a second time in |
42 | | - # --include-in-header. |
| 16 | + # ── Pandoc Metadata ───────────────────────────────────────────────── |
43 | 17 | meta = { |
44 | | - 'title': fm.get('title', ''), |
45 | | - 'date': str(fm.get('date', '')), |
46 | | - 'colorlinks': True, |
47 | | - 'linkcolor': 'blue', |
48 | | - 'urlcolor': 'blue', |
49 | | - 'citecolor': 'blue', |
50 | | - 'geometry': 'a4paper, margin=2.5cm', |
| 18 | + 'title': fm.get('title', ''), |
| 19 | + 'date': str(fm.get('date', '')), |
| 20 | + 'colorlinks': True, |
| 21 | + 'linkcolor': 'blue', |
| 22 | + 'urlcolor': 'blue', |
| 23 | + 'citecolor': 'blue', |
| 24 | + 'geometry': 'a4paper, margin=2.5cm', |
51 | 25 | } |
52 | 26 | with open('/tmp/pandoc_meta.yaml', 'w') as f: |
53 | | - yaml.dump(meta, f, allow_unicode=True) |
| 27 | + yaml.dump(meta, f) |
54 | 28 |
|
55 | | - # ── LaTeX title block ───────────────────────────────────────────────── |
56 | | - lines = [] |
57 | | - lines.append(r'\begin{center}') |
58 | | - lines.append(r'{\LARGE\bfseries ' + fm.get('title','').replace('&', r'\&') + r'}\\[0.8em]') |
| 29 | + # ── Title Block Construction ──────────────────────────────────────── |
| 30 | + lines = [r'\begin{center}'] |
| 31 | + lines.append(r'{\LARGE\bfseries ' + fm.get('title','') + r'}\\[1.2em]') |
59 | 32 |
|
60 | | - author_parts = [] |
| 33 | + auth_line = [] |
61 | 34 | for a in authors: |
62 | | - affs = a.get('affiliation', '') |
63 | | - nums = [s.strip() for s in str(affs).split(',')] |
64 | | - sup = ','.join(nums) |
65 | | - name = a['name'].replace('&', r'\&') |
| 35 | + name = a['name'] |
| 36 | + aff_indices = str(a.get('affiliation', '')).split(',') |
| 37 | + marker = ",".join([idx.strip() for idx in aff_indices]) |
66 | 38 | if a.get('corresponding'): |
67 | | - author_parts.append(rf'{name}$^{{{sup},*}}$') |
68 | | - else: |
69 | | - author_parts.append(rf'{name}$^{{{sup}}}$') |
70 | | -
|
71 | | - lines.append(r'\large ' + r',\quad '.join(author_parts) + r'\\[0.5em]') |
72 | | -
|
73 | | - for idx, name in sorted(affiliations.items()): |
74 | | - lines.append(rf'$^{{{idx}}}$\small {name.replace("&", r"&")}\\[0.2em]') |
75 | | -
|
76 | | - for a in authors: |
77 | | - if a.get('corresponding') and a.get('email'): |
78 | | - lines.append(r'\small $^{*}$Corresponding author: \href{mailto:' |
79 | | - + a['email'] + r'}{' + a['email'] + r'}\\[0.3em]') |
80 | | -
|
81 | | - lines.append(r'\small ' + str(fm.get('date','')) + r'\\') |
| 39 | + marker += r",*" |
| 40 | + auth_line.append(rf'{name}$^{{{marker}}}$') |
| 41 | + lines.append(r'\large ' + r', '.join(auth_line) + r'\\[0.8em]') |
| 42 | +
|
| 43 | + for idx, aff in aff_map.items(): |
| 44 | + ror_id = aff.get('ror', '') |
| 45 | + ror_link = rf" \small (ROR: \href{{https://ror.org/{ror_id}}}{{{ror_id}}})" if ror_id else "" |
| 46 | + lines.append(rf'$^{{{idx}}}$\small {aff["name"]}{ror_link}\\[0.2em]') |
| 47 | +
|
| 48 | + corres = [a['email'] for a in authors if a.get('corresponding') and a.get('email')] |
| 49 | + if corres: |
| 50 | + lines.append(rf'\small $^*$Corresponding author: \href{{mailto:{corres[0]}}}{{{corres[0]}}}\\[0.2em]') |
| 51 | + |
| 52 | + lines.append(r'\small DOI: \href{https://doi.org/10.5281/zenodo.18377216}{10.5281/zenodo.18377216}\\[0.2em]') |
| 53 | + lines.append(r'\small ' + str(fm.get('date',''))) |
82 | 54 | lines.append(r'\end{center}') |
83 | | - lines.append(r'\vspace{1em}') |
84 | | - lines.append(r'\noindent\rule{\textwidth}{0.4pt}') |
85 | | - lines.append(r'\vspace{0.5em}') |
| 55 | + lines.append(r'\vspace{0.5em}\noindent\rule{\textwidth}{0.6pt}\vspace{1.5em}') |
86 | 56 |
|
87 | 57 | with open('/tmp/title_block.tex', 'w') as f: |
88 | 58 | f.write('\n'.join(lines)) |
89 | | -
|
90 | | - print("Done. Authors:", [a['name'] for a in authors]) |
91 | 59 | PYEOF |
92 | 60 |
|
93 | | - - name: Create LaTeX header |
| 61 | + - name: Create Header |
94 | 62 | run: | |
95 | 63 | cat > /tmp/header.tex << 'EOF' |
96 | | - % ── URL breaking (loaded AFTER hyperref by Pandoc's template) ───────── |
97 | 64 | \usepackage{xurl} |
98 | | -
|
99 | | - % ── Fonts ───────────────────────────────────────────────────────────── |
100 | 65 | \usepackage{fontspec} |
101 | 66 | \setmainfont{TeX Gyre Termes} |
102 | | - \usepackage{microtype} |
103 | | -
|
104 | | - % ── Preprint watermark header ───────────────────────────────────────── |
| 67 | + \usepackage{unicode-math} |
| 68 | + \setmathfont{TeX Gyre Termes Math} |
105 | 69 | \usepackage{fancyhdr} |
106 | 70 | \usepackage{xcolor} |
107 | 71 | \pagestyle{fancy} |
108 | 72 | \fancyhf{} |
109 | | - \fancyhead[C]{% |
110 | | - \textcolor{red}{\textbf{PREPRINT\,---\,NOT PEER REVIEWED}}% |
111 | | - } |
| 73 | + |
| 74 | + % ── Clear Preprint Identification ─────────────────────────────────── |
| 75 | + \fancyhead[L]{\small \textbf{\textcolor{gray}{PREPRINT -- NOT PEER REVIEWED}}} |
| 76 | + \fancyhead[R]{\small \textit{PICA: Advanced Transport Automation}} |
112 | 77 | \fancyfoot[C]{\thepage} |
113 | 78 | \renewcommand{\headrulewidth}{0.4pt} |
114 | | -
|
115 | | - % ── Suppress Pandoc's auto title block (we use our own) ─────────────── |
| 79 | + |
| 80 | + % ── Internal Reference Logic ──────────────────────────────────────── |
116 | 81 | \renewcommand{\maketitle}{} |
| 82 | + \hypersetup{ |
| 83 | + breaklinks=true, |
| 84 | + pdfauthor={Deshmukh and Mukherjee}, |
| 85 | + pdftitle={PICA: High-Precision Automation} |
| 86 | + } |
117 | 87 | EOF |
118 | | -
|
119 | | - - name: Generate Preprint PDF and LaTeX source |
120 | | - run: | |
121 | | - cd paper |
122 | | -
|
123 | | - pandoc paper.md -o paper.pdf \ |
124 | | - --standalone \ |
125 | | - --citeproc \ |
126 | | - --pdf-engine=xelatex \ |
127 | | - --metadata-file=/tmp/pandoc_meta.yaml \ |
128 | | - --include-in-header=/tmp/header.tex \ |
129 | | - --include-before-body=/tmp/title_block.tex |
130 | | -
|
131 | | - pandoc paper.md -o paper.tex \ |
132 | | - --standalone \ |
133 | | - --citeproc \ |
134 | | - --pdf-engine=xelatex \ |
135 | | - --metadata-file=/tmp/pandoc_meta.yaml \ |
136 | | - --include-in-header=/tmp/header.tex \ |
137 | | - --include-before-body=/tmp/title_block.tex |
138 | | -
|
139 | | - zip preprint_submission.zip paper.tex |
140 | | -
|
141 | | - - name: Upload Preprint PDF |
142 | | - uses: actions/upload-artifact@v7 |
143 | | - with: |
144 | | - name: preprint-pdf |
145 | | - path: paper/paper.pdf |
146 | | - |
147 | | - - name: Upload Preprint Package |
148 | | - uses: actions/upload-artifact@v7 |
149 | | - with: |
150 | | - name: preprint-package |
151 | | - path: paper/preprint_submission.zip |
0 commit comments