func secondPass(lines []string) string {
	var (
		out     strings.Builder
		lineNum int
	)

	for lineNum < len(lines) {
		line := lines[lineNum]
		tokens := tokenize(line)

		if len(tokens) == 0 {
			out.WriteString(line)

			lineNum++
			if lineNum < len(lines)-1 {
				out.WriteRune(newLine)
			}
			continue
		}

		var beg int

	out:
		for beg < len(line) {
			end := beg

			if token, ok := tokenStarts(beg, tokens); ok {
				switch token.family {
				case typeTagTextEffect:
					end = token.handleTextEffects(line, &out)
				case typeTagHeading:
					end = token.handleHeadings(line, &out)
				case typeTagInlineQuote:
					end = token.handleInlineBlockQuote(line, &out)
				case typeTagList:
					end = token.handleList(line, &out)
				case typeTagFencedCode:
					lineNum = token.handleFencedCodeBlock(lineNum, lines, &out)
					break out
				case typeTagReferenceLink:
					end = token.handleReferenceLink(line, &out)
				case typeTagTable:
					end = token.handleTable(line, &out)
				case typeTagOther:
					if token.tag == TagQuote {
						// If end is same as size of the input, it implies that
						// we've found a closing token, and we will ignore it.
						if token.endIdx != len(line)-1 {
							out.WriteString(fmt.Sprintf("\n%s", replacements[token.tag]))
						}
					} else {
						out.WriteString(fmt.Sprintf("\n%s", replacements[token.tag]))
					}

					if token.tag == TagPanel {
						if t, ok := token.attrs[attrTitle]; ok {
							out.WriteString(fmt.Sprintf("\n**%s**\n", t))
						}

						if token.endIdx != len(line)-1 {
							out.WriteRune(newLine)
						}
					}

					end = token.endIdx
				}
			} else {
				out.WriteRune(rune(line[beg]))
			}

			end++
			beg = end
		}

		lineNum++
		out.WriteRune(newLine)
	}

	return out.String()
}
/*
	Second pass: actual rendering.
		- Process each line to search and mark tags.
		- Use replacements to prepare markdown.
*/
Second pass: actual rendering.
Process each line to search and mark tags.
Use replacements to prepare markdown.
/ * Second pass : actual rendering . - Process each line to search and mark tags . - Use replacements to prepare markdown . * /
func secondPass(lines []string) string {
	var (
		out     strings.Builder
		lineNum int
	)
	for lineNum < len(lines) {
		line := lines[lineNum]
		tokens := tokenize(line)
		if len(tokens) == 0 {
			out.WriteString(line)
			lineNum++
			if lineNum < len(lines)-1 {
				out.WriteRune(newLine)
			}
			continue
		}
		var beg int
	out:
		for beg < len(line) {
			end := beg
			if token, ok := tokenStarts(beg, tokens); ok {
				switch token.family {
				case typeTagTextEffect:
					end = token.handleTextEffects(line, &out)
				case typeTagHeading:
					end = token.handleHeadings(line, &out)
				case typeTagInlineQuote:
					end = token.handleInlineBlockQuote(line, &out)
				case typeTagList:
					end = token.handleList(line, &out)
				case typeTagFencedCode:
					lineNum = token.handleFencedCodeBlock(lineNum, lines, &out)
					break out
				case typeTagReferenceLink:
					end = token.handleReferenceLink(line, &out)
				case typeTagTable:
					end = token.handleTable(line, &out)
				case typeTagOther:
					if token.tag == TagQuote {
						if token.endIdx != len(line)-1 {
							out.WriteString(fmt.Sprintf("\n%s", replacements[token.tag]))
						}
					} else {
						out.WriteString(fmt.Sprintf("\n%s", replacements[token.tag]))
					}
					if token.tag == TagPanel {
						if t, ok := token.attrs[attrTitle]; ok {
							out.WriteString(fmt.Sprintf("\n**%s**\n", t))
						}
						if token.endIdx != len(line)-1 {
							out.WriteRune(newLine)
						}
					}
					end = token.endIdx
				}
			} else {
				out.WriteRune(rune(line[beg]))
			}
			end++
			beg = end
		}
		lineNum++
		out.WriteRune(newLine)
	}
	return out.String()
}
func secondPass ( lines [ ] string ) string { var ( out strings . Builder lineNum int ) for lineNum < len ( lines ) { line := lines [ lineNum ] tokens := tokenize ( line ) if len ( tokens ) == 0 { out . WriteString ( line ) lineNum ++ if lineNum < len ( lines ) - 1 { out . WriteRune ( newLine ) } continue } var beg int out : for beg < len ( line ) { end := beg if token , ok := tokenStarts ( beg , tokens ) ; ok { switch token . family { case typeTagTextEffect : end = token . handleTextEffects ( line , & out ) case typeTagHeading : end = token . handleHeadings ( line , & out ) case typeTagInlineQuote : end = token . handleInlineBlockQuote ( line , & out ) case typeTagList : end = token . handleList ( line , & out ) case typeTagFencedCode : lineNum = token . handleFencedCodeBlock ( lineNum , lines , & out ) break out case typeTagReferenceLink : end = token . handleReferenceLink ( line , & out ) case typeTagTable : end = token . handleTable ( line , & out ) case typeTagOther : if token . tag == TagQuote { if token . endIdx != len ( line ) - 1 { out . WriteString ( fmt . Sprintf ( " \n " , replacements [ token . tag ] ) ) } } else { out . WriteString ( fmt . Sprintf ( " \n " , replacements [ token . tag ] ) ) } if token . tag == TagPanel { if t , ok := token . attrs [ attrTitle ] ; ok { out . WriteString ( fmt . Sprintf ( " \n \n " , t ) ) } if token . endIdx != len ( line ) - 1 { out . WriteRune ( newLine ) } } end = token . endIdx } } else { out . WriteRune ( rune ( line [ beg ] ) ) } end ++ beg = end } lineNum ++ out . WriteRune ( newLine ) } return out . String ( ) }
Second pass: actual rendering.
Second pass : actual rendering .
// If end is same as size of the input, it implies that // we've found a closing token, and we will ignore it.