# frozen_string_literal: true require 'cgi' require 'date' require 'forwardable' require 'open3' require 'pathname' require 'uri' require 'yaml' require 'addressable' require_relative 'repubmark/config' require_relative 'repubmark/highlight' require_relative 'repubmark/titled_ref' require_relative 'repubmark/elems/base' # Top-level element require_relative 'repubmark/elems/article' # Always inside Article require_relative 'repubmark/elems/annotation' require_relative 'repubmark/elems/footnotes_category' # Always inside Article, Chapter require_relative 'repubmark/elems/chapter' # Always inside Annotation, Blockquote, Chapter require_relative 'repubmark/elems/canvas' # Always inside Canvas require_relative 'repubmark/elems/blockquote' require_relative 'repubmark/elems/code_block' require_relative 'repubmark/elems/figures' require_relative 'repubmark/elems/iframe' require_relative 'repubmark/elems/paragraph' require_relative 'repubmark/elems/separator' # Always inside Canvas, Figures require_relative 'repubmark/elems/figure' # Always inside Canvas, ListItem require_relative 'repubmark/elems/list' # Always inside List require_relative 'repubmark/elems/list_item' # Always inside Caption, Quote require_relative 'repubmark/elems/joint' # Always inside Blockquote, Figure, Footnote, ListItem, Paragraph require_relative 'repubmark/elems/caption' # Always inside Caption, Joint, Quote require_relative 'repubmark/elems/quote' # Always inside Joint require_relative 'repubmark/elems/abbrev' require_relative 'repubmark/elems/code_inline' require_relative 'repubmark/elems/fraction' require_relative 'repubmark/elems/note' require_relative 'repubmark/elems/section' require_relative 'repubmark/elems/special' require_relative 'repubmark/elems/text' require_relative 'repubmark/elems/link' require_relative 'repubmark/elems/power' # Always inside FootnotesCategory require_relative 'repubmark/elems/footnote' ## # A Markdown-inspired markup language that can be compiled into HTML and # Gemtext. # module Repubmark FORMATS = %i[chapters gemtext html summary_plain word_count].freeze SLUG_RE = /\A[[:word:]]+(-[[:word:]]+)*\z/ UNICODE_SUPS = { '0' => '⁰', '1' => '¹', '2' => '²', '3' => '³', '4' => '⁴', '5' => '⁵', '6' => '⁶', '7' => '⁷', '8' => '⁸', '9' => '⁹', '+' => '⁺', '-' => '⁻', '=' => '⁼', '(' => '⁽', ')' => '⁾', }.freeze UNICODE_SUBS = { '0' => '₀', '1' => '₁', '2' => '₂', '3' => '₃', '4' => '₄', '5' => '₅', '6' => '₆', '7' => '₇', '8' => '₈', '9' => '₉', '+' => '₊', '-' => '₋', '=' => '₌', '(' => '₍', ')' => '₎', }.freeze def self.validate_slug!(slug) slug = String(slug).freeze raise 'Invalid slug' unless SLUG_RE.match? slug slug end def self.unicode_sup(val) String(val).each_char.map { |chr| UNICODE_SUPS.fetch chr }.join.freeze end def self.unicode_sub(val) String(val).each_char.map { |chr| UNICODE_SUBS.fetch chr }.join.freeze end end