Skip to content

Commit

Permalink
Merge pull request #842 from tidalcycles/slashocalypse
Browse files Browse the repository at this point in the history
improve slashing + base href behavior
  • Loading branch information
felixroos committed Dec 6, 2023
2 parents 8a0cf14 + 2ddd2d1 commit d9f78e1
Show file tree
Hide file tree
Showing 12 changed files with 64 additions and 36 deletions.
32 changes: 21 additions & 11 deletions website/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,34 @@ import AstroPWA from '@vite-pwa/astro';

const site = `https://strudel.cc/`; // root url without a path
const base = '/'; // base path of the strudel site
const baseNoTrailing = base.endsWith('/') ? base.slice(0, -1) : base;

// this rehype plugin converts relative anchor links to absolute ones
// it wokrs by prepending the absolute page path to anchor links
// example: #gain -> /learn/effects/#gain
// this rehype plugin fixes relative links
// it works by prepending the base + page path to anchor links
// and by prepending the base path to other relative links starting with /
// this is necessary when using a base href like <base href={base} />
// in this setup, relative anchor links will always link to base, instead of the current page
function absoluteAnchors() {
// examples with base as "mybase":
// #gain -> /mybase/learn/effects/#gain
// /some/page -> /mybase/some/page
function relativeURLFix() {
return (tree, file) => {
const chunks = file.history[0].split('/src/pages/'); // file.history[0] is the file path
const path = chunks[chunks.length - 1].slice(0, -4); // only path inside src/pages, without .mdx
return rehypeUrls((url) => {
if (!url.href.startsWith('#')) {
let newHref = baseNoTrailing;
if (url.href.startsWith('#')) {
// special case: a relative anchor link to the current page
newHref += `/${path}/${url.href}`;
} else if (url.href.startsWith('/')) {
// any other relative url starting with /
// NOTE: this does strip off serialized queries and fragments
newHref += url.pathname.endsWith('/') ? url.pathname : url.pathname + '/';
} else {
// leave this URL alone
return;
}
const baseWithSlash = base.endsWith('/') ? base : base + '/';
const absoluteUrl = baseWithSlash + path + url.href;
// console.log(url.href + ' -> ', absoluteUrl);
return absoluteUrl;
// console.log(url.href + ' -> ', newHref);
return newHref;
})(tree);
};
}
Expand All @@ -40,7 +50,7 @@ const options = {
remarkToc,
// E.g. `remark-frontmatter`
],
rehypePlugins: [rehypeSlug, [rehypeAutolinkHeadings, { behavior: 'append' }], absoluteAnchors],
rehypePlugins: [rehypeSlug, [rehypeAutolinkHeadings, { behavior: 'append' }], relativeURLFix],
};

// https://astro.build/config
Expand Down
12 changes: 6 additions & 6 deletions website/src/components/HeadCommon.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,28 @@ import { pwaInfo } from 'virtual:pwa-info';
import '../styles/index.css';
const { BASE_URL } = import.meta.env;
const base = BASE_URL;
const baseNoTrailing = BASE_URL.endsWith('/') ? BASE_URL.slice(0, -1) : BASE_URL;
---

<!-- Global Metadata -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />

<link rel="icon" type="image/svg+xml" href="favicon.ico" />
<link rel="icon" type="image/svg+xml" href={`${baseNoTrailing}/favicon.ico`} />

<meta
name="description"
content="Strudel is a music live coding environment for the browser, porting the TidalCycles pattern language to JavaScript."
/>
<link rel="icon" href="/favicon.ico" />
<link rel="apple-touch-icon" href="/icons/apple-icon-180.png" sizes="180x180" />
<link rel="icon" href={`${baseNoTrailing}/favicon.ico`} />
<link rel="apple-touch-icon" href={`${baseNoTrailing}/icons/apple-icon-180.png`} sizes="180x180" />
<meta name="theme-color" content="#222222" />

<base href={base} />
<base href={BASE_URL} />

<!-- Scrollable a11y code helper -->
<script src="./make-scrollable-code-focusable.js" is:inline></script>
<script src{`${baseNoTrailing}/make-scrollable-code-focusable.js`} is:inline></script>

<script src="/src/pwa.ts"></script>
<!-- this does not work for some reason: -->
Expand Down
7 changes: 5 additions & 2 deletions website/src/components/Header/Header.astro
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,17 @@ const { currentPage } = Astro.props as Props;
// const lang = getLanguageFromURL(currentPage);
const langCode = 'en'; // getLanguageFromURL(currentPage);
const sidebar = SIDEBAR[langCode];
const { BASE_URL } = import.meta.env;
const baseNoTrailing = BASE_URL.endsWith('/') ? BASE_URL.slice(0, -1) : BASE_URL;
---

<nav
class="flex justify-between py-2 px-4 items-center h-14 max-h-14 bg-lineHighlight text-foreground"
title="Top Navigation"
>
<div class="flex overflow-visible items-center grow" style="overflow:visible">
<a href="/" class="flex items-center text-2xl space-x-2">
<a href={`${baseNoTrailing}/`} class="flex items-center text-2xl space-x-2">
<h1 class="font-bold flex space-x-2 items-baseline text-xl">
<span>🌀</span>
<div class="flex space-x-1 items-baseline">
Expand All @@ -37,7 +40,7 @@ const sidebar = SIDEBAR[langCode];
<div class="search-item h-10">
<Search client:idle />
</div>
<a href="./" class="hidden md:flex cursor-pointer items-center space-x-1"
<a href={`${baseNoTrailing}/`} class="hidden md:flex cursor-pointer items-center space-x-1"
><CommandLineIcon className="w-5 h-5" /><span>go to REPL</span>
</a>
<div class="md:hidden">
Expand Down
8 changes: 7 additions & 1 deletion website/src/components/Header/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import './Search.css';

import { createPortal } from 'react-dom';
import * as docSearchReact from '@docsearch/react';
const { BASE_URL } = import.meta.env;
const baseNoTrailing = BASE_URL.endsWith('/') ? BASE_URL.slice(0, -1) : BASE_URL;

/** FIXME: This is still kinda nasty, but DocSearch is not ESM ready. */
const DocSearchModal = docSearchReact.DocSearchModal || (docSearchReact as any).default.DocSearchModal;
Expand Down Expand Up @@ -89,9 +91,13 @@ export default function Search() {
const a = document.createElement('a');
a.href = item.url;
const hash = a.hash === '#overview' ? '' : a.hash;
let pathname = a.pathname;
pathname = pathname.startsWith('/') ? pathname.slice(1) : pathname;
pathname = pathname.endsWith('/') ? pathname.slice(0, -1) : pathname;
const url = `${baseNoTrailing}/${pathname}/${hash}`;
return {
...item,
url: `${a.pathname}${hash}`,
url,
};
});
}}
Expand Down
3 changes: 2 additions & 1 deletion website/src/components/LeftSidebar/LeftSidebar.astro
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type Props = {
const { currentPage } = Astro.props as Props;
const { BASE_URL } = import.meta.env;
let currentPageMatch = currentPage.slice(BASE_URL.length, currentPage.endsWith('/') ? -1 : undefined);
const baseNoTrailing = BASE_URL.endsWith('/') ? BASE_URL.slice(0, -1) : BASE_URL;
const langCode = getLanguageFromURL(currentPage) || 'en';
const sidebar = SIDEBAR[langCode];
Expand All @@ -23,7 +24,7 @@ const sidebar = SIDEBAR[langCode];
<h2>{header}</h2>
<ul>
{children.map((child) => {
const url = Astro.site?.pathname + child.link;
const url = `${baseNoTrailing}/${child.link}${child.link.endsWith('/') ? '' : '/'}`;
return (
<li class="">
<a
Expand Down
2 changes: 1 addition & 1 deletion website/src/components/RightSidebar/TableOfContents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ const TableOfContents: FC<{ headings: MarkdownHeading[]; currentPage: string }>
.map((heading, i) => (
<li className={`w-full`} key={i}>
<a
href={`${currentPage}#${heading.slug}`}
href={`${currentPage}/#${heading.slug}`}
onClick={onLinkClick}
className={`py-0.5 block cursor-pointer w-full border-l-4 border-lineHighlight hover:bg-lineHighlight ${
['pl-4', 'pl-9', 'pl-12'][heading.depth - minDepth]
Expand Down
7 changes: 2 additions & 5 deletions website/src/pages/img/example-[name].png.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { evaluate } from '@strudel.cycles/transpiler';
import '../../../../test/runtime.mjs';
import * as tunes from '../../repl/tunes.mjs';

export async function get({ params, request }) {
export async function GET({ params, request }) {
const { name } = params;
const tune = tunes[name];
const { pattern } = await evaluate(tune);
Expand All @@ -13,10 +13,7 @@ export async function get({ params, request }) {
const ctx = canvas.getContext('2d');
pianoroll({ time: 4, haps, ctx, playhead: 1, fold: 1, background: 'transparent', playheadColor: 'transparent' });
const buffer = canvas.toBuffer('image/png');
return {
body: buffer,
encoding: 'binary',
};
return new Response(buffer);
}
export function getStaticPaths() {
return Object.keys(tunes).map((name) => ({
Expand Down
7 changes: 5 additions & 2 deletions website/src/pages/swatch/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import { Content } from '../../../../my-patterns/README.md';
import HeadCommon from '../../components/HeadCommon.astro';
const myPatterns = await getMyPatterns();
const { BASE_URL } = import.meta.env;
const baseNoTrailing = BASE_URL.endsWith('/') ? BASE_URL.slice(0, -1) : BASE_URL;
---

<head>
Expand All @@ -23,12 +26,12 @@ const myPatterns = await getMyPatterns();
Object.entries(myPatterns).map(([name, tune]) => (
<a
class="rounded-md bg-slate-900 hover:bg-slate-700 cursor-pointer relative"
href={`./#${btoa(tune as string)}`}
href={`${baseNoTrailing}/#${btoa(tune as string)}`}
>
<div class="absolute w-full h-full flex justify-center items-center">
<span class="bg-slate-800 p-2 rounded-md text-white">{name}</span>
</div>
<img src={`./swatch/${name}.png`} />
<img src={`${baseNoTrailing}/swatch/${name}.png/`} />
</a>
))
}
Expand Down
2 changes: 1 addition & 1 deletion website/src/pages/workshop/getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { MiniRepl } from '../../docs/MiniRepl';

# Welcome

<img src="/icons/strudel_icon.png" className="w-32 animate-pulse md:float-right ml-8" />
<div className="w-32 animate-pulse md:float-right ml-8">![Strudel Icon](/icons/strudel_icon.png)</div>

Welcome to the Strudel documentation pages!
You've come to the right place if you want to learn how to make music with code.
Expand Down
5 changes: 4 additions & 1 deletion website/src/repl/Footer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ import { FilesTab } from './FilesTab';

const TAURI = window.__TAURI__;

const { BASE_URL } = import.meta.env;
const baseNoTrailing = BASE_URL.endsWith('/') ? BASE_URL.slice(0, -1) : BASE_URL;

export function Footer({ context }) {
const footerContent = useRef();
const [log, setLog] = useState([]);
Expand Down Expand Up @@ -154,7 +157,7 @@ function WelcomeTab() {
</p>
<p>
To learn more about what this all means, check out the{' '}
<a href="./workshop/getting-started" target="_blank">
<a href={`${baseNoTrailing}/workshop/getting-started/`} target="_blank">
interactive tutorial
</a>
. Also feel free to join the{' '}
Expand Down
4 changes: 3 additions & 1 deletion website/src/repl/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import React, { useContext } from 'react';
import { useSettings, setIsZen } from '../settings.mjs';
// import { ReplContext } from './Repl';
import './Repl.css';
const { BASE_URL } = import.meta.env;
const baseNoTrailing = BASE_URL.endsWith('/') ? BASE_URL.slice(0, -1) : BASE_URL;

export function Header({ context }) {
const {
Expand Down Expand Up @@ -123,7 +125,7 @@ export function Header({ context }) {
{!isEmbedded && (
<a
title="learn"
href="./workshop/getting-started"
href={`${baseNoTrailing}/workshop/getting-started/`}
className={cx('hover:opacity-50 flex items-center space-x-1', !isEmbedded ? 'p-2' : 'px-2')}
>
<AcademicCapIcon className="w-6 h-6" />
Expand Down
11 changes: 7 additions & 4 deletions website/src/repl/prebake.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { registerSynthSounds, registerZZFXSounds, samples } from '@strudel.cycle
import './piano.mjs';
import './files.mjs';

const { BASE_URL } = import.meta.env;
const baseNoTrailing = BASE_URL.endsWith('/') ? BASE_URL.slice(0, -1) : BASE_URL;

export async function prebake() {
// https://archive.org/details/SalamanderGrandPianoV3
// License: CC-by http://creativecommons.org/licenses/by/3.0/ Author: Alexander Holm
Expand All @@ -14,16 +17,16 @@ export async function prebake() {
// => getting "window is not defined", as soon as "@strudel.cycles/soundfonts" is imported statically
// seems to be a problem with soundfont2
import('@strudel.cycles/soundfonts').then(({ registerSoundfonts }) => registerSoundfonts()),
samples(`./piano.json`, `./piano/`, { prebake: true }),
samples(`${baseNoTrailing}/piano.json`, `./piano/`, { prebake: true }),
// https://github.com/sgossner/VCSL/
// https://api.github.com/repositories/126427031/contents/
// LICENSE: CC0 general-purpose
samples(`./vcsl.json`, 'github:sgossner/VCSL/master/', { prebake: true }),
samples(`./tidal-drum-machines.json`, 'github:ritchse/tidal-drum-machines/main/machines/', {
samples(`${baseNoTrailing}/vcsl.json`, 'github:sgossner/VCSL/master/', { prebake: true }),
samples(`${baseNoTrailing}/tidal-drum-machines.json`, 'github:ritchse/tidal-drum-machines/main/machines/', {
prebake: true,
tag: 'drum-machines',
}),
samples(`./EmuSP12.json`, `./EmuSP12/`, { prebake: true, tag: 'drum-machines' }),
samples(`${baseNoTrailing}/EmuSP12.json`, `${baseNoTrailing}/EmuSP12/`, { prebake: true, tag: 'drum-machines' }),
samples(
{
casio: ['casio/high.wav', 'casio/low.wav', 'casio/noise.wav'],
Expand Down

0 comments on commit d9f78e1

Please sign in to comment.