thibaud frere commited on
Commit
3f64d97
·
1 Parent(s): d8d4124

feat(astro): port base Distill-like template into index.astro with TOC and Plotly

Browse files
Files changed (1) hide show
  1. app/src/pages/index.astro +143 -7
app/src/pages/index.astro CHANGED
@@ -1,21 +1,157 @@
1
  ---
2
  import { Image } from 'astro:assets';
3
  import banner from "../assets/images/banner.png";
4
- const title = 'Hello Astro on HF Spaces';
5
  ---
6
  <html lang="en">
7
  <head>
8
  <meta charset="utf-8" />
9
  <meta name="viewport" content="width=device-width, initial-scale=1" />
 
10
  <title>{title}</title>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  </head>
12
  <body>
13
- <main style="max-width: 720px; margin: 40px auto; font-family: system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, Helvetica Neue, Arial, Apple Color Emoji, Segoe UI Emoji;">
14
- <h1 style="margin:0 0 16px;">🚀 Hello World</h1>
15
- <p>Astro est déployé statiquement via Nginx sur le port 8080.</p>
16
- <figure>
17
- <Image src={banner} alt="FineTasks banner" widths={[480,768,1080,1440]} formats={["avif","webp","png"]} sizes="(max-width: 768px) 100vw, 720px" loading="lazy" decoding="async" />
18
- </figure>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  </main>
20
  </body>
21
  </html>
 
1
  ---
2
  import { Image } from 'astro:assets';
3
  import banner from "../assets/images/banner.png";
4
+ const title = 'The Distill Blog Template (Astro)';
5
  ---
6
  <html lang="en">
7
  <head>
8
  <meta charset="utf-8" />
9
  <meta name="viewport" content="width=device-width, initial-scale=1" />
10
+ <base target="_blank" />
11
  <title>{title}</title>
12
+ <script src="https://cdn.plot.ly/plotly-3.0.0.min.js" charset="utf-8"></script>
13
+ <style>
14
+ :root { --page-width: 980px; }
15
+ body { margin:0; font-family: system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, Helvetica Neue, Arial, Apple Color Emoji, Segoe UI Emoji; }
16
+ main { max-width: var(--page-width); margin: 24px auto; padding: 16px; }
17
+ .l-page { max-width: var(--page-width); margin: 0 auto; }
18
+ .l-screen { width: 100%; }
19
+ figure { margin: 16px 0; }
20
+ .figcaption, figcaption { color: rgba(0,0,0,.6); font-size: 12px; }
21
+ .plot-card { background: #fff; border: 1px solid rgba(0,0,0,.1); border-radius: 8px; padding: 12px; }
22
+ d-contents nav { border-left: 1px solid rgba(0,0,0,.1); padding-left: 16px; margin: 16px 0; }
23
+ .toc-header { display:flex; align-items:center; gap: 8px; cursor: pointer; user-select:none; }
24
+ .toc-title { font-weight: 600; }
25
+ .toggle-icon { transition: transform .2s ease; display:inline-block; }
26
+ .toggle-icon.collapsed { transform: rotate(-90deg); }
27
+ .toc-content.collapsed { display:none; }
28
+ d-article pre, d-code[block] { overflow:auto; background:#f6f8fa; border:1px solid #d0d7de; border-radius:6px; padding:12px; }
29
+ d-article table { border-collapse: collapse; width: 100%; }
30
+ d-article th, d-article td { border-bottom: 1px solid rgba(0,0,0,.1); padding: 6px 8px; text-align: left; }
31
+ aside { color: rgba(0,0,0,.6); font-size: 14px; }
32
+ </style>
33
  </head>
34
  <body>
35
+ <main>
36
+ <d-front-matter>
37
+ <script id='distill-front-matter' type="application/json">{ "title": "The Distill Blog Template", "description": "Building beautiful blog posts.", "published": "Feb 19, 2025", "affiliation": {"name": "YourCompany"}, "authors": [ { "author":"The Author (you!)", "authorURL":"https://huggingface.co/" } ] }</script>
38
+ </d-front-matter>
39
+
40
+ <d-title>
41
+ <h1 class="l-page" style="text-align: center;">The Distill Template:<br/>Craft Beautiful Blogs</h1>
42
+ <div id="title-plot" class="main-plot-container l-screen" style="overflow-x: hidden; width: 100%; text-align: center;">
43
+ <div style="display: flex; justify-content: center; position: relative;">
44
+ <figure class="l-page" style="margin:0;">
45
+ <Image src={banner} alt="Banner" widths={[480,768,1080,1440]} formats={["avif","webp","png"]} sizes="(max-width: 768px) 100vw, var(--page-width)" loading="eager" />
46
+ </figure>
47
+ </div>
48
+ <p style="text-align: center; font-style: italic; margin-top: 10px; max-width: 900px; margin-left: auto; margin-right: auto;">It's nice to have a cute interactive banner!</p>
49
+ </div>
50
+ </d-title>
51
+
52
+ <d-byline></d-byline>
53
+
54
+ <d-article>
55
+ <d-contents></d-contents>
56
+
57
+ <p>Welcome to the Distill Blog Template! This framework is based on the <a href="https://distill.pub/">distill.pub</a> design and has been adapted to make it easy for you to create beautiful, interactive technical blogs.</p>
58
+ <aside>Reading time: 10-15 minutes.</aside>
59
+ <p>This template includes support for mathematics, interactive visualizations, citations, footnotes, and more.</p>
60
+
61
+ <h2>Getting Started with the Template</h2>
62
+ <h3>Installation and Setup</h3>
63
+ <d-code block language="bash">npm install\nnpm run dev</d-code>
64
+
65
+ <h3>Mathematical Equations</h3>
66
+ <p>You can include inline math using <code>x^2 + y^2 = z^2</code>.</p>
67
+
68
+ <h3>Figures and Images</h3>
69
+ <figure>
70
+ <Image src={banner} alt="Example figure" widths={[480,768,1080]} formats={["avif","webp","png"]} sizes="(max-width: 768px) 100vw, var(--page-width)" />
71
+ <figcaption>Caption for your figure</figcaption>
72
+ </figure>
73
+
74
+ <h3>Tables</h3>
75
+ <table>
76
+ <thead>
77
+ <tr><th><strong>Model</strong></th><th><strong>Accuracy</strong></th><th><strong>Speed</strong></th></tr>
78
+ </thead>
79
+ <tbody>
80
+ <tr><td>Model A</td><td>95%</td><td>Fast</td></tr>
81
+ <tr><td>Model B</td><td>98%</td><td>Medium</td></tr>
82
+ <tr><td>Model C</td><td>99%</td><td>Slow</td></tr>
83
+ </tbody>
84
+ </table>
85
+
86
+ <h2>Interactive Components</h2>
87
+ <div class="plot-card">
88
+ <div id="fragment-line"></div>
89
+ </div>
90
+ <script>
91
+ // Example: simple Plotly line chart using the CDN
92
+ const container = document.getElementById('fragment-line');
93
+ if (container && window.Plotly) {
94
+ window.Plotly.newPlot(container, [{x:[1,2,3,4], y:[1,3,2,4], type:'scatter'}], {margin:{t:16,r:16,b:32,l:32}});
95
+ }
96
+ </script>
97
+
98
+ </d-article>
99
+
100
+ <d-appendix>
101
+ <h3 id="citation">Citation</h3>
102
+ <pre class="citation short">"The Distill Blog Template", 2025.</pre>
103
+ </d-appendix>
104
+
105
+ <script>
106
+ function toggleTOC() {
107
+ const content = document.querySelector('.toc-content');
108
+ const icon = document.querySelector('.toggle-icon');
109
+ if (content) content.classList.toggle('collapsed');
110
+ if (icon) icon.classList.toggle('collapsed');
111
+ }
112
+ </script>
113
+
114
+ <script>
115
+ const article = document.querySelector('d-article');
116
+ const toc = document.querySelector('d-contents');
117
+ if (toc && article) {
118
+ const headings = article.querySelectorAll('h2, h3, h4');
119
+ let ToC = `<nav role="navigation" class="l-text figcaption"><div class="toc-header" onclick="toggleTOC()"><span class="toc-title">Table of Contents</span><span class="toggle-icon">▼</span></div><div class="toc-content">`;
120
+ let prevLevel = 0;
121
+ for (const el of headings) {
122
+ const isInTitle = el.parentElement.tagName == 'D-TITLE';
123
+ const isException = el.getAttribute('no-toc');
124
+ if (isInTitle || isException) continue;
125
+ el.setAttribute('id', el.textContent.toLowerCase().replaceAll(" ", "_"));
126
+ const link = '<a target="_self" href="#' + el.getAttribute('id') + '">' + el.textContent + '</a>';
127
+ const level = el.tagName === 'H2' ? 0 : (el.tagName === 'H3' ? 1 : 2);
128
+ while (prevLevel < level) { ToC += '<ul>'; prevLevel++; }
129
+ while (prevLevel > level) { ToC += '</ul>'; prevLevel--; }
130
+ if (level === 0) ToC += '<div>' + link + '</div>'; else ToC += '<li>' + link + '</li>';
131
+ }
132
+ while (prevLevel > 0) { ToC += '</ul>'; prevLevel--; }
133
+ ToC += '</div></nav>';
134
+ toc.innerHTML = ToC;
135
+ toc.setAttribute('prerendered', 'true');
136
+ const toc_links = document.querySelectorAll('d-contents > nav div a');
137
+ window.addEventListener('scroll', () => {
138
+ if (!headings || !toc_links) return;
139
+ for (let i = headings.length - 1; i >= 0; i--) {
140
+ const heading = headings[i];
141
+ if (heading.parentElement.tagName == 'D-TITLE' || heading.getAttribute('no-toc')) continue;
142
+ if (heading.getBoundingClientRect().top - 50 <= 0) {
143
+ const headingId = heading.getAttribute('id');
144
+ const activeLink = Array.from(toc_links).find(link => link.getAttribute('href') === '#' + headingId);
145
+ if (activeLink && !activeLink.classList.contains('active')) {
146
+ toc_links.forEach(link => link.classList.remove('active'));
147
+ activeLink.classList.add('active');
148
+ }
149
+ break;
150
+ }
151
+ }
152
+ });
153
+ }
154
+ </script>
155
  </main>
156
  </body>
157
  </html>