@thomasfosterau/components 0.0.0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +2 -2
- package/dist/canvas/VectorCanvas.svelte +239 -0
- package/dist/canvas/VectorCanvas.svelte.d.ts +87 -0
- package/dist/canvas/history.d.ts +105 -0
- package/dist/canvas/history.js +147 -0
- package/dist/canvas/index.d.ts +15 -0
- package/dist/canvas/index.js +14 -0
- package/dist/canvas/types.d.ts +91 -0
- package/dist/canvas/types.js +13 -0
- package/dist/canvas/utils.d.ts +66 -0
- package/dist/canvas/utils.js +114 -0
- package/dist/charts/Chart.svelte +300 -0
- package/dist/charts/Chart.svelte.d.ts +50 -0
- package/dist/charts/index.d.ts +11 -0
- package/dist/charts/index.js +10 -0
- package/dist/charts/types.d.ts +28 -0
- package/dist/charts/types.js +6 -0
- package/dist/citations/BookCitation.svelte +53 -0
- package/dist/citations/BookCitation.svelte.d.ts +41 -0
- package/dist/citations/ChapterCitation.svelte +38 -0
- package/dist/citations/ChapterCitation.svelte.d.ts +50 -0
- package/dist/citations/Citation.svelte +47 -0
- package/dist/citations/Citation.svelte.d.ts +24 -0
- package/dist/citations/CreditList.svelte +69 -0
- package/dist/citations/CreditList.svelte.d.ts +47 -0
- package/dist/citations/DOILink.svelte +28 -0
- package/dist/citations/DOILink.svelte.d.ts +19 -0
- package/dist/citations/Footnote.svelte +39 -0
- package/dist/citations/Footnote.svelte.d.ts +17 -0
- package/dist/citations/FootnoteList.svelte +36 -0
- package/dist/citations/FootnoteList.svelte.d.ts +21 -0
- package/dist/citations/ISBNLink.svelte +29 -0
- package/dist/citations/ISBNLink.svelte.d.ts +19 -0
- package/dist/citations/ISSNLink.svelte +29 -0
- package/dist/citations/ISSNLink.svelte.d.ts +19 -0
- package/dist/citations/Publisher.svelte +34 -0
- package/dist/citations/Publisher.svelte.d.ts +14 -0
- package/dist/citations/ReferenceList.svelte +53 -0
- package/dist/citations/ReferenceList.svelte.d.ts +21 -0
- package/dist/citations/ReportCitation.svelte +41 -0
- package/dist/citations/ReportCitation.svelte.d.ts +36 -0
- package/dist/citations/ScholarlyArticleCitation.svelte +64 -0
- package/dist/citations/ScholarlyArticleCitation.svelte.d.ts +41 -0
- package/dist/citations/ThesisCitation.svelte +35 -0
- package/dist/citations/ThesisCitation.svelte.d.ts +29 -0
- package/dist/citations/bibliography.svelte.d.ts +55 -0
- package/dist/citations/bibliography.svelte.js +78 -0
- package/dist/citations/citation.d.ts +71 -0
- package/dist/citations/citation.js +121 -0
- package/dist/citations/csl.d.ts +102 -0
- package/dist/citations/csl.js +20 -0
- package/dist/citations/index.d.ts +31 -0
- package/dist/citations/index.js +36 -0
- package/dist/citations/list-format.d.ts +34 -0
- package/dist/citations/list-format.js +38 -0
- package/dist/context.svelte.d.ts +46 -0
- package/dist/context.svelte.js +51 -0
- package/dist/data/DataGrid.svelte +150 -0
- package/dist/data/DataGrid.svelte.d.ts +118 -0
- package/dist/data/DescriptionList.svelte +47 -0
- package/dist/data/DescriptionList.svelte.d.ts +26 -0
- package/dist/data/DescriptionRow.svelte +55 -0
- package/dist/data/DescriptionRow.svelte.d.ts +21 -0
- package/dist/data/DiffText.svelte +29 -0
- package/dist/data/DiffText.svelte.d.ts +19 -0
- package/dist/data/ItemList.svelte +80 -0
- package/dist/data/ItemList.svelte.d.ts +52 -0
- package/dist/data/LinkListItem.svelte +46 -0
- package/dist/data/LinkListItem.svelte.d.ts +21 -0
- package/dist/data/Pagination.svelte +136 -0
- package/dist/data/Pagination.svelte.d.ts +71 -0
- package/dist/data/PaginationFooter.svelte +41 -0
- package/dist/data/PaginationFooter.svelte.d.ts +59 -0
- package/dist/data/ResultCount.svelte +27 -0
- package/dist/data/ResultCount.svelte.d.ts +18 -0
- package/dist/data/Table.svelte +145 -0
- package/dist/data/Table.svelte.d.ts +75 -0
- package/dist/data/TreeList.svelte +41 -0
- package/dist/data/TreeList.svelte.d.ts +17 -0
- package/dist/data/TreeListItem.svelte +29 -0
- package/dist/data/TreeListItem.svelte.d.ts +10 -0
- package/dist/data/description-context.d.ts +33 -0
- package/dist/data/description-context.js +35 -0
- package/dist/data/diff.d.ts +14 -0
- package/dist/data/diff.js +10 -0
- package/dist/data/index.d.ts +35 -0
- package/dist/data/index.js +35 -0
- package/dist/data/list-item.d.ts +30 -0
- package/dist/data/list-item.js +19 -0
- package/dist/data/pagination.d.ts +81 -0
- package/dist/data/pagination.js +79 -0
- package/dist/data/table-types.d.ts +64 -0
- package/dist/data/table-types.js +35 -0
- package/dist/feedback/ConfirmDialog.svelte +79 -0
- package/dist/feedback/ConfirmDialog.svelte.d.ts +82 -0
- package/dist/feedback/Dialog.svelte +77 -0
- package/dist/feedback/Dialog.svelte.d.ts +37 -0
- package/dist/feedback/LoadingBoundary.svelte +61 -0
- package/dist/feedback/LoadingBoundary.svelte.d.ts +34 -0
- package/dist/feedback/ProgressBar.svelte +46 -0
- package/dist/feedback/ProgressBar.svelte.d.ts +28 -0
- package/dist/feedback/SegmentBar.svelte +83 -0
- package/dist/feedback/SegmentBar.svelte.d.ts +36 -0
- package/dist/feedback/StatTile.svelte +77 -0
- package/dist/feedback/StatTile.svelte.d.ts +49 -0
- package/dist/feedback/Stats.svelte +18 -0
- package/dist/feedback/Stats.svelte.d.ts +16 -0
- package/dist/feedback/Timeline.svelte +86 -0
- package/dist/feedback/Timeline.svelte.d.ts +52 -0
- package/dist/feedback/Toaster.svelte +78 -0
- package/dist/feedback/Toaster.svelte.d.ts +32 -0
- package/dist/feedback/index.d.ts +31 -0
- package/dist/feedback/index.js +27 -0
- package/dist/feedback/sizes.d.ts +27 -0
- package/dist/feedback/sizes.js +41 -0
- package/dist/feedback/toaster.d.ts +48 -0
- package/dist/feedback/toaster.js +29 -0
- package/dist/fields/Checkbox.svelte +33 -0
- package/dist/fields/Checkbox.svelte.d.ts +24 -0
- package/dist/fields/CheckboxGroup.svelte +41 -0
- package/dist/fields/CheckboxGroup.svelte.d.ts +40 -0
- package/dist/fields/Combobox.svelte +222 -0
- package/dist/fields/Combobox.svelte.d.ts +98 -0
- package/dist/fields/DateInput.svelte +31 -0
- package/dist/fields/DateInput.svelte.d.ts +29 -0
- package/dist/fields/FieldErrors.svelte +30 -0
- package/dist/fields/FieldErrors.svelte.d.ts +11 -0
- package/dist/fields/Fieldset.svelte +48 -0
- package/dist/fields/Fieldset.svelte.d.ts +26 -0
- package/dist/fields/FileInput.svelte +67 -0
- package/dist/fields/FileInput.svelte.d.ts +33 -0
- package/dist/fields/FormField.svelte +54 -0
- package/dist/fields/FormField.svelte.d.ts +29 -0
- package/dist/fields/ImageInput.svelte +87 -0
- package/dist/fields/ImageInput.svelte.d.ts +39 -0
- package/dist/fields/PushToggle.svelte +93 -0
- package/dist/fields/PushToggle.svelte.d.ts +55 -0
- package/dist/fields/RadioGroup.svelte +85 -0
- package/dist/fields/RadioGroup.svelte.d.ts +41 -0
- package/dist/fields/SearchInput.svelte +57 -0
- package/dist/fields/SearchInput.svelte.d.ts +33 -0
- package/dist/fields/Select.svelte +36 -0
- package/dist/fields/Select.svelte.d.ts +29 -0
- package/dist/fields/TextInput.svelte +26 -0
- package/dist/fields/TextInput.svelte.d.ts +30 -0
- package/dist/fields/Textarea.svelte +22 -0
- package/dist/fields/Textarea.svelte.d.ts +25 -0
- package/dist/fields/Toggle.svelte +72 -0
- package/dist/fields/Toggle.svelte.d.ts +32 -0
- package/dist/fields/VideoInput.svelte +35 -0
- package/dist/fields/VideoInput.svelte.d.ts +40 -0
- package/dist/fields/field-types.d.ts +51 -0
- package/dist/fields/field-types.js +60 -0
- package/dist/fields/index.d.ts +34 -0
- package/dist/fields/index.js +34 -0
- package/dist/formatting/DateTime.svelte +35 -0
- package/dist/formatting/DateTime.svelte.d.ts +26 -0
- package/dist/formatting/FormatList.svelte +31 -0
- package/dist/formatting/FormatList.svelte.d.ts +46 -0
- package/dist/formatting/Highlight.svelte +47 -0
- package/dist/formatting/Highlight.svelte.d.ts +15 -0
- package/dist/formatting/Number.svelte +35 -0
- package/dist/formatting/Number.svelte.d.ts +43 -0
- package/dist/formatting/RelativeTime.svelte +69 -0
- package/dist/formatting/RelativeTime.svelte.d.ts +26 -0
- package/dist/formatting/Year.svelte +39 -0
- package/dist/formatting/Year.svelte.d.ts +21 -0
- package/dist/formatting/index.d.ts +12 -0
- package/dist/formatting/index.js +14 -0
- package/dist/forms/EntityForm.svelte +177 -0
- package/dist/forms/EntityForm.svelte.d.ts +57 -0
- package/dist/forms/FormActions.svelte +29 -0
- package/dist/forms/FormActions.svelte.d.ts +37 -0
- package/dist/forms/FormErrors.svelte +21 -0
- package/dist/forms/FormErrors.svelte.d.ts +16 -0
- package/dist/forms/HiddenField.svelte +22 -0
- package/dist/forms/HiddenField.svelte.d.ts +11 -0
- package/dist/forms/SearchForm.svelte +43 -0
- package/dist/forms/SearchForm.svelte.d.ts +36 -0
- package/dist/forms/entity-form.d.ts +12 -0
- package/dist/forms/entity-form.js +12 -0
- package/dist/forms/index.d.ts +14 -0
- package/dist/forms/index.js +14 -0
- package/dist/hotkeys/HotkeyBadge.svelte +39 -0
- package/dist/hotkeys/HotkeyBadge.svelte.d.ts +25 -0
- package/dist/hotkeys/HotkeyHelpDialog.svelte +68 -0
- package/dist/hotkeys/HotkeyHelpDialog.svelte.d.ts +35 -0
- package/dist/hotkeys/HotkeyProvider.svelte +92 -0
- package/dist/hotkeys/HotkeyProvider.svelte.d.ts +4 -0
- package/dist/hotkeys/context.svelte.d.ts +47 -0
- package/dist/hotkeys/context.svelte.js +72 -0
- package/dist/hotkeys/index.d.ts +23 -0
- package/dist/hotkeys/index.js +22 -0
- package/dist/hotkeys/match.d.ts +65 -0
- package/dist/hotkeys/match.js +133 -0
- package/dist/hotkeys/registry.svelte.d.ts +55 -0
- package/dist/hotkeys/registry.svelte.js +110 -0
- package/dist/hotkeys/types.d.ts +72 -0
- package/dist/hotkeys/types.js +18 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.js +36 -0
- package/dist/infobox/Infobox.svelte +79 -0
- package/dist/infobox/Infobox.svelte.d.ts +26 -0
- package/dist/infobox/InfoboxHeader.svelte +27 -0
- package/dist/infobox/InfoboxHeader.svelte.d.ts +11 -0
- package/dist/infobox/InfoboxImage.svelte +38 -0
- package/dist/infobox/InfoboxImage.svelte.d.ts +21 -0
- package/dist/infobox/InfoboxRow.svelte +50 -0
- package/dist/infobox/InfoboxRow.svelte.d.ts +25 -0
- package/dist/infobox/InfoboxSection.svelte +24 -0
- package/dist/infobox/InfoboxSection.svelte.d.ts +12 -0
- package/dist/infobox/index.d.ts +21 -0
- package/dist/infobox/index.js +20 -0
- package/dist/infobox/types.d.ts +86 -0
- package/dist/infobox/types.js +27 -0
- package/dist/layout/Breadcrumbs.svelte +52 -0
- package/dist/layout/Breadcrumbs.svelte.d.ts +18 -0
- package/dist/layout/DetailLayout.svelte +50 -0
- package/dist/layout/DetailLayout.svelte.d.ts +19 -0
- package/dist/layout/FilterBar.svelte +40 -0
- package/dist/layout/FilterBar.svelte.d.ts +12 -0
- package/dist/layout/Footer.svelte +32 -0
- package/dist/layout/Footer.svelte.d.ts +12 -0
- package/dist/layout/Main.svelte +30 -0
- package/dist/layout/Main.svelte.d.ts +15 -0
- package/dist/layout/Navbar.svelte +68 -0
- package/dist/layout/Navbar.svelte.d.ts +31 -0
- package/dist/layout/PageHeader.svelte +77 -0
- package/dist/layout/PageHeader.svelte.d.ts +33 -0
- package/dist/layout/Section.svelte +72 -0
- package/dist/layout/Section.svelte.d.ts +40 -0
- package/dist/layout/Sidebar.svelte +54 -0
- package/dist/layout/Sidebar.svelte.d.ts +27 -0
- package/dist/layout/Tabs.svelte +85 -0
- package/dist/layout/Tabs.svelte.d.ts +42 -0
- package/dist/layout/index.d.ts +29 -0
- package/dist/layout/index.js +29 -0
- package/dist/layout/types.d.ts +52 -0
- package/dist/layout/types.js +27 -0
- package/dist/links/ContextLinks.svelte +28 -0
- package/dist/links/ContextLinks.svelte.d.ts +20 -0
- package/dist/links/EmailLink.svelte +26 -0
- package/dist/links/EmailLink.svelte.d.ts +20 -0
- package/dist/links/index.d.ts +7 -0
- package/dist/links/index.js +7 -0
- package/dist/media/Figure.svelte +26 -0
- package/dist/media/Figure.svelte.d.ts +12 -0
- package/dist/media/Image.svelte +76 -0
- package/dist/media/Image.svelte.d.ts +41 -0
- package/dist/media/Video.svelte +65 -0
- package/dist/media/Video.svelte.d.ts +29 -0
- package/dist/media/image-dimensions.d.ts +28 -0
- package/dist/media/image-dimensions.js +34 -0
- package/dist/media/index.d.ts +10 -0
- package/dist/media/index.js +10 -0
- package/dist/search/CommandPalette.svelte +257 -0
- package/dist/search/CommandPalette.svelte.d.ts +59 -0
- package/dist/search/index.d.ts +13 -0
- package/dist/search/index.js +13 -0
- package/dist/search/types.d.ts +37 -0
- package/dist/search/types.js +20 -0
- package/dist/seo/Head.svelte +190 -0
- package/dist/seo/Head.svelte.d.ts +86 -0
- package/dist/seo/JsonLd.svelte +30 -0
- package/dist/seo/JsonLd.svelte.d.ts +20 -0
- package/dist/seo/index.d.ts +18 -0
- package/dist/seo/index.js +17 -0
- package/dist/seo/json-ld.d.ts +33 -0
- package/dist/seo/json-ld.js +29 -0
- package/dist/seo/og-image.d.ts +71 -0
- package/dist/seo/og-image.js +81 -0
- package/dist/seo/types.d.ts +43 -0
- package/dist/seo/types.js +6 -0
- package/dist/theme.css +161 -0
- package/dist/tips/PopoverTip.svelte +80 -0
- package/dist/tips/PopoverTip.svelte.d.ts +33 -0
- package/dist/tips/Tip.svelte +91 -0
- package/dist/tips/Tip.svelte.d.ts +25 -0
- package/dist/tips/index.d.ts +15 -0
- package/dist/tips/index.js +14 -0
- package/dist/tips/tip-stack.d.ts +25 -0
- package/dist/tips/tip-stack.js +37 -0
- package/dist/tips/tip-store.svelte.d.ts +74 -0
- package/dist/tips/tip-store.svelte.js +158 -0
- package/dist/tips/types.d.ts +46 -0
- package/dist/tips/types.js +6 -0
- package/dist/ui/Alert.svelte +61 -0
- package/dist/ui/Alert.svelte.d.ts +37 -0
- package/dist/ui/Badge.svelte +39 -0
- package/dist/ui/Badge.svelte.d.ts +32 -0
- package/dist/ui/Button.svelte +43 -0
- package/dist/ui/Button.svelte.d.ts +29 -0
- package/dist/ui/Card.svelte +49 -0
- package/dist/ui/Card.svelte.d.ts +44 -0
- package/dist/ui/Chip.svelte +58 -0
- package/dist/ui/Chip.svelte.d.ts +21 -0
- package/dist/ui/ConfirmButton.svelte +75 -0
- package/dist/ui/ConfirmButton.svelte.d.ts +48 -0
- package/dist/ui/Disclosure.svelte +39 -0
- package/dist/ui/Disclosure.svelte.d.ts +22 -0
- package/dist/ui/EmptyState.svelte +37 -0
- package/dist/ui/EmptyState.svelte.d.ts +22 -0
- package/dist/ui/ExternalLink.svelte +38 -0
- package/dist/ui/ExternalLink.svelte.d.ts +34 -0
- package/dist/ui/Heading.svelte +58 -0
- package/dist/ui/Heading.svelte.d.ts +22 -0
- package/dist/ui/Link.svelte +34 -0
- package/dist/ui/Link.svelte.d.ts +20 -0
- package/dist/ui/LinkButton.svelte +51 -0
- package/dist/ui/LinkButton.svelte.d.ts +33 -0
- package/dist/ui/Menu.svelte +54 -0
- package/dist/ui/Menu.svelte.d.ts +34 -0
- package/dist/ui/MenuItem.svelte +75 -0
- package/dist/ui/MenuItem.svelte.d.ts +21 -0
- package/dist/ui/MenuSeparator.svelte +26 -0
- package/dist/ui/MenuSeparator.svelte.d.ts +8 -0
- package/dist/ui/Popover.svelte +63 -0
- package/dist/ui/Popover.svelte.d.ts +40 -0
- package/dist/ui/ShareButton.svelte +64 -0
- package/dist/ui/ShareButton.svelte.d.ts +39 -0
- package/dist/ui/Skeleton.svelte +43 -0
- package/dist/ui/Skeleton.svelte.d.ts +22 -0
- package/dist/ui/ThemeToggle.svelte +65 -0
- package/dist/ui/ThemeToggle.svelte.d.ts +24 -0
- package/dist/ui/Tooltip.svelte +54 -0
- package/dist/ui/Tooltip.svelte.d.ts +35 -0
- package/dist/ui/VisuallyHidden.svelte +23 -0
- package/dist/ui/VisuallyHidden.svelte.d.ts +10 -0
- package/dist/ui/colour-token.d.ts +41 -0
- package/dist/ui/colour-token.js +49 -0
- package/dist/ui/index.d.ts +44 -0
- package/dist/ui/index.js +44 -0
- package/dist/ui/menu-context.d.ts +22 -0
- package/dist/ui/menu-context.js +26 -0
- package/dist/ui/slug.d.ts +19 -0
- package/dist/ui/slug.js +25 -0
- package/dist/ui/tones.d.ts +68 -0
- package/dist/ui/tones.js +150 -0
- package/package.json +25 -25
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAnchorAttributes } from 'svelte/elements';
|
|
3
|
+
interface Props extends Omit<HTMLAnchorAttributes, 'children'> {
|
|
4
|
+
/** The ISSN, without a prefix. */
|
|
5
|
+
issn: string;
|
|
6
|
+
/**
|
|
7
|
+
* Schema.org `itemprop` on the link, when the identifier is a property of an enclosing item.
|
|
8
|
+
*/
|
|
9
|
+
itemprop?: string | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* Replaces the link text.
|
|
12
|
+
* @defaultValue the bare ISSN
|
|
13
|
+
*/
|
|
14
|
+
children?: Snippet<[]> | undefined;
|
|
15
|
+
}
|
|
16
|
+
/** An ISSN rendered as a WorldCat lookup link that opens in a new tab. */
|
|
17
|
+
declare const ISSNLink: import("svelte").Component<Props, {}, "">;
|
|
18
|
+
type ISSNLink = ReturnType<typeof ISSNLink>;
|
|
19
|
+
export default ISSNLink;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
A publisher or awarding institution as Schema.org microdata: "Oxford, Oxfordshire, UK: Oxford University Press".
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
Publisher — a publisher (or awarding institution) as Schema.org microdata:
|
|
6
|
+
"Oxford, Oxfordshire, UK: Oxford University Press". The place is a
|
|
7
|
+
`PostalAddress` of whichever of locality / region / country are present,
|
|
8
|
+
and is omitted, colon included, when none are.
|
|
9
|
+
|
|
10
|
+
Microdata, not ARIA: the name is plain text; the structure is for machines.
|
|
11
|
+
`itemprop` defaults to `publisher` and is a prop so a thesis can credit its
|
|
12
|
+
awarding institution as `sourceOrganization`.
|
|
13
|
+
-->
|
|
14
|
+
<script lang="ts">let { publisher, itemprop = "publisher" } = $props();
|
|
15
|
+
const placeParts = $derived([
|
|
16
|
+
["addressLocality", publisher.address?.locality],
|
|
17
|
+
["addressRegion", publisher.address?.region],
|
|
18
|
+
["addressCountry", publisher.address?.country]
|
|
19
|
+
].flatMap(([prop, value]) => value === undefined || value === "" ? [] : [{
|
|
20
|
+
prop,
|
|
21
|
+
value
|
|
22
|
+
}]));
|
|
23
|
+
export {};
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<span {itemprop} itemscope itemtype={`https://schema.org/${publisher.itemtype ?? 'Organization'}`}>
|
|
27
|
+
{#if placeParts.length > 0}
|
|
28
|
+
<span itemprop="location" itemscope itemtype="https://schema.org/PostalAddress"
|
|
29
|
+
>{#each placeParts as { prop, value }, index (prop)}<span itemprop={prop}>{value}</span
|
|
30
|
+
>{#if index < placeParts.length - 1},{' '}{/if}{/each}</span
|
|
31
|
+
>:
|
|
32
|
+
{/if}
|
|
33
|
+
<span itemprop="name">{publisher.name}</span>
|
|
34
|
+
</span>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { PublisherRecord } from './csl.ts';
|
|
2
|
+
interface Props {
|
|
3
|
+
/** The publisher to render; its place is omitted when it has none. */
|
|
4
|
+
publisher: PublisherRecord;
|
|
5
|
+
/**
|
|
6
|
+
* Schema.org `itemprop` on the root.
|
|
7
|
+
* @defaultValue `'publisher'`
|
|
8
|
+
*/
|
|
9
|
+
itemprop?: string | undefined;
|
|
10
|
+
}
|
|
11
|
+
/** A publisher or awarding institution as Schema.org microdata: "Oxford, Oxfordshire, UK: Oxford University Press". */
|
|
12
|
+
declare const Publisher: import("svelte").Component<Props, {}, "">;
|
|
13
|
+
type Publisher = ReturnType<typeof Publisher>;
|
|
14
|
+
export default Publisher;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
The numbered bibliography a page’s `<Citation>` markers accumulated, in citation order.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
ReferenceList — the numbered bibliography a page's `<Citation>` markers
|
|
6
|
+
accumulated, rendered in citation order.
|
|
7
|
+
|
|
8
|
+
Formatting happens once, in a single `$derived` over the whole list, rather
|
|
9
|
+
than per-entry inside the template on every reactive change — and pulling
|
|
10
|
+
it into `formatCitation` (`./citation.ts`) is what makes the style testable
|
|
11
|
+
besides.
|
|
12
|
+
|
|
13
|
+
There is no "alphabetical" style: sorting a numbered style alphabetically
|
|
14
|
+
breaks the `[n]` markers already printed in the prose, so that would need to
|
|
15
|
+
be a different style entirely, not a display toggle on this one.
|
|
16
|
+
-->
|
|
17
|
+
<script lang="ts">import { getBibliographyContext } from "./bibliography.svelte.js";
|
|
18
|
+
import { formatCitation } from "./citation.js";
|
|
19
|
+
let { title = "References", showTitle = true, headingLevel = 2 } = $props();
|
|
20
|
+
const manager = getBibliographyContext();
|
|
21
|
+
// One pass over the whole list, recomputed only when the list changes.
|
|
22
|
+
const entries = $derived(manager.citations().map((entry) => ({
|
|
23
|
+
id: entry.citation.id,
|
|
24
|
+
order: entry.order,
|
|
25
|
+
text: formatCitation(entry.citation),
|
|
26
|
+
url: entry.citation.url
|
|
27
|
+
})));
|
|
28
|
+
const Heading = $derived(`h${headingLevel}`);
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
{#if entries.length > 0}
|
|
32
|
+
<section class="mt-8 space-y-3">
|
|
33
|
+
{#if showTitle}
|
|
34
|
+
<svelte:element this={Heading} class="text-xl font-semibold">{title}</svelte:element>
|
|
35
|
+
{/if}
|
|
36
|
+
|
|
37
|
+
<ol class="space-y-2 text-sm">
|
|
38
|
+
{#each entries as entry (entry.id)}
|
|
39
|
+
<li id="ref-{entry.id}" class="text-base-content/80 flex gap-2 leading-relaxed">
|
|
40
|
+
<span class="text-base-content/60 shrink-0 font-medium">[{entry.order}]</span>
|
|
41
|
+
<span>
|
|
42
|
+
{entry.text}
|
|
43
|
+
{#if entry.url}
|
|
44
|
+
<a class="link link-hover" href={entry.url} rel="noreferrer nofollow" target="_blank">
|
|
45
|
+
{entry.url}
|
|
46
|
+
</a>
|
|
47
|
+
{/if}
|
|
48
|
+
</span>
|
|
49
|
+
</li>
|
|
50
|
+
{/each}
|
|
51
|
+
</ol>
|
|
52
|
+
</section>
|
|
53
|
+
{/if}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
/**
|
|
3
|
+
* Heading text.
|
|
4
|
+
* @defaultValue `'References'`
|
|
5
|
+
*/
|
|
6
|
+
title?: string | undefined;
|
|
7
|
+
/**
|
|
8
|
+
* Render the heading. Off when the page supplies its own.
|
|
9
|
+
* @defaultValue `true`
|
|
10
|
+
*/
|
|
11
|
+
showTitle?: boolean | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* Heading level, for a page whose outline this list sits deeper in.
|
|
14
|
+
* @defaultValue `2`
|
|
15
|
+
*/
|
|
16
|
+
headingLevel?: 1 | 2 | 3 | 4 | 5 | 6 | undefined;
|
|
17
|
+
}
|
|
18
|
+
/** The numbered bibliography a page’s `<Citation>` markers accumulated, in citation order. */
|
|
19
|
+
declare const ReferenceList: import("svelte").Component<Props, {}, "">;
|
|
20
|
+
type ReferenceList = ReturnType<typeof ReferenceList>;
|
|
21
|
+
export default ReferenceList;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
A report as "Authors, <cite>Title</cite> (2021) Canberra: Department of X pp 88", with Schema.org `Report` microdata.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
ReportCitation — a report as "Authors, <cite>Title</cite> (2021) Canberra:
|
|
6
|
+
Department of X pp 88", with Schema.org Report microdata. Same shape as
|
|
7
|
+
`BookCitation` without edition, series or ISBN; a report's author and
|
|
8
|
+
publisher are usually the same Organization.
|
|
9
|
+
|
|
10
|
+
The record type is local — see `./csl.ts`. Every string is a prop with an
|
|
11
|
+
English default.
|
|
12
|
+
-->
|
|
13
|
+
<script lang="ts">import Year from "../formatting/Year.svelte";
|
|
14
|
+
import CreditList from "./CreditList.svelte";
|
|
15
|
+
import Publisher from "./Publisher.svelte";
|
|
16
|
+
let { report, itemid, untitledLabel = "Untitled report", noDateLabel = "no date", pageCountLabel = "pp", availableOnlineLabel = "available online at", locales } = $props();
|
|
17
|
+
const authors = $derived(report.authors ?? []);
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<span itemscope {itemid} itemtype="https://schema.org/Report">
|
|
21
|
+
{#if authors.length > 0}
|
|
22
|
+
<CreditList credits={authors} role="author" {locales} />,
|
|
23
|
+
{/if}
|
|
24
|
+
<cite itemprop="name">{report.title ?? untitledLabel}</cite>
|
|
25
|
+
<CreditList credits={report.editors ?? []} role="editor" {locales} />
|
|
26
|
+
<CreditList credits={report.translators ?? []} role="translator" {locales} />
|
|
27
|
+
({#if report.datePublished !== undefined}<Year
|
|
28
|
+
value={report.datePublished}
|
|
29
|
+
itemprop="datePublished"
|
|
30
|
+
{locales}
|
|
31
|
+
/>{:else}{noDateLabel}{/if})
|
|
32
|
+
{#if report.publisher !== undefined}
|
|
33
|
+
<Publisher publisher={report.publisher} />
|
|
34
|
+
{/if}
|
|
35
|
+
{#if report.numberOfPages !== undefined}
|
|
36
|
+
{pageCountLabel} <span itemprop="numberOfPages">{report.numberOfPages}</span>
|
|
37
|
+
{/if}
|
|
38
|
+
{#if report.url !== undefined}
|
|
39
|
+
{availableOnlineLabel} <a itemprop="url" href={report.url}>{report.url}</a>
|
|
40
|
+
{/if}
|
|
41
|
+
</span>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ReportRecord } from './csl.ts';
|
|
2
|
+
interface Props {
|
|
3
|
+
/** The report record; absent fields are left out of the rendering. */
|
|
4
|
+
report: ReportRecord;
|
|
5
|
+
/** Schema.org `itemid` on the root. */
|
|
6
|
+
itemid?: string | undefined;
|
|
7
|
+
/**
|
|
8
|
+
* Rendered in place of a missing title.
|
|
9
|
+
* @defaultValue `'Untitled report'`
|
|
10
|
+
*/
|
|
11
|
+
untitledLabel?: string | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* Rendered in place of a missing date.
|
|
14
|
+
* @defaultValue `'no date'`
|
|
15
|
+
*/
|
|
16
|
+
noDateLabel?: string | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Abbreviation after a page count.
|
|
19
|
+
* @defaultValue `'pp'`
|
|
20
|
+
*/
|
|
21
|
+
pageCountLabel?: string | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Lead-in before the record’s URL.
|
|
24
|
+
* @defaultValue `'available online at'`
|
|
25
|
+
*/
|
|
26
|
+
availableOnlineLabel?: string | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Locale(s) for the joined name lists.
|
|
29
|
+
* @defaultValue the components context's `locale()`
|
|
30
|
+
*/
|
|
31
|
+
locales?: string | readonly string[] | undefined;
|
|
32
|
+
}
|
|
33
|
+
/** A report as "Authors, <cite>Title</cite> (2021) Canberra: Department of X pp 88", with Schema.org `Report` microdata. */
|
|
34
|
+
declare const ReportCitation: import("svelte").Component<Props, {}, "">;
|
|
35
|
+
type ReportCitation = ReturnType<typeof ReportCitation>;
|
|
36
|
+
export default ReportCitation;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
A journal article as "Authors, ‘Title’ (2019) <cite>Periodical</cite> 12 (3) pp 45–67", with the Schema.org article → issue → volume → periodical chain as microdata.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
ScholarlyArticleCitation — a journal article as "Authors, 'Title' (2019)
|
|
6
|
+
<cite>Periodical</cite> 12 (3) pp 45–67 doi ISSN", with the Schema.org
|
|
7
|
+
ScholarlyArticle → PublicationIssue → PublicationVolume → Periodical chain
|
|
8
|
+
as nested `isPartOf` microdata.
|
|
9
|
+
|
|
10
|
+
The record type is local — see `./csl.ts`. Every string is a prop with an
|
|
11
|
+
English default.
|
|
12
|
+
-->
|
|
13
|
+
<script lang="ts">import Year from "../formatting/Year.svelte";
|
|
14
|
+
import CreditList from "./CreditList.svelte";
|
|
15
|
+
import DOILink from "./DOILink.svelte";
|
|
16
|
+
import ISSNLink from "./ISSNLink.svelte";
|
|
17
|
+
let { article, itemid, untitledLabel = "Untitled article", noDateLabel = "no date", pageLabel = "p", pagesLabel = "pp", availableOnlineLabel = "available online at", locales } = $props();
|
|
18
|
+
const authors = $derived(article.authors ?? []);
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<span itemscope {itemid} itemtype="https://schema.org/ScholarlyArticle">
|
|
22
|
+
{#if authors.length > 0}
|
|
23
|
+
<CreditList credits={authors} role="author" {locales} />,
|
|
24
|
+
{/if}
|
|
25
|
+
'<cite class="not-italic" itemprop="headline name">{article.title ?? untitledLabel}</cite>'
|
|
26
|
+
({#if article.datePublished !== undefined}<Year
|
|
27
|
+
value={article.datePublished}
|
|
28
|
+
itemprop="datePublished"
|
|
29
|
+
{locales}
|
|
30
|
+
/>{:else}{noDateLabel}{/if})
|
|
31
|
+
{#if article.periodical !== undefined || article.volumeNumber !== undefined || article.issueNumber !== undefined}
|
|
32
|
+
<span itemprop="isPartOf" itemscope itemtype="https://schema.org/PublicationIssue">
|
|
33
|
+
<span itemprop="isPartOf" itemscope itemtype="https://schema.org/PublicationVolume">
|
|
34
|
+
{#if article.periodical?.title !== undefined}
|
|
35
|
+
<span itemprop="isPartOf" itemscope itemtype="https://schema.org/Periodical">
|
|
36
|
+
<cite class="italic" itemprop="name">{article.periodical.title}</cite>
|
|
37
|
+
</span>
|
|
38
|
+
{/if}
|
|
39
|
+
{#if article.volumeNumber !== undefined}
|
|
40
|
+
<span itemprop="volumeNumber">{article.volumeNumber}</span>
|
|
41
|
+
{/if}
|
|
42
|
+
</span>
|
|
43
|
+
{#if article.issueNumber !== undefined}
|
|
44
|
+
(<span itemprop="issueNumber">{article.issueNumber}</span>)
|
|
45
|
+
{/if}
|
|
46
|
+
</span>
|
|
47
|
+
{/if}
|
|
48
|
+
{#if article.pageStart !== undefined && article.pageEnd !== undefined}
|
|
49
|
+
{pagesLabel} <span itemprop="pageStart">{article.pageStart}</span>–<span itemprop="pageEnd"
|
|
50
|
+
>{article.pageEnd}</span
|
|
51
|
+
>
|
|
52
|
+
{:else if article.pageStart !== undefined}
|
|
53
|
+
{pageLabel} <span itemprop="pageStart">{article.pageStart}</span>
|
|
54
|
+
{/if}
|
|
55
|
+
{#if article.doi !== undefined}
|
|
56
|
+
<DOILink doi={article.doi} itemprop="identifier sameAs" />
|
|
57
|
+
{/if}
|
|
58
|
+
{#if article.periodical?.issn !== undefined}
|
|
59
|
+
<ISSNLink issn={article.periodical.issn} />
|
|
60
|
+
{/if}
|
|
61
|
+
{#if article.url !== undefined}
|
|
62
|
+
{availableOnlineLabel} <a itemprop="url" href={article.url}>{article.url}</a>
|
|
63
|
+
{/if}
|
|
64
|
+
</span>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { ScholarlyArticleRecord } from './csl.ts';
|
|
2
|
+
interface Props {
|
|
3
|
+
/** The article record, with its periodical, volume and issue; absent fields are left out. */
|
|
4
|
+
article: ScholarlyArticleRecord;
|
|
5
|
+
/** Microdata `itemid` — the article's canonical URL. */
|
|
6
|
+
itemid?: string | undefined;
|
|
7
|
+
/**
|
|
8
|
+
* Rendered in place of a missing title.
|
|
9
|
+
* @defaultValue `'Untitled article'`
|
|
10
|
+
*/
|
|
11
|
+
untitledLabel?: string | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* Rendered in place of a missing date.
|
|
14
|
+
* @defaultValue `'no date'`
|
|
15
|
+
*/
|
|
16
|
+
noDateLabel?: string | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Abbreviation before a single page.
|
|
19
|
+
* @defaultValue `'p'`
|
|
20
|
+
*/
|
|
21
|
+
pageLabel?: string | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Abbreviation before a page range.
|
|
24
|
+
* @defaultValue `'pp'`
|
|
25
|
+
*/
|
|
26
|
+
pagesLabel?: string | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Lead-in before the record’s URL.
|
|
29
|
+
* @defaultValue `'available online at'`
|
|
30
|
+
*/
|
|
31
|
+
availableOnlineLabel?: string | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* Locale(s) for the joined name lists.
|
|
34
|
+
* @defaultValue the components context's `locale()`
|
|
35
|
+
*/
|
|
36
|
+
locales?: string | readonly string[] | undefined;
|
|
37
|
+
}
|
|
38
|
+
/** A journal article as "Authors, ‘Title’ (2019) <cite>Periodical</cite> 12 (3) pp 45–67", with the Schema.org article → issue → volume → periodical chain as microdata. */
|
|
39
|
+
declare const ScholarlyArticleCitation: import("svelte").Component<Props, {}, "">;
|
|
40
|
+
type ScholarlyArticleCitation = ReturnType<typeof ScholarlyArticleCitation>;
|
|
41
|
+
export default ScholarlyArticleCitation;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<!-- @component
|
|
2
|
+
A thesis as "Author, <cite>Title</cite> (2019) PhD thesis, University of Sydney", with Schema.org `Thesis` microdata.
|
|
3
|
+
-->
|
|
4
|
+
<!--
|
|
5
|
+
ThesisCitation — a thesis as "Author, <cite>Title</cite> (2019) PhD thesis,
|
|
6
|
+
University of Sydney", with Schema.org Thesis microdata.
|
|
7
|
+
|
|
8
|
+
The record type is local — see `./csl.ts`. Every string is a prop with an
|
|
9
|
+
English default.
|
|
10
|
+
-->
|
|
11
|
+
<script lang="ts">import Year from "../formatting/Year.svelte";
|
|
12
|
+
import CreditList from "./CreditList.svelte";
|
|
13
|
+
import Publisher from "./Publisher.svelte";
|
|
14
|
+
let { thesis, untitledLabel = "Untitled thesis", degreeLabel = (degree) => degree === undefined ? "thesis" : `${degree} thesis`, availableOnlineLabel = "available online at", locales } = $props();
|
|
15
|
+
const authors = $derived(thesis.authors ?? []);
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<span itemscope itemtype="https://schema.org/Thesis">
|
|
19
|
+
{#if authors.length > 0}
|
|
20
|
+
<CreditList credits={authors} role="author" {locales} />,
|
|
21
|
+
{/if}
|
|
22
|
+
<cite itemprop="name">{thesis.title ?? untitledLabel}</cite>
|
|
23
|
+
{#if thesis.datePublished !== undefined}
|
|
24
|
+
(<Year value={thesis.datePublished} itemprop="datePublished" {locales} />)
|
|
25
|
+
{/if}
|
|
26
|
+
{#if thesis.degree !== undefined || thesis.institution !== undefined}
|
|
27
|
+
<span itemprop="inSupportOf">{degreeLabel(thesis.degree)}</span
|
|
28
|
+
>{#if thesis.institution !== undefined},
|
|
29
|
+
<Publisher publisher={thesis.institution} itemprop="sourceOrganization" />
|
|
30
|
+
{/if}
|
|
31
|
+
{/if}
|
|
32
|
+
{#if thesis.url !== undefined}
|
|
33
|
+
{availableOnlineLabel} <a itemprop="url" href={thesis.url}>{thesis.url}</a>
|
|
34
|
+
{/if}
|
|
35
|
+
</span>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ThesisRecord } from "./csl.ts";
|
|
2
|
+
interface Props {
|
|
3
|
+
/** The thesis record; absent fields are left out of the rendering. */
|
|
4
|
+
thesis: ThesisRecord;
|
|
5
|
+
/**
|
|
6
|
+
* Rendered in place of a missing title.
|
|
7
|
+
* @defaultValue `'Untitled thesis'`
|
|
8
|
+
*/
|
|
9
|
+
untitledLabel?: string | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* Degree → its label.
|
|
12
|
+
* @defaultValue `"<degree> thesis"`, or `"thesis"` without a degree
|
|
13
|
+
*/
|
|
14
|
+
degreeLabel?: ((degree: string | undefined) => string) | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* Lead-in before the record’s URL.
|
|
17
|
+
* @defaultValue `'available online at'`
|
|
18
|
+
*/
|
|
19
|
+
availableOnlineLabel?: string | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Locale(s) for the joined name lists.
|
|
22
|
+
* @defaultValue the components context's `locale()`
|
|
23
|
+
*/
|
|
24
|
+
locales?: string | readonly string[] | undefined;
|
|
25
|
+
}
|
|
26
|
+
/** A thesis as "Author, <cite>Title</cite> (2019) PhD thesis, University of Sydney", with Schema.org `Thesis` microdata. */
|
|
27
|
+
declare const ThesisCitation: import("svelte").Component<Props, {}, "">;
|
|
28
|
+
type ThesisCitation = ReturnType<typeof ThesisCitation>;
|
|
29
|
+
export default ThesisCitation;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The bibliography context a page's citations and footnotes collect into.
|
|
3
|
+
*
|
|
4
|
+
* A `<Citation>` in prose has to know its own number, and the number depends
|
|
5
|
+
* on how many distinct sources were cited before it — which only the
|
|
6
|
+
* surrounding page knows. So the four components share one manager through
|
|
7
|
+
* Svelte context: `<Citation>` registers a source and gets its ordinal back,
|
|
8
|
+
* `<ReferenceList>` renders what accumulated, and the footnote pair does the
|
|
9
|
+
* same for notes.
|
|
10
|
+
*
|
|
11
|
+
* `getBibliographyContext` does not throw when no provider is mounted: it
|
|
12
|
+
* falls back to a fresh manager, matching how this package's
|
|
13
|
+
* `setComponentsContext` degrades (`../context.svelte.ts`). A `<Citation>`
|
|
14
|
+
* rendered on its own — in a story, in a unit test, or on a page that never
|
|
15
|
+
* calls `setupBibliography` — is a legitimate use; it just numbers from one
|
|
16
|
+
* and has no reference list to link to.
|
|
17
|
+
*
|
|
18
|
+
* @module
|
|
19
|
+
*/
|
|
20
|
+
import type { Citation, Footnote } from './citation.ts';
|
|
21
|
+
/** One collected source, with the order it was first cited in. */
|
|
22
|
+
export interface BibliographyEntry {
|
|
23
|
+
readonly citation: Citation;
|
|
24
|
+
readonly order: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The per-page collector. Citations dedupe by id — the same source cited
|
|
28
|
+
* three times is `[1]` three times, which is the whole point of a numbered
|
|
29
|
+
* style — and footnotes dedupe by their own key.
|
|
30
|
+
*/
|
|
31
|
+
export declare class BibliographyManager {
|
|
32
|
+
#private;
|
|
33
|
+
/**
|
|
34
|
+
* Register a source and return its bibliography number, assigning the next
|
|
35
|
+
* one if this is its first appearance.
|
|
36
|
+
*/
|
|
37
|
+
addCitation(citation: Citation): number;
|
|
38
|
+
/** Every collected source, in citation order. */
|
|
39
|
+
citations(): readonly BibliographyEntry[];
|
|
40
|
+
/** Register a footnote under a caller-supplied key. */
|
|
41
|
+
addFootnote(id: string, footnote: Footnote): void;
|
|
42
|
+
/** Every collected footnote, in registration order. */
|
|
43
|
+
footnotes(): readonly (readonly [string, Footnote])[];
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Provide a bibliography to a component subtree. Call once, in the page (or
|
|
47
|
+
* layout) whose prose carries the citations.
|
|
48
|
+
*/
|
|
49
|
+
export declare const setupBibliography: () => BibliographyManager;
|
|
50
|
+
/**
|
|
51
|
+
* The nearest provided bibliography, or a fresh standalone one.
|
|
52
|
+
*
|
|
53
|
+
* Falling back rather than throwing is deliberate (see the module doc).
|
|
54
|
+
*/
|
|
55
|
+
export declare const getBibliographyContext: () => BibliographyManager;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The bibliography context a page's citations and footnotes collect into.
|
|
3
|
+
*
|
|
4
|
+
* A `<Citation>` in prose has to know its own number, and the number depends
|
|
5
|
+
* on how many distinct sources were cited before it — which only the
|
|
6
|
+
* surrounding page knows. So the four components share one manager through
|
|
7
|
+
* Svelte context: `<Citation>` registers a source and gets its ordinal back,
|
|
8
|
+
* `<ReferenceList>` renders what accumulated, and the footnote pair does the
|
|
9
|
+
* same for notes.
|
|
10
|
+
*
|
|
11
|
+
* `getBibliographyContext` does not throw when no provider is mounted: it
|
|
12
|
+
* falls back to a fresh manager, matching how this package's
|
|
13
|
+
* `setComponentsContext` degrades (`../context.svelte.ts`). A `<Citation>`
|
|
14
|
+
* rendered on its own — in a story, in a unit test, or on a page that never
|
|
15
|
+
* calls `setupBibliography` — is a legitimate use; it just numbers from one
|
|
16
|
+
* and has no reference list to link to.
|
|
17
|
+
*
|
|
18
|
+
* @module
|
|
19
|
+
*/
|
|
20
|
+
import { getContext, setContext } from 'svelte';
|
|
21
|
+
const BIBLIOGRAPHY_KEY = Symbol('components/bibliography');
|
|
22
|
+
/**
|
|
23
|
+
* The per-page collector. Citations dedupe by id — the same source cited
|
|
24
|
+
* three times is `[1]` three times, which is the whole point of a numbered
|
|
25
|
+
* style — and footnotes dedupe by their own key.
|
|
26
|
+
*/
|
|
27
|
+
export class BibliographyManager {
|
|
28
|
+
#entries = $state(new Map());
|
|
29
|
+
#footnotes = $state(new Map());
|
|
30
|
+
#nextOrder = $state(1);
|
|
31
|
+
/**
|
|
32
|
+
* Register a source and return its bibliography number, assigning the next
|
|
33
|
+
* one if this is its first appearance.
|
|
34
|
+
*/
|
|
35
|
+
addCitation(citation) {
|
|
36
|
+
const existing = this.#entries.get(citation.id);
|
|
37
|
+
if (existing !== undefined)
|
|
38
|
+
return existing.order;
|
|
39
|
+
const order = this.#nextOrder;
|
|
40
|
+
this.#entries.set(citation.id, { citation, order });
|
|
41
|
+
this.#nextOrder = order + 1;
|
|
42
|
+
return order;
|
|
43
|
+
}
|
|
44
|
+
/** Every collected source, in citation order. */
|
|
45
|
+
citations() {
|
|
46
|
+
return [...this.#entries.values()].sort((a, b) => a.order - b.order);
|
|
47
|
+
}
|
|
48
|
+
/** Register a footnote under a caller-supplied key. */
|
|
49
|
+
addFootnote(id, footnote) {
|
|
50
|
+
this.#footnotes.set(id, footnote);
|
|
51
|
+
}
|
|
52
|
+
/** Every collected footnote, in registration order. */
|
|
53
|
+
footnotes() {
|
|
54
|
+
return [...this.#footnotes.entries()];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Provide a bibliography to a component subtree. Call once, in the page (or
|
|
59
|
+
* layout) whose prose carries the citations.
|
|
60
|
+
*/
|
|
61
|
+
export const setupBibliography = () => {
|
|
62
|
+
const manager = new BibliographyManager();
|
|
63
|
+
setContext(BIBLIOGRAPHY_KEY, manager);
|
|
64
|
+
return manager;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* The nearest provided bibliography, or a fresh standalone one.
|
|
68
|
+
*
|
|
69
|
+
* Falling back rather than throwing is deliberate (see the module doc).
|
|
70
|
+
*/
|
|
71
|
+
export const getBibliographyContext = () => {
|
|
72
|
+
// `getContext<T>` is typed to return `T`, but returns `undefined` when no
|
|
73
|
+
// provider is mounted — the `??` is the runtime fallback that type does not
|
|
74
|
+
// describe, which is why the annotation stays `BibliographyManager` rather
|
|
75
|
+
// than widening the whole call site to a union.
|
|
76
|
+
const provided = getContext(BIBLIOGRAPHY_KEY);
|
|
77
|
+
return provided ?? new BibliographyManager();
|
|
78
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The citation vocabulary and its formatter.
|
|
3
|
+
*
|
|
4
|
+
* The shape a `Citation` carries is deliberately not any particular app's
|
|
5
|
+
* publication model: this package is app-agnostic and presentational, and a
|
|
6
|
+
* component that imported a models package would put the whole model layer
|
|
7
|
+
* into every consumer's bundle for the sake of a title and a year. The app
|
|
8
|
+
* maps its resource onto this shape at its own seam, which is also what lets
|
|
9
|
+
* a Storybook story or a test render one from a literal.
|
|
10
|
+
*
|
|
11
|
+
* ## Why the formatter is a pure function here
|
|
12
|
+
*
|
|
13
|
+
* Formatting inside the component recomputes on every re-render and cannot
|
|
14
|
+
* be tested without mounting a component. Pulling it out fixes both — the
|
|
15
|
+
* caller can memoise, the list derives once — and a citation style is a pile
|
|
16
|
+
* of conditional punctuation, which is exactly the kind of code that is
|
|
17
|
+
* wrong in the fourth branch and never noticed by eye.
|
|
18
|
+
*
|
|
19
|
+
* The style is a compact author–date one. It is not CSL: a full CSL
|
|
20
|
+
* implementation is a dependency and a style-file pipeline, and most
|
|
21
|
+
* consumers need one readable rendering rather than eleven switchable ones.
|
|
22
|
+
*
|
|
23
|
+
* @module
|
|
24
|
+
*/
|
|
25
|
+
/** The kinds a citation renders differently. */
|
|
26
|
+
export type CitationKind = 'article' | 'book' | 'chapter' | 'thesis' | 'report' | 'conference' | 'web' | 'dataset' | 'software' | 'media' | 'periodical';
|
|
27
|
+
/**
|
|
28
|
+
* One bibliography entry, as a presentational component needs it.
|
|
29
|
+
*
|
|
30
|
+
* Every field beyond `id` / `kind` / `title` is optional, because every one of
|
|
31
|
+
* them is missing from some real citation: a thesis has no journal, a
|
|
32
|
+
* mononymous eighteenth-century author has no given name, and grey literature
|
|
33
|
+
* routinely has no year.
|
|
34
|
+
*/
|
|
35
|
+
export interface Citation {
|
|
36
|
+
/** The publication's node id — also the anchor `#ref-<id>` links to. */
|
|
37
|
+
readonly id: string;
|
|
38
|
+
readonly kind: CitationKind;
|
|
39
|
+
readonly title: string;
|
|
40
|
+
/** Author display names, already ordered by the byline's own ordinal. */
|
|
41
|
+
readonly authors?: readonly string[] | undefined;
|
|
42
|
+
/** Publication year, as printed. */
|
|
43
|
+
readonly year?: number | undefined;
|
|
44
|
+
/** The serial an article appeared in, or the book a chapter is from. */
|
|
45
|
+
readonly container?: string | undefined;
|
|
46
|
+
readonly volume?: string | undefined;
|
|
47
|
+
readonly issue?: string | undefined;
|
|
48
|
+
/** Page span, already assembled (`"12–34"`). */
|
|
49
|
+
readonly pages?: string | undefined;
|
|
50
|
+
readonly publisher?: string | undefined;
|
|
51
|
+
readonly place?: string | undefined;
|
|
52
|
+
readonly url?: string | undefined;
|
|
53
|
+
readonly doi?: string | undefined;
|
|
54
|
+
/** When the citing author read a web source. */
|
|
55
|
+
readonly accessed?: Date | undefined;
|
|
56
|
+
}
|
|
57
|
+
/** A footnote — tracked separately from citations. */
|
|
58
|
+
export interface Footnote {
|
|
59
|
+
/** The note's text. */
|
|
60
|
+
readonly content: string;
|
|
61
|
+
/** A custom marker (`*`, `†`) instead of the auto-assigned number. */
|
|
62
|
+
readonly symbol?: string | undefined;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Render a citation as one formatted string.
|
|
66
|
+
*
|
|
67
|
+
* Pure and total: every branch is reachable from real data and none throws on
|
|
68
|
+
* a citation carrying nothing but a title, which is a state the corpus can
|
|
69
|
+
* genuinely be in (an ingested reference awaiting enrichment).
|
|
70
|
+
*/
|
|
71
|
+
export declare const formatCitation: (citation: Citation) => string;
|