| {/* IMPORTS */} |
| import { Image } from 'astro:assets'; |
| import placeholder from '../assets/images/placeholder.png'; |
| import Sidenote from '../../components/Sidenote.astro'; |
| import Wide from '../../components/Wide.astro'; |
| import Note from '../../components/Note.astro'; |
| import FullWidth from '../../components/FullWidth.astro'; |
| import HtmlEmbed from '../../components/HtmlEmbed.astro'; |
| import audioDemo from '../assets/audio/audio-example.wav'; |
|
|
| |
|
|
| |
|
|
| Your **article** lives in **one place** |
|
|
| Everything is **self-contained** under `app/src/content/`: |
| - **MDX**: `article.mdx` and [**optional chapters**]( |
| - **Assets**: `assets/` images, audios, datas, etc. (tracked via **Git LFS**) |
| - **Embeds**: `embed/` [**HtmlEmbed**]( |
|
|
| The `article.mdx` file is the **main entry point** of your article. |
|
|
| **MDX** is a mix of **Markdown** and **HTML/JSX**: write regular Markdown, and embed **interactive components** inline when needed. We’ll describe the available options you can use later in this guide. |
|
|
| Here's what the file looks like in detail: |
|
|
| <small className="muted">app/src/content/article.mdx</small> |
| ```mdx |
| {/* |
| |
| {/* |
| title: "This is the main title" |
| subtitle: "This will be displayed just below the banner" |
| description: "A modern, MDX-first research article template with math, citations, and interactive figures." |
| published: "Feb 19, 2025" |
| tags: |
| - research |
| - template |
| authors: |
| - name: "Thibaud Frere" {/* Author name */} |
| url: "https://huggingface.co/tfrere" {/* Optional author url */} |
| affiliations: [1] {/* Optional author affiliations based on the list below */} |
| - name: "Alice Martin" |
| url: "https://example.com/~alice" |
| affiliations: [1, 2] |
| - name: "Robert Brown" |
| url: "https://example.com/~bob" |
| affiliations: [2] |
| |
| {/* |
| affiliations: {/* Affiliations list */} |
| - name: "Hugging Face" |
| url: "https://huggingface.co" |
| - name: "Example University" |
| url: "https://example.edu" |
| doi: 10.1234/abcd.efgh {/* Add a DOI to your article */} |
| {/* Add a licence text to the end of your article */} |
| licence: Diagrams and text are licensed under <a href="https://creativecommons.org/licenses/by/4.0/" target="_blank" rel="noopener noreferrer">CC‑BY 4.0</a> with the source available on <a href="https://huggingface.co/spaces/stfrere/research-article-template">Hugging Face</a>, unless noted otherwise. Figures reused from other sources are excluded and marked in their captions (“Figure from …”). |
| seoThumbImage: "https://example.com/thumb.png" {/* Override default thumbnail */} |
| tableOfContentsAutoCollapse: true {/* By default the table of contents is not collapsing */} |
| |
|
|
| {/* |
| import placeholder from '../assets/images/placeholder.png' |
| import ResponsiveImage from '../components/ResponsiveImage.astro' |
| import Sidenote from '../components/Sidenote.astro' |
|
|
| {/* |
| <Sidenote> |
| This paragraph is written in Markdown. |
| <Fragment slot="aside">A short callout inserted via a component.</Fragment> |
| </Sidenote> |
| <ResponsiveImage src={placeholder} alt="Sample image with optimization" /> |
|
|
| This paragraph is also written in Markdown. |
| ``` |
|
|
|
|
|
|
| |
|
|
|
|
| **If** your article becomes **too long** for one file, you can **organize** it into **separate chapters**. |
|
|
| Simply **create a new file** in the `app/src/content/chapters` **directory**. |
| Then, **include** your new chapter in the main `article.mdx` like below. |
|
|
|
|
| <small className="muted">Example</small> |
| ```mdx |
| import MyChapter from './chapters/my-chapter.mdx'; |
|
|
| <MyChapter /> |
| ``` |
| <small className="muted">You can see a living example here <a target="_blank" href="https://huggingface.co/spaces/tfrere/research-article-template/blob/main/app/src/content/chapters/best-pratices.mdx">app/src/content/chapters/best-pratices.mdx</a>.</small> |
|
|
| |
| |
| The **Table of contents** is generated **automatically** from your **H2–H4** headings. Keep headings **short** and **descriptive**; links work on **desktop** and **mobile**. |
|
|
| <Note variant="info">You can make the table of contents collapse by changing the `tableOfContentsAutoCollapse` parameter in the frontmatter. Which is `true` by default.</Note> |
|
|
| |
|
|
| All **interactive elements** (buttons, inputs, cards, etc.) are themed with the **primary color** you choose. |
|
|
| You can **update this main color** to match your brand by changing the ` |
|
|
| Use the **color picker** below to see how the primary color affects the theme. |
|
|
| |
|
|
| <Sidenote> |
| <HtmlEmbed frameless src="color-picker.html" /> |
| <Fragment slot="aside"> |
| You can use the color picker to select the right color. |
| |
| Here is an example of an <a href="#">interactive element</a>. |
| </Fragment> |
| </Sidenote> |
|
|
|
|
| |
|
|
| Here is a suggestion of **color palettes** for your **data visualizations** that align with your **brand identity**. These palettes are generated from your ` |
|
|
| <HtmlEmbed frameless src="palettes.html" /> |
| <br/> |
| **Use color with care.** |
| Color should rarely be the only channel of meaning. |
| Always pair it with text, icons, shape or position. The simulation helps you spot palettes and states that become indistinguishable for people with color‑vision deficiencies. |
|
|
| |
|
|
| |
| Use the generated **CSS variables** to style elements. |
|
|
| ```css |
| /* Usage */ |
| .series-a { color: var( |
| .series-b { color: var( |
| .heatmap-low { background: var( |
| .heatmap-high { background: var( |
| .neg { color: var( |
| .pos { color: var( |
|
|
| /* Override size */ |
| :root { |
| :root { |
| ``` |
|
|
| <Note variant="info">⚠️ **CSS overrides** automatically trigger a **palette regeneration** via JS observers; no manual call is needed.</Note> |
|
|
| |
| Fetch arrays of colors via **`window.ColorPalettes.getColors(type)`**. To change sizes **at runtime**, set CSS vars and call **`window.ColorPalettes.refresh()`**. |
|
|
| ```js |
| // Usage |
| const cat = window.ColorPalettes.getColors('categorical'); |
| const seq = window.ColorPalettes.getColors('sequential'); |
| const div = window.ColorPalettes.getColors('diverging'); |
|
|
| // Override size (runtime) |
| document.documentElement.style.setProperty(' |
| document.documentElement.style.setProperty(' |
| window.ColorPalettes.refresh(); |
| ``` |
|
|