Skip to content

Commit

Permalink
Fix tables
Browse files Browse the repository at this point in the history
  • Loading branch information
kazcw committed Mar 4, 2025
1 parent 2d4eefd commit 689435b
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 20 deletions.
14 changes: 9 additions & 5 deletions app/gui/src/project-view/components/MarkdownEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@ import { Vec2 } from '@/util/data/vec2'
import { ComponentInstance, computed, defineAsyncComponent, ref, toRef } from 'vue'
import * as Y from 'yjs'
const props = defineProps<{
content: Y.Text | string
transformImageUrl?: UrlTransformer
}>()
const props = withDefaults(
defineProps<{
content: Y.Text | string
transformImageUrl?: UrlTransformer

Check warning on line 13 in app/gui/src/project-view/components/MarkdownEditor.vue

View workflow job for this annotation

GitHub Actions / 🧹 GUI Lint Results

app/gui/src/project-view/components/MarkdownEditor.vue#L13

[vue/require-default-prop] Prop 'transformImageUrl' requires default value to be set.

Check warning on line 13 in app/gui/src/project-view/components/MarkdownEditor.vue

View workflow job for this annotation

GitHub Actions / 🧹 GUI Lint Results

app/gui/src/project-view/components/MarkdownEditor.vue#L13

[vue/require-default-prop] Prop 'transformImageUrl' requires default value to be set.

Check warning on line 13 in app/gui/src/project-view/components/MarkdownEditor.vue

View workflow job for this annotation

GitHub Actions / 🧹 GUI Lint Results

app/gui/src/project-view/components/MarkdownEditor.vue#L13

[vue/require-default-prop] Prop 'transformImageUrl' requires default value to be set.

Check warning on line 13 in app/gui/src/project-view/components/MarkdownEditor.vue

View workflow job for this annotation

GitHub Actions / 🧹 GUI Lint Results

app/gui/src/project-view/components/MarkdownEditor.vue#L13

[vue/require-default-prop] Prop 'transformImageUrl' requires default value to be set.
toolbar?: boolean
}>(),
{ toolbar: true },
)
const inner = ref<ComponentInstance<typeof LazyMarkdownEditor>>()
Expand All @@ -33,7 +37,7 @@ defineExpose({

<template>
<Suspense>
<LazyMarkdownEditor ref="inner" v-bind="props">
<LazyMarkdownEditor ref="inner" :content="props.content" :toolbar="props.toolbar">
<template #toolbarLeft>
<slot name="toolbarLeft" />
</template>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ import { minimalSetup } from 'codemirror'
import { computed, onMounted, ref, useCssModule, useTemplateRef, type ComponentInstance } from 'vue'
import * as Y from 'yjs'
const { content } = defineProps<{
const { content, toolbar } = defineProps<{
content: Y.Text | string
toolbarContainer?: HTMLElement | undefined
toolbar: boolean
}>()
const focused = ref(false)
Expand Down Expand Up @@ -65,7 +65,7 @@ defineExpose({

<template>
<div class="MarkdownEditorRoot">
<div class="toolbar" @pointerdown.prevent>
<div v-if="toolbar" class="toolbar" @pointerdown.prevent>
<slot name="toolbarLeft" />
<template v-if="!readonly">
<BlockTypeDropdown
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,14 @@ const content = computed(() => {
<thead>
<tr>
<th v-for="(cell, c) in content.headers" :key="c" class="cell">
<MarkdownEditorImpl :content="cell" />
<MarkdownEditorImpl :content="cell" :toolbar="false" />
</th>
</tr>
</thead>
<tbody class="tableBody">
<tr v-for="(row, r) in content.rows" :key="r" class="row">
<td v-for="(cell, c) in row" :key="c" class="cell">
<MarkdownEditorImpl :content="cell" />
<MarkdownEditorImpl :content="cell" :toolbar="false" />
</td>
</tr>
</tbody>
Expand Down
56 changes: 50 additions & 6 deletions app/ydoc-shared/src/ast/__tests__/ensoMarkdown.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,18 @@ import { expect, test } from 'vitest'
import { type DebugTree, debugTree } from '../../util/lezer'
import { ensoMarkdownParser } from '../ensoMarkdown'

function checkTree({ source, expected }: { source: string; expected: DebugTree }) {
expect(debugTree(ensoMarkdownParser.parse(source), source)).toEqual(expected)
function checkTree({
source,
expected,
not,
}: {
source: string
expected: DebugTree
not?: DebugTree
}) {
const result = debugTree(ensoMarkdownParser.parse(source), source)
if (not) expect(result).not.toEqual(not)
expect(result).toEqual(expected)
}

// === Prerendered newlines ===
Expand Down Expand Up @@ -144,22 +154,18 @@ test.each([
source: '****',
// TODO
expected: ['Document', ['HorizontalRule', '****']],
not: ['Document', ['HorizontalRule', '****']],
},
{
description: 'Empty bold+italic not parsed as HorizontalRule',
source: '******',
// TODO
expected: ['Document', ['HorizontalRule', '******']],
not: ['Document', ['HorizontalRule', '******']],
},
{
description: 'Empty strikethrough not parsed as FencedCode',
source: '~~~~',
// TODO
// expected: ['Document', ['Paragraph', '~~~~']],
expected: ['Document', ['FencedCode', ['CodeMark', '~~~~']]],
not: ['Document', ['FencedCode', ['CodeMark', '~~~~']]],
},
])('Syntax extensions: Special cases: $description', checkTree)

Expand Down Expand Up @@ -239,6 +245,44 @@ test.each([
},
])('Standards-compatible AST refinements: $description', checkTree)

// === Standard extensions ===

test.each([
{
extension: 'Tables',
source: '| foo | bar |\n| --- | --- |\n| baz | bim |',
expected: [
'Document',
[
'Table',
[
'TableHeader',
['TableDelimiter', '|'],
['TableCell', 'foo'],
['TableDelimiter', '|'],
['TableCell', 'bar'],
['TableDelimiter', '|'],
],
['TableDelimiter', '| --- | --- |'],
[
'TableRow',
['TableDelimiter', '|'],
['TableCell', 'baz'],
['TableDelimiter', '|'],
['TableCell', 'bim'],
['TableDelimiter', '|'],
],
],
],
not: [
'Document',
['Paragraph', '| foo | bar |'],
['Paragraph', '| --- | --- |'],
['Paragraph', '| baz | bim |'],
],
},
])('Markdown extensions: $extension', checkTree)

// === Standard syntax cases ===

// These cases are not affected by our parser customizations (except for inclusion of extensions, like Strikethrough).
Expand Down
9 changes: 5 additions & 4 deletions app/ydoc-shared/src/ast/ensoMarkdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@ import {
} from '@lezer/markdown'

/**
* End any element when a newline is encountered. This parser operates on preprocessed Markdown that has "prerendered"
* newlines: Before parsing, hard-wrapped lines within any block element are concatenated, and the extra newlines
* between block elements are removed.
* End any element when a newline is encountered. This parser operates on preprocessed Markdown that
* has "prerendered" newlines: Before parsing, hard-wrapped lines within any block element are
* concatenated, and the extra newlines between block elements are removed.
*/
const newlineEndsBlock: BlockParser = {
name: 'NewlineEndsBlock',
endLeaf: () => true,
endLeaf: (_cx, line) =>
!(line.text.startsWith('|') && line.text.length > 2 && line.text.endsWith('|')),
}

/** @lezer/markdown extension for the Markdown dialect used in the Enso documentation editor. */
Expand Down

0 comments on commit 689435b

Please sign in to comment.