import { GetStaticProps } from "next"; import { useCallback, useMemo, useRef, useState } from "react"; import TurndownService from "turndown"; import { AppLayout, AppLayoutRequired } from "components/AppLayout"; import { Button } from "components/Inputs/Button"; import { Markdawn, TableOfContents } from "components/Markdown/Markdawn"; import { ContentPanel, ContentPanelWidthSizes } from "components/Panels/ContentPanel"; import { Popup } from "components/Popup"; import { ToolTip } from "components/ToolTip"; import { Icon } from "components/Ico"; import { getOpenGraph } from "helpers/openGraph"; import { getLangui } from "graphql/fetchLocalData"; /* * ╭────────╮ * ──────────────────────────────────────────╯ PAGE ╰───────────────────────────────────────────── */ interface Props extends AppLayoutRequired {} const Editor = (props: Props): JSX.Element => { const handleInput = useCallback((text: string) => { setMarkdown(text); }, []); const [markdown, setMarkdown] = useState(""); const [converterOpened, setConverterOpened] = useState(false); const textAreaRef = useRef(null); const transformationWrapper = useCallback( ( transformation: ( value: string, selectionStart: number, selectedEnd: number ) => { prependLength: number; transformedValue: string } ) => { if (textAreaRef.current) { const { value, selectionStart, selectionEnd } = textAreaRef.current; const { prependLength, transformedValue } = transformation( value, selectionStart, selectionEnd ); textAreaRef.current.value = transformedValue; handleInput(textAreaRef.current.value); textAreaRef.current.focus(); textAreaRef.current.selectionStart = selectionStart + prependLength; textAreaRef.current.selectionEnd = selectionEnd + prependLength; } }, [handleInput] ); const wrap = useCallback( (wrapper: string, properties?: Record, addInnerNewLines?: boolean) => { transformationWrapper((value, selectionStart, selectionEnd) => { let prepend = wrapper; let append = wrapper; if (properties) { prepend = `<${wrapper}${Object.entries(properties).map( ([propertyName, propertyValue]) => ` ${propertyName}="${propertyValue}"` )}>`; append = ``; } if (addInnerNewLines === true) { prepend = `${prepend}\n`; append = `\n${append}`; } let newValue = ""; newValue += value.slice(0, selectionStart); newValue += prepend; newValue += value.slice(selectionStart, selectionEnd); newValue += append; newValue += value.slice(selectionEnd); return { prependLength: prepend.length, transformedValue: newValue }; }); }, [transformationWrapper] ); const unwrap = useCallback( (wrapper: string) => { transformationWrapper((value, selectionStart, selectionEnd) => { let newValue = ""; newValue += value.slice(0, selectionStart - wrapper.length); newValue += value.slice(selectionStart, selectionEnd); newValue += value.slice(wrapper.length + selectionEnd); return { prependLength: -wrapper.length, transformedValue: newValue }; }); }, [transformationWrapper] ); const toggleWrap = useCallback( (wrapper: string, properties?: Record, addInnerNewLines?: boolean) => { if (textAreaRef.current) { const { value, selectionStart, selectionEnd } = textAreaRef.current; if ( value.slice(selectionStart - wrapper.length, selectionStart) === wrapper && value.slice(selectionEnd, selectionEnd + wrapper.length) === wrapper ) { unwrap(wrapper); } else { wrap(wrapper, properties, addInnerNewLines); } } }, [unwrap, wrap] ); const preline = useCallback( (prepend: string) => { transformationWrapper((value, selectionStart) => { const lastNewLine = value.slice(0, selectionStart).lastIndexOf("\n") + 1; let newValue = ""; newValue += value.slice(0, lastNewLine); newValue += prepend; newValue += value.slice(lastNewLine); return { prependLength: prepend.length, transformedValue: newValue }; }); }, [transformationWrapper] ); const insert = useCallback( (prepend: string) => { transformationWrapper((value, selectionStart) => { let newValue = ""; newValue += value.slice(0, selectionStart); newValue += prepend; newValue += value.slice(selectionStart); return { prependLength: prepend.length, transformedValue: newValue }; }); }, [transformationWrapper] ); const appendDoc = useCallback( (append: string) => { transformationWrapper((value) => { const newValue = value + append; return { prependLength: 0, transformedValue: newValue }; }); }, [transformationWrapper] ); const contentPanel = useMemo( () => ( setConverterOpened(false)} state={converterOpened}>

Convert HTML to markdown

Copy and paste any HTML content (content from web pages) here.
The text will immediatly be converted to valid Markdown.
You can then copy the converted text and paste it anywhere you want in the editor