Skip to content

Commit

Permalink
Added AST & info/fail message reporting to application; added info me…
Browse files Browse the repository at this point in the history
…ssages to tooltip plugin and fail message to chart configuration parsing (#3602)
  • Loading branch information
chandlerprall authored Jun 16, 2020
1 parent dc8fee5 commit a35fc03
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 14 deletions.
40 changes: 35 additions & 5 deletions src-docs/src/views/markdown_editor/markdown_editor.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
/* eslint-disable prettier/prettier */
import React, { useState } from 'react';
import React, { useCallback, useState } from 'react';

import { defaultParsingPlugins, defaultProcessingPlugins, EuiMarkdownEditor } from '../../../../src';
import {
defaultParsingPlugins,
defaultProcessingPlugins,
EuiMarkdownEditor,
EuiSpacer,
EuiText,
EuiCodeBlock,
} from '../../../../src';
import * as MarkdownChart from './plugins/markdown_chart';
import * as MarkdownTooltip from './plugins/markdown_tooltip';
import * as MarkdownCheckbox from './plugins/markdown_checkbox';
Expand All @@ -23,9 +29,33 @@ exampleProcessingList[0][1].handlers.tooltipPlugin = MarkdownTooltip.handler;
exampleProcessingList[1][1].components.tooltipPlugin = MarkdownTooltip.renderer;

exampleProcessingList[0][1].handlers.checkboxPlugin = MarkdownCheckbox.handler;
exampleProcessingList[1][1].components.checkboxPlugin = MarkdownCheckbox.renderer;
exampleProcessingList[1][1].components.checkboxPlugin =
MarkdownCheckbox.renderer;

export default () => {
const [value, setValue] = useState(markdownExample);
return <EuiMarkdownEditor value={value} onChange={setValue} height={400} uiPlugins={[MarkdownChart.plugin, MarkdownTooltip.plugin]} parsingPluginList={exampleParsingList} processingPluginList={exampleProcessingList} />;
const [messages, setMessages] = useState([]);
const [ast, setAst] = useState(null);
const onParse = useCallback((err, { messages, ast }) => {
setMessages(err ? [err] : messages);
setAst(JSON.stringify(ast, null, 2));
}, []);
return (
<>
<EuiMarkdownEditor
value={value}
onChange={setValue}
height={400}
uiPlugins={[MarkdownChart.plugin, MarkdownTooltip.plugin]}
parsingPluginList={exampleParsingList}
processingPluginList={exampleProcessingList}
onParse={onParse}
/>
<EuiSpacer />
{messages.map((message, idx) => (
<EuiText key={idx}>{message.toString()}</EuiText>
))}
<EuiCodeBlock language="json">{ast}</EuiCodeBlock>
</>
);
};
9 changes: 7 additions & 2 deletions src-docs/src/views/markdown_editor/plugins/markdown_chart.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,13 @@ function ChartParser() {
match += configurationString;
try {
configuration = JSON.parse(configurationString);
// eslint-disable-next-line no-empty
} catch (e) {}
} catch (e) {
const now = eat.now();
this.file.fail(`Unable to parse chart JSON configuration: ${e}`, {
line: now.line,
column: now.column + 7,
});
}
}

match += '}';
Expand Down
16 changes: 15 additions & 1 deletion src-docs/src/views/markdown_editor/plugins/markdown_tooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,27 @@ function TooltipParser() {
const tooltipAnchor = readArg('[', ']');
const tooltipText = readArg('(', ')');

const now = eat.now();

if (!tooltipAnchor) {
this.file.info('No tooltip anchor found', {
line: now.line,
column: now.column + 10,
});
}
if (!tooltipText) {
this.file.info('No tooltip text found', {
line: now.line,
column: now.column + 12 + tooltipAnchor.length,
});
}

if (!tooltipText || !tooltipAnchor) return false;

if (silent) {
return true;
}

const now = eat.now();
now.column += 10;
now.offset += 10;
const children = this.tokenizeInline(tooltipAnchor, now);
Expand Down
32 changes: 31 additions & 1 deletion src/components/markdown_editor/markdown_editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import React, {
useState,
} from 'react';
import unified, { PluggableList, Processor } from 'unified';
import { VFileMessage } from 'vfile-message';
import classNames from 'classnames';
// @ts-ignore
import emoji from 'remark-emoji';
Expand Down Expand Up @@ -105,7 +106,17 @@ export type EuiMarkdownEditorProps = HTMLAttributes<HTMLDivElement> &
/** array of unified plugins to convert the AST into a ReactNode */
processingPluginList?: PluggableList;

/** array of toolbar plugins **/
uiPlugins?: EuiMarkdownEditorUiPlugin[];

/** callback triggered when parsing results are available **/
onParse?: (
error: any | null,
data: {
messages: VFileMessage[];
ast: any;
}
) => void;
};

export const EuiMarkdownEditor: FunctionComponent<EuiMarkdownEditorProps> = ({
Expand All @@ -117,6 +128,7 @@ export const EuiMarkdownEditor: FunctionComponent<EuiMarkdownEditorProps> = ({
parsingPluginList = defaultParsingPlugins,
processingPluginList = defaultProcessingPlugins,
uiPlugins = [],
onParse,
...rest
}) => {
const [viewMode, setViewMode] = useState<MARKDOWN_MODE>(MODE_EDITING);
Expand Down Expand Up @@ -148,7 +160,16 @@ export const EuiMarkdownEditor: FunctionComponent<EuiMarkdownEditorProps> = ({
.use(identityCompiler);
}, [parsingPluginList]);

const parsed = useMemo(() => parser.processSync(value), [parser, value]);
const [parsed, parseError] = useMemo<
[any | null, VFileMessage | null]
>(() => {
try {
const parsed = parser.processSync(value);
return [parsed, null];
} catch (e) {
return [null, e];
}
}, [parser, value]);

const processor = useMemo(
() =>
Expand Down Expand Up @@ -180,6 +201,7 @@ export const EuiMarkdownEditor: FunctionComponent<EuiMarkdownEditorProps> = ({
);
useEffect(() => {
if (textareaRef == null) return;
if (parsed == null) return;

const getCursorNode = () => {
const { selectionStart } = textareaRef;
Expand Down Expand Up @@ -215,6 +237,14 @@ export const EuiMarkdownEditor: FunctionComponent<EuiMarkdownEditorProps> = ({
};
}, [textareaRef, parsed]);

useEffect(() => {
if (onParse) {
const messages = parsed ? parsed.messages : [];
const ast = parsed ? parsed.contents : null;
onParse(parseError, { messages, ast });
}
}, [onParse, parsed, parseError]);

return (
<EuiMarkdownContext.Provider value={contextValue}>
<div className={classes} {...rest}>
Expand Down
13 changes: 8 additions & 5 deletions src/components/markdown_editor/markdown_format.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,12 @@ export const EuiMarkdownFormat: FunctionComponent<EuiMarkdownFormatProps> = ({
children,
processor,
}) => {
const result = useMemo(() => processor.processSync(children), [
processor,
children,
]);
return <div className="euiMarkdownFormat">{result.contents}</div>;
const result = useMemo(() => {
try {
return processor.processSync(children).contents;
} catch (e) {
return children;
}
}, [processor, children]);
return <div className="euiMarkdownFormat">{result}</div>;
};

0 comments on commit a35fc03

Please sign in to comment.