Skip to the content

Capsid menu

app/lib/publications/paths.mjs

56 lines and 6 functions in DrDustinEdwards/dustinedwards-info, at commit 1590ba4 on 2026-10-24. This file on GitHub.

Functions

The functions of paths.mjs
FunctionLinesComplexityCoveredCRAPMutation
doiSlug14 to 202100%OkCRAP 2No data: no mutants in this code
paperPath30 to 321100%OkCRAP 1No data: no mutants in this code
paperPdfPath39 to 411100%OkCRAP 1No data: no mutants in this code
paperMarkdownPath46 to 481100%OkCRAP 1No data: no mutants in this code
paperAskUrl56 to 581100%OkCRAP 1No data: no mutants in this code
paperPdfDiskPath63 to 65133%OkCRAP 1.3No data: no mutants in this code

Imports

It imports app/lib/media/classify.mjs. Imported by app/lib/cache-purge.server.ts, app/lib/carrel/publication-handler.server.ts, app/lib/cv/entries.mjs, app/lib/llms/save.server.ts, app/lib/nav.ts, app/lib/publications/compile.mjs, app/lib/publications/export-response.mjs, app/lib/publications/record.mjs, app/lib/publications/search-inputs.mjs, app/lib/publications/validate.mjs, app/lib/search/ask.server.ts, app/lib/seo.ts, app/lib/site-urls.server.ts, app/routes/publications.$slug.tsx, app/routes/publications.$slug[.md].ts, app/routes/publications.tsx.

Source

// The trailing slash is load-bearing: Scholar requires citation_pdf_url in the same subdirectory as the
// abstract page, which only /research/publications/<slug>/ satisfies. The slug derives from the DOI, never the
// curated id, so it cannot be re-decided after Scholar has indexed it.

import { ASSET_PREFIX } from "../media/classify.mjs";

/**
 * Casefolded: DOIs are case-insensitive and some are deposited mixed case. The collapse is lossy, so
 * check:machine-readable asserts uniqueness.
 *
 * @param {string} doi as deposited
 * @returns {string}
 */
export function doiSlug(doi) {
  return String(doi ?? "")
    .trim()
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/^-+|-+$/g, "");
}

export const PUBLICATIONS_PATH = "/research/publications";

/** Every publication response carries it (the index, the pages, the exports, the twins); a save purges it. */
export const PUBLICATIONS_CACHE_TAG = "publications";

/**
 * @param {string} slug from `doiSlug`
 */
export function paperPath(slug) {
  return `${PUBLICATIONS_PATH}/${slug}/`;
}

/**
 * Named for the slug, not the curated filename, so one string decides both the directory and the file.
 *
 * @param {string} slug from `doiSlug`
 */
export function paperPdfPath(slug) {
  return `${PUBLICATIONS_PATH}/${slug}/${ASSET_PREFIX}${slug}.pdf`;
}

/**
 * @param {string} slug from `doiSlug`
 */
export function paperMarkdownPath(slug) {
  return `${PUBLICATIONS_PATH}/${slug}.md`;
}

/**
 * A link to /search, so it works without script. Only the quoted title: the classic index ANDs its terms,
 * so extra words return nothing. check:machine-readable asserts no title contains a quotation mark.
 *
 * @param {string} title DECODED, the way a reader sees it
 */
export function paperAskUrl(title) {
  return `/search?q=${encodeURIComponent(`"${title}"`)}`;
}

/**
 * @param {string} slug from `doiSlug`
 */
export function paperPdfDiskPath(slug) {
  return `public/research/publications/${slug}/${ASSET_PREFIX}${slug}.pdf`;
}