/* * SPDX-License-Identifier: Apache-2.0 * * The OpenSearch Contributors require contributions made to * this file be licensed under the Apache-2.0 license or a * compatible open source license. * * Modifications Copyright OpenSearch Contributors. See * GitHub history for details. */ /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright * ownership. Elasticsearch B.V. licenses this file to you under * the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import React, { FunctionComponent } from 'react'; import { OuiMarkdownAstNodePosition, RemarkTokenizer } from '../markdown_types'; import { OuiToolTip } from '../../tool_tip'; import { OuiIcon } from '../../icon'; import { OuiCodeBlock } from '../../code'; import { Plugin } from 'unified'; interface TooltipNodeDetails { type: 'tooltipPlugin'; content: string; } const tooltipPlugin = { name: 'tooltipPlugin', button: { label: 'Tooltip', iconType: 'editorComment', }, formatting: { prefix: '!{tooltip[', suffix: ']()}', trimFirst: true, }, helpText: ( {'!{tooltip[anchor text](helpful description)}'} ), }; const TooltipParser: Plugin = function TooltipParser() { const Parser = this.Parser; const tokenizers = Parser.prototype.inlineTokenizers; const methods = Parser.prototype.inlineMethods; const tokenizeTooltip: RemarkTokenizer = function tokenizeTooltip( eat, value, silent ) { if (value.startsWith('!{tooltip') === false) return false; const nextChar = value[9]; if (nextChar !== '[') return false; // this isn't actually a tooltip let index = 9; function readArg(open: string, close: string) { if (value[index] !== open) throw 'Expected left bracket'; index++; let body = ''; let openBrackets = 0; for (; index < value.length; index++) { const char = value[index]; if (char === close && openBrackets === 0) { index++; return body; } else if (char === close) { openBrackets--; } else if (char === open) { openBrackets++; } body += char; } return ''; } 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; } now.column += 10; now.offset += 10; const children = this.tokenizeInline(tooltipAnchor, now); return eat(`!{tooltip[${tooltipAnchor}](${tooltipText})}`)({ type: 'tooltipPlugin', content: tooltipText, children, } as TooltipNodeDetails); }; tokenizeTooltip.notInLink = true; tokenizeTooltip.locator = (value, fromIndex) => { return value.indexOf('!{tooltip', fromIndex); }; tokenizers.tooltip = tokenizeTooltip; methods.splice(methods.indexOf('text'), 0, 'tooltip'); }; const tooltipMarkdownRenderer: FunctionComponent< TooltipNodeDetails & { position: OuiMarkdownAstNodePosition; } > = ({ content, children }) => { return ( {children} ); }; export { tooltipPlugin as plugin, TooltipParser as parser, tooltipMarkdownRenderer as renderer, };