# frozen_string_literal: true class TiptapService # NOTE: node must be deep symbolized keys def self.used_tags_and_libelle_for(node, tags = Set.new) case node in type: 'mention', attrs: { id:, label: }, **rest tags << [id, label] in { content:, **rest } if content.is_a?(Array) content.each { used_tags_and_libelle_for(_1, tags) } in type:, **rest # noop end tags end def to_html(node, substitutions = {}) return '' if node.nil? children(node[:content], substitutions, 0).gsub('
', '') end def to_texts_and_tags(node, substitutions = {}) return '' if node.nil? children_texts_and_tags(node[:content], substitutions) end private def initialize @body_started = false end def children_texts_and_tags(content, substitutions) content.map { node_to_texts_and_tags(_1, substitutions) }.join end def node_to_texts_and_tags(node, substitutions) case node in type: 'paragraph', content: children_texts_and_tags(content, substitutions) in type: 'paragraph' # empty paragraph '' in type: 'text', text: text.strip in type: 'mention', attrs: { id:, label: } if substitutions.present? substitutions.fetch(id) { "--#{id}--" } else "#{label}" end end end def children(content, substitutions, level) content.map { node_to_html(_1, substitutions, level) }.join end def node_to_html(node, substitutions, level) if level == 0 && !@body_started && node[:type].in?(['paragraph', 'heading']) && node.key?(:content) @body_started = true body_start_mark = " class=\"body-start\"" end case node in type: 'header', content: "#{children(content, substitutions, level + 1)}
" in type: 'title', content:, **rest ""
else
content
end
end
def text_align(attrs)
if attrs.present? && attrs[:textAlign].present?
" style=\"text-align: #{attrs[:textAlign]}\""
else
""
end
end
def class_list(attrs)
if attrs.present? && attrs[:class].present?
" class=\"#{attrs[:class]}\""
end
end
def apply_marks(text, marks)
marks.reduce(text) do |text, mark|
case mark
in type: 'bold'
"#{text}"
in type: 'italic'
"#{text}"
in type: 'underline'
"#{text}"
in type: 'strike'
"#{text}"
in type: 'highlight'
"#{text}"
end
end
end
end