diff options
Diffstat (limited to 'app/assets/javascripts/vue_shared/components/rich_content_editor/services/build_html_to_markdown_renderer.js')
-rw-r--r-- | app/assets/javascripts/vue_shared/components/rich_content_editor/services/build_html_to_markdown_renderer.js | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/app/assets/javascripts/vue_shared/components/rich_content_editor/services/build_html_to_markdown_renderer.js b/app/assets/javascripts/vue_shared/components/rich_content_editor/services/build_html_to_markdown_renderer.js new file mode 100644 index 00000000000..ed04765c871 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/rich_content_editor/services/build_html_to_markdown_renderer.js @@ -0,0 +1,53 @@ +import { defaults, repeat } from 'lodash'; + +const DEFAULTS = { + subListIndentSpaces: 4, +}; + +const countIndentSpaces = text => { + const matches = text.match(/^\s+/m); + + return matches ? matches[0].length : 0; +}; + +const buildHTMLToMarkdownRender = (baseRenderer, formattingPreferences = {}) => { + const { subListIndentSpaces } = defaults(formattingPreferences, DEFAULTS); + // eslint-disable-next-line @gitlab/require-i18n-strings + const sublistNode = 'LI OL, LI UL'; + + return { + TEXT_NODE(node) { + return baseRenderer.getSpaceControlled( + baseRenderer.trim(baseRenderer.getSpaceCollapsedText(node.nodeValue)), + node, + ); + }, + /* + * This converter overwrites the default indented list converter + * to allow us to parameterize the number of indent spaces for + * sublists. + * + * See the original implementation in + * https://github.com/nhn/tui.editor/blob/master/libs/to-mark/src/renderer.basic.js#L161 + */ + [sublistNode](node, subContent) { + const baseResult = baseRenderer.convert(node, subContent); + // Default to 1 to prevent possible divide by 0 + const firstLevelIndentSpacesCount = countIndentSpaces(baseResult) || 1; + const reindentedList = baseResult + .split('\n') + .map(line => { + const itemIndentSpacesCount = countIndentSpaces(line); + const nestingLevel = Math.ceil(itemIndentSpacesCount / firstLevelIndentSpacesCount); + const indentSpaces = repeat(' ', subListIndentSpaces * nestingLevel); + + return line.replace(/^ +/, indentSpaces); + }) + .join('\n'); + + return reindentedList; + }, + }; +}; + +export default buildHTMLToMarkdownRender; |