@erudit-js/prose 3.0.0-dev.29 → 4.0.0-dev.1

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.
@@ -1,12 +1,13 @@
1
1
  import { type Component, type InjectionKey, type Ref } from 'vue';
2
2
  import type { EruditLanguageCode } from '@erudit-js/core/eruditConfig/language';
3
3
  import type { EruditMode } from '@erudit-js/core/mode';
4
+ import type { FormatText } from '@erudit-js/core/formatText';
4
5
  import type { AppElement } from '../appElement.js';
5
6
  export interface ProseContext {
6
7
  mode: EruditMode;
7
8
  languageCode: EruditLanguageCode;
8
9
  appElements: Record<string, AppElement>;
9
- formatText: (text: string) => string;
10
+ formatText: FormatText;
10
11
  pathUrl: string;
11
12
  baseUrl: string;
12
13
  hashUrl: Ref<string | undefined>;
@@ -1 +1,5 @@
1
- export declare function useFormatText(): (text: string) => string;
1
+ import { type InjectionKey } from 'vue';
2
+ import type { FormatTextState } from '@erudit-js/core/formatText';
3
+ export declare function useFormatText(): import("@erudit-js/core/formatText").FormatText;
4
+ export declare const formatTextStateSymbol: InjectionKey<FormatTextState>;
5
+ export declare function useFormatTextState(): FormatTextState;
@@ -1,5 +1,10 @@
1
+ import { inject } from "vue";
1
2
  import { useProseContext } from "./context.js";
2
3
  export function useFormatText() {
3
4
  const { formatText } = useProseContext();
4
5
  return formatText;
5
6
  }
7
+ export const formatTextStateSymbol = Symbol();
8
+ export function useFormatTextState() {
9
+ return inject(formatTextStateSymbol);
10
+ }
@@ -2,15 +2,19 @@
2
2
  import { Text, h } from 'vue';
3
3
  import type { ProseElement, textSchema } from '@jsprose/core';
4
4
 
5
- import { useFormatText } from '../composables/formatText.js';
5
+ import {
6
+ useFormatText,
7
+ useFormatTextState,
8
+ } from '../composables/formatText.js';
6
9
 
7
10
  const { element } = defineProps<{ element: ProseElement<typeof textSchema> }>();
11
+ const formatTextState = useFormatTextState();
8
12
  const formatText = useFormatText();
9
13
 
10
14
  const originalText = element.data;
11
15
  const leadingSpace = originalText.match(/^(\s*)/)?.[1] ? ' ' : '';
12
16
  const trailingSpace = originalText.match(/(\s*)$/)?.[1] ? ' ' : '';
13
- const formattedText = formatText(originalText);
17
+ const formattedText = formatText(originalText, formatTextState);
14
18
  const textWithSpaces = leadingSpace + formattedText + trailingSpace;
15
19
 
16
20
  const TextComponent = h(Text, textWithSpaces);
@@ -1,6 +1,7 @@
1
1
  <script lang="ts" setup>
2
2
  import { provide } from 'vue';
3
3
  import type { AnySchema, GenericStorage, ProseElement } from '@jsprose/core';
4
+ import { createFormatTextState } from '@erudit-js/core/formatText';
4
5
 
5
6
  import {
6
7
  proseContextSymbol,
@@ -9,6 +10,7 @@ import {
9
10
  import { proseStorageSymbol } from '../composables/storage.js';
10
11
  import Render from './Render.vue';
11
12
  import { anchorStateSymbol, useAnchorState } from '../composables/anchor.js';
13
+ import { formatTextStateSymbol } from '../composables/formatText.js';
12
14
 
13
15
  const { element, storage, context } = defineProps<{
14
16
  element: ProseElement<AnySchema>;
@@ -21,6 +23,8 @@ provide(proseStorageSymbol, storage);
21
23
 
22
24
  const anchorState = useAnchorState(context.hashUrl, element);
23
25
  provide(anchorStateSymbol, anchorState);
26
+
27
+ provide(formatTextStateSymbol, createFormatTextState());
24
28
  </script>
25
29
 
26
30
  <template>
@@ -18,11 +18,16 @@ import {
18
18
  useResolveAnchor,
19
19
  } from '../../composables/anchor.js';
20
20
  import AsideMenu from './AsideMenu.vue';
21
+ import { useFormatTextState } from '../../composables/formatText.js';
21
22
 
22
23
  const { element } = defineProps<{ element: ProseElement<BlockSchema> }>();
23
24
  const { EruditIcon, EruditTransition } = useProseContext();
24
25
  const elementIcon = await useElementIcon(element);
25
26
 
27
+ const formatTextState = useFormatTextState();
28
+ // Reset quote state making sure any opened quote does not leak outside
29
+ formatTextState.quote = 'closed';
30
+
26
31
  const blockElement = useTemplateRef('block');
27
32
  const asideElement = useTemplateRef('aside');
28
33
  const asideMenuElement = useTemplateRef('asideMenu');
@@ -22,7 +22,7 @@ export function usePhotoSwipe() {
22
22
  lightbox.value.on("uiRegister", () => {
23
23
  lightbox.value.pswp?.ui?.registerElement({
24
24
  name: "caption",
25
- className: "text-xs micro:text-sm absolute bottom-0 w-full text-center p-normal bg-bg-main/50 backdrop-blur-md",
25
+ className: "text-xs micro:text-sm absolute **:text-text-muted bottom-0 w-full text-center p-normal bg-bg-main/50 backdrop-blur-md",
26
26
  order: 9,
27
27
  isButton: false,
28
28
  appendTo: "root",
@@ -30,7 +30,7 @@ onMounted(() => {
30
30
  <template>
31
31
  <div
32
32
  ref="caption"
33
- class="text-text-muted text-main-sm mt-small micro:mt-normal m-auto
33
+ class="**:text-text-muted text-main-sm mt-small micro:mt-normal m-auto
34
34
  text-center"
35
35
  v-bind="width ? { style: { width } } : {}"
36
36
  >
@@ -27,7 +27,7 @@ const containsAnchor = useContainsAnchor(element);
27
27
  </script>
28
28
 
29
29
  <template>
30
- <Block :element v-if="isAnchor || containsAnchor || mode !== 'generate'">
30
+ <Block :element v-if="isAnchor || containsAnchor || mode !== 'static'">
31
31
  <div
32
32
  class="border-border bg-bg-accent/30 rounded-xl border-2
33
33
  border-dashed transition-[border,background]
@@ -26,6 +26,7 @@ const { EruditIcon, loadingSvg } = useProseContext();
26
26
  const loading = ref(true);
27
27
  const diagramRendering = ref(false);
28
28
  const dummyMathHtml = ref('');
29
+ const dummyElement = useTemplateRef('dummy');
29
30
  const diagramContent = ref(element.children[0].data);
30
31
  const diagramSvgContent = ref('');
31
32
  const diagramElement = useTemplateRef('diagram');
@@ -198,7 +199,11 @@ async function renderDiagram() {
198
199
  theme: 'base',
199
200
  });
200
201
 
201
- const { svg } = await mermaid.render(diagramUid, diagramContent.value);
202
+ const { svg } = await mermaid.render(
203
+ diagramUid,
204
+ diagramContent.value,
205
+ dummyElement.value!,
206
+ );
202
207
 
203
208
  diagramSvgContent.value = svg;
204
209
  }
@@ -207,7 +212,8 @@ async function renderDiagram() {
207
212
  <template>
208
213
  <Block :element>
209
214
  <div
210
- class="fixed -top-[9999px] -left-[9999px]"
215
+ ref="dummy"
216
+ :class="[$style.diagram, 'fixed -top-[9999px] -left-[9999px]']"
211
217
  v-html="dummyMathHtml"
212
218
  ></div>
213
219
  <div ref="diagram">
@@ -239,6 +245,10 @@ async function renderDiagram() {
239
245
  cursor: pointer;
240
246
  }
241
247
 
248
+ :global(.katex-display) {
249
+ margin: 0 !important;
250
+ }
251
+
242
252
  /* Text color */
243
253
 
244
254
  :global(.edgeLabel) {
@@ -79,7 +79,8 @@ function linkClick() {
79
79
  :style="{ '--tGap': '1px', '--xGap': '4px', '--bGap': '4px' }"
80
80
  class="text-brand hocus:bg-brand/15 relative
81
81
  -mx-[calc(var(--xGap)-3px)] -mt-(--tGap) -mb-(--bGap) rounded-sm
82
- bg-transparent px-(--xGap) pt-(--tGap) pb-(--bGap) underline
82
+ bg-transparent px-(--xGap) pt-(--tGap) pb-(--bGap)
83
+ whitespace-nowrap underline
83
84
  decoration-[color-mix(in_srgb,var(--color-brand)30%,transparent)]
84
85
  decoration-2 underline-offset-2 transition-[color,background]"
85
86
  >
@@ -14,9 +14,9 @@ defineProps<{ element: ProseElement<typeof listSchema> }>();
14
14
  :is="element.data.type"
15
15
  class="micro:[--proseGap:18px]"
16
16
  :style="{
17
- '--liBorder': 'var(--accentBorder, var(--color-border))',
17
+ '--liBorder': 'var(--color-text-disabled)',
18
18
  '--liBackground':
19
- 'color-mix(in hsl, var(--accentText, var(--color-text)) 12%, transparent)',
19
+ 'color-mix(in hsl, var(--accentText, var(--color-text)) 12%, var(--color-bg-main))',
20
20
  '--liText': 'var(--accentText, var(--color-text-muted))',
21
21
  }"
22
22
  v-bind="
@@ -27,9 +27,14 @@ defineProps<{ element: ProseElement<typeof listSchema> }>();
27
27
  >
28
28
  <li
29
29
  v-for="(listItem, i) of element.children"
30
- class="flex not-last-of-type:mb-(--proseGap)"
30
+ class="relative flex not-last-of-type:mb-(--proseGap)"
31
31
  >
32
- <div class="shrink-0">
32
+ <div
33
+ class="micro:left-[11px] bg-text-disabled micro:w-[2px]
34
+ absolute top-[3px] bottom-[5px] left-[9px] w-[1px]
35
+ transition-[background]"
36
+ ></div>
37
+ <div class="relative shrink-0">
33
38
  <div
34
39
  class="micro:top-[1.5px] micro:size-[23px] relative
35
40
  top-[3px] flex size-[20px] items-center
@@ -1,5 +1,5 @@
1
1
  import { type TagChildren } from '@jsprose/core';
2
- export declare const mathGroupTypes: readonly ["zero", "normal", "big"];
2
+ export declare const mathGroupTypes: readonly ["zero", "normal", "big", "huge"];
3
3
  export type MathGroupGapType = (typeof mathGroupTypes)[number] | 'custom';
4
4
  export interface MathGroupGapTemplate {
5
5
  type: MathGroupGapType;
@@ -13,11 +13,14 @@ export interface MathGroupGapNormal extends MathGroupGapTemplate {
13
13
  export interface MathGroupGapBig extends MathGroupGapTemplate {
14
14
  type: 'big';
15
15
  }
16
+ export interface MathGroupGapHuge extends MathGroupGapTemplate {
17
+ type: 'huge';
18
+ }
16
19
  export interface MathGroupGapCustom extends MathGroupGapTemplate {
17
20
  type: 'custom';
18
21
  size: string;
19
22
  }
20
- export type MathGroupGap = MathGroupGapNone | MathGroupGapNormal | MathGroupGapBig | MathGroupGapCustom;
23
+ export type MathGroupGap = MathGroupGapNone | MathGroupGapNormal | MathGroupGapBig | MathGroupGapHuge | MathGroupGapCustom;
21
24
  export type MathGroupPart = string | MathGroup;
22
25
  export interface MathGroup {
23
26
  gap: MathGroupGap;
@@ -4,7 +4,8 @@ import { defineEruditTag } from "../../tag.js";
4
4
  export const mathGroupTypes = [
5
5
  "zero",
6
6
  "normal",
7
- "big"
7
+ "big",
8
+ "huge"
8
9
  ];
9
10
  function gapFromString(strGap) {
10
11
  if (mathGroupTypes.includes(strGap)) {
@@ -15,6 +15,8 @@ const columnGap = (() => {
15
15
  return 'var(--proseAsideWidth)';
16
16
  case 'big':
17
17
  return 'calc(var(--proseAsideWidth) * 2)';
18
+ case 'huge':
19
+ return 'calc(var(--proseAsideWidth) * 4)';
18
20
  case 'custom':
19
21
  return mathGroup.gap.size;
20
22
  }
@@ -16,8 +16,6 @@ export const Problem = defineEruditTag({
16
16
  })(({ element, tagName, props, children }) => {
17
17
  element.data = { info: problemProps2Info(props) };
18
18
  element.title = element.data.info.title;
19
- element.snippet = {};
20
- element.toc = { add: true };
21
19
  if (children && props.script) {
22
20
  throw new ProseError(`<${tagName}> cannot have both script and children in Problem element!`);
23
21
  }
@@ -64,8 +64,6 @@ export const Problems = defineEruditTag({
64
64
  element.children = [...otherChildren, ...subProblemChildren];
65
65
  element.data = problemProps2Info(props);
66
66
  element.title = element.data.title;
67
- element.snippet = {};
68
- element.toc = { add: true };
69
67
  });
70
68
  export const problemsRegistryItem = defineRegistryItem({
71
69
  schema: problemsSchema,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@erudit-js/prose",
4
- "version": "3.0.0-dev.29",
4
+ "version": "4.0.0-dev.1",
5
5
  "description": "📝 JSX prose subsystem for Erudit sites",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
@@ -32,7 +32,7 @@
32
32
  "prepack": "bun run build"
33
33
  },
34
34
  "dependencies": {
35
- "@erudit-js/core": "3.0.0-dev.29",
35
+ "@erudit-js/core": "4.0.0-dev.1",
36
36
  "@jsprose/core": "^1.0.0",
37
37
  "vue": "latest",
38
38
  "@floating-ui/vue": "^1.1.9",