Class: MarkupStyleRender

Inherits:
Object
  • Object
show all
Defined in:
lib/Parsers/MarkupStyleRender.rb

Overview

Renders a Paragraph’s text + Markup list into final markdown.

Pipeline:

1. Build a position-indexed `chars` map of the paragraph text. Emoji
   and other 4-byte chars occupy two slots, mirroring Medium's own
   paragraph index space — this is what `markup.start` / `markup.end`
   reference.
2. Convert each Markup into a TagChar (start/end positions + start/end
   strings to emit, plus a `sort` priority for nesting).
3. Walk every position, emitting tag-open / char / tag-close in order,
   with a stack to track nesting and to handle line breaks (close
   every open tag at the `\n`, then reopen on the next line) and
   mismatched-end ordering.
4. Optimize the resulting char stream:
     - Strip nested style tags inside ` ` code spans (markdown forbids).
     - Flatten ESCAPE tags (start `\`, empty end) into literal `\` text.
     - Tighten spacing around tags (no whitespace just inside a tag,
       and a space after a closing tag if text follows).

Defined Under Namespace

Classes: TagChar, TextChar

Constant Summary collapse

URL_REGEX =

URL pattern that anchor markups must match before we emit a link. Anything weirder (mailto:, javascript:, relative paths) is dropped rather than rendered with broken syntax.

/\A(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,6}(:[0-9]{1,5})?(\/.*)?\z/ix.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(paragraph, isForJekyll) ⇒ MarkupStyleRender

Returns a new instance of MarkupStyleRender.



52
53
54
55
56
# File 'lib/Parsers/MarkupStyleRender.rb', line 52

def initialize(paragraph, isForJekyll)
    @paragraph = paragraph
    @isForJekyll = isForJekyll
    @chars = buildCharIndex(paragraph.text)
end

Instance Attribute Details

#charsObject

Returns the value of attribute chars.



23
24
25
# File 'lib/Parsers/MarkupStyleRender.rb', line 23

def chars
  @chars
end

#encodeTypeObject

Returns the value of attribute encodeType.



23
24
25
# File 'lib/Parsers/MarkupStyleRender.rb', line 23

def encodeType
  @encodeType
end

#isForJekyllObject

Returns the value of attribute isForJekyll.



23
24
25
# File 'lib/Parsers/MarkupStyleRender.rb', line 23

def isForJekyll
  @isForJekyll
end

#paragraphObject

Returns the value of attribute paragraph.



23
24
25
# File 'lib/Parsers/MarkupStyleRender.rb', line 23

def paragraph
  @paragraph
end

#usersPostURLsObject

Returns the value of attribute usersPostURLs.



23
24
25
# File 'lib/Parsers/MarkupStyleRender.rb', line 23

def usersPostURLs
  @usersPostURLs
end

Instance Method Details

#optimize(response) ⇒ Object

Public for backwards compat / unit tests; the parse pipeline drives it.



71
72
73
74
75
76
# File 'lib/Parsers/MarkupStyleRender.rb', line 71

def optimize(response)
    stripStylesInsideCodeSpans(response)
    flattenEscapeTagsToText(response)
    tightenSpacingAroundTags(response)
    response
end

#parseObject



58
59
60
61
62
63
64
65
66
67
68
# File 'lib/Parsers/MarkupStyleRender.rb', line 58

def parse
    if paragraph.markups.nil? || paragraph.markups.empty?
        response = chars.values
    else
        tags = buildTags(paragraph.markups).sort_by(&:startIndex)
        response = walkCharsWithTags(tags)
    end

    optimize(response)
    response.map { |c| c.chars }.join
end