Skip to content

Commit

Permalink
Merge pull request #11338 from straight-shoota/feature/update-markd
Browse files Browse the repository at this point in the history
  • Loading branch information
straight-shoota committed Oct 20, 2021
2 parents d702e12 + 3c107f8 commit 120f0ab
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 59 deletions.
2 changes: 1 addition & 1 deletion lib/markd/.github/workflows/linux-ci.yml
Expand Up @@ -14,7 +14,7 @@ jobs:
strategy:
fail-fast: false
matrix:
crystal: [ '1.0.0', 'latest', 'nightly' ]
crystal: [ '1.0.0', '1.1.0', '1.2.0', 'latest', 'nightly' ]
name: Crystal ${{ matrix.crystal }} tests
steps:
- uses: actions/checkout@master
Expand Down
23 changes: 22 additions & 1 deletion lib/markd/CHANGELOG.md
Expand Up @@ -11,6 +11,24 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

- GFM support

## [0.4.2] (2021-10-19)

### Added

- Enable Table of Content (TOC) #[41](https://github.com/icyleaf/markd/pull/41) thanks @[Nephos](https://github.com/Nephos).

### Fixed

- Fix byte slice negative #[43](https://github.com/icyleaf/markd/pull/43).
- Compatibility with Crystal 1.2.

## [0.4.1] (2021-09-27)

### Added

- Refactor Options and change to a class #[36](https://github.com/icyleaf/markd/pull/36) thanks @[straight-shoota](https://github.com/straight-shoota).
- Add `lang` parameter to to `HTMLRenderer#code_block_body` #[38](https://github.com/icyleaf/markd/pull/38) thanks @[straight-shoota](https://github.com/straight-shoota).

## [0.4.0] (2021-03-23)

- Compatibility with Crystal 1.0. #[34](https://github.com/icyleaf/markd/pull/34) thanks @[bcardiff](https://github.com/bcardiff).
Expand Down Expand Up @@ -53,7 +71,10 @@ No changelog.

- [initial implementation](https://github.com/icyleaf/markd/milestone/1?closed=1)

[Unreleased]: https://github.com/icyleaf/markd/compare/v0.3.0...HEAD
[Unreleased]: https://github.com/icyleaf/markd/compare/v0.4.2...HEAD
[0.4.2]: https://github.com/icyleaf/halite/compare/v0.4.1...v0.4.2
[0.4.1]: https://github.com/icyleaf/halite/compare/v0.4.0...v0.4.1
[0.4.0]: https://github.com/icyleaf/halite/compare/v0.3.0...v0.4.0
[0.3.0]: https://github.com/icyleaf/halite/compare/v0.2.1...v0.3.0
[0.2.1]: https://github.com/icyleaf/halite/compare/v0.2.0...v0.2.1
[0.2.0]: https://github.com/icyleaf/halite/compare/v0.1.2...v0.2.0
Expand Down
4 changes: 2 additions & 2 deletions lib/markd/shard.yml
@@ -1,9 +1,9 @@
name: markd
version: 0.4.0
version: 0.4.2

authors:
- icyleaf <icyleaf.cn@gmail.com>

crystal: 1.0.0
crystal: ">= 0.36.1, < 2.0.0"

license: MIT
37 changes: 35 additions & 2 deletions lib/markd/src/markd/options.cr
@@ -1,8 +1,41 @@
require "uri"

module Markd
struct Options
property time, gfm, toc, smart, source_pos, safe, prettyprint
# Markdown rendering options.
class Options
property time, gfm, toc

# If `true`:
# - straight quotes will be made curly
# - `--` will be changed to an en dash
# - `---` will be changed to an em dash
# - `...` will be changed to ellipses
property? smart : Bool

@[Deprecated("Use `#smart?` instead.")]
getter smart

# If `true`, source position information for block-level elements
# will be rendered in the `data-sourcepos` attribute (for HTML).
property? source_pos : Bool

@[Deprecated("Use `#source_pos?` instead.")]
getter source_pos

# If `true`, raw HTML will not be passed through to HTML output
# (it will be replaced by comments).
property? safe : Bool

@[Deprecated("Use `#safe?` instead.")]
getter safe

# If `true`, code tags generated by code blocks will have a
# prettyprint class added to them, to be used by
# [Google code-prettify](https://github.com/google/code-prettify).
property? prettyprint : Bool

@[Deprecated("Use `#prettyprint?` instead.")]
getter prettyprint

# If `base_url` is not `nil`, it is used to resolve URLs of relative
# links. It act's like HTML's `<base href="base_url">` in the context
Expand Down
7 changes: 4 additions & 3 deletions lib/markd/src/markd/parsers/inline.cr
Expand Up @@ -43,7 +43,7 @@ module Markd::Parser
when '*', '_'
handle_delim(char, node)
when '\'', '"'
@options.smart && handle_delim(char, node)
@options.smart? && handle_delim(char, node)
when '['
open_bracket(node)
when '!'
Expand Down Expand Up @@ -226,7 +226,8 @@ module Markd::Parser
elsif !opener.bracket_after
# Empty or missing second label means to use the first label as the reference.
# The reference must not contain a bracket. If we know there's a bracket, we don't even bother checking it.
ref_label = normalize_refernence(@text.byte_slice(opener.index, start_pos - opener.index))
byte_count = start_pos - opener.index
ref_label = byte_count > 0 ? normalize_refernence(@text.byte_slice(opener.index, byte_count)) : nil
end

if label_size == 0
Expand Down Expand Up @@ -445,7 +446,7 @@ module Markd::Parser

private def string(node : Node)
if text = match_main
if @options.smart
if @options.smart?
text = text.gsub(Rule::ELLIPSIS, '\u{2026}')
.gsub(Rule::DASH) do |chars|
en_count = em_count = 0
Expand Down
45 changes: 31 additions & 14 deletions lib/markd/src/markd/renderers/html_renderer.cr
Expand Up @@ -12,7 +12,7 @@ module Markd
if entering
newline
tag(tag_name, attrs(node))
# toc(node) if @options.toc
toc(node) if @options.toc
else
tag(tag_name, end_tag: true)
newline
Expand All @@ -21,33 +21,46 @@ module Markd

def code(node : Node, entering : Bool)
tag("code") do
output(node.text)
code_body(node)
end
end

def code_body(node : Node)
output(node.text)
end

def code_block(node : Node, entering : Bool)
languages = node.fence_language ? node.fence_language.split : nil
code_tag_attrs = attrs(node)
pre_tag_attrs = if @options.prettyprint
pre_tag_attrs = if @options.prettyprint?
{"class" => "prettyprint"}
else
nil
end

if languages && languages.size > 0 && (lang = languages[0]) && !lang.empty?
lang = code_block_language(languages)
if lang
code_tag_attrs ||= {} of String => String
code_tag_attrs["class"] = "language-#{escape(lang.strip)}"
code_tag_attrs["class"] = "language-#{escape(lang)}"
end

newline
tag("pre", pre_tag_attrs) do
tag("code", code_tag_attrs) do
output(node.text)
code_block_body(node, lang)
end
end
newline
end

def code_block_language(languages)
languages.try(&.first?).try(&.strip.presence)
end

def code_block_body(node : Node, lang : String?)
output(node.text)
end

def thematic_break(node : Node, entering : Bool)
newline
tag("hr", attrs(node), self_closing: true)
Expand Down Expand Up @@ -97,7 +110,7 @@ module Markd
attrs = attrs(node)
destination = node.data["destination"].as(String)

unless @options.safe && potentially_unsafe(destination)
unless @options.safe? && potentially_unsafe(destination)
attrs ||= {} of String => String
destination = resolve_uri(destination, node)
attrs["href"] = escape(destination)
Expand Down Expand Up @@ -128,7 +141,7 @@ module Markd
if entering
if @disable_tag == 0
destination = node.data["destination"].as(String)
if @options.safe && potentially_unsafe(destination)
if @options.safe? && potentially_unsafe(destination)
literal(%(<img src="" alt=""))
else
destination = resolve_uri(destination, node)
Expand All @@ -149,13 +162,13 @@ module Markd

def html_block(node : Node, entering : Bool)
newline
content = @options.safe ? "<!-- raw HTML omitted -->" : node.text
content = @options.safe? ? "<!-- raw HTML omitted -->" : node.text
literal(content)
newline
end

def html_inline(node : Node, entering : Bool)
content = @options.safe ? "<!-- raw HTML omitted -->" : node.text
content = @options.safe? ? "<!-- raw HTML omitted -->" : node.text
literal(content)
end

Expand Down Expand Up @@ -222,14 +235,18 @@ module Markd
private def toc(node : Node)
return unless node.type.heading?

title = URI.encode(node.text)

@output_io << %(<a id="anchor-) << title << %(" class="anchor" href="#) << title %("></a>)
{% if Crystal::VERSION < "1.2.0" %}
title = URI.encode(node.first_child.text)
@output_io << %(<a id="anchor-) << title << %(" class="anchor" href="#anchor-) << title << %("></a>)
{% else %}
title = URI.encode_path(node.first_child.text)
@output_io << %(<a id="anchor-) << title << %(" class="anchor" href="#anchor-) << title << %("></a>)
{% end %}
@last_output = ">"
end

private def attrs(node : Node)
if @options.source_pos && (pos = node.source_pos)
if @options.source_pos? && (pos = node.source_pos)
{"data-source-pos" => "#{pos[0][0]}:#{pos[0][1]}-#{pos[1][0]}:#{pos[1][1]}"}
else
nil
Expand Down
2 changes: 1 addition & 1 deletion lib/markd/src/markd/version.cr
@@ -1,3 +1,3 @@
module Markd
VERSION = "0.4.0"
VERSION = "0.4.2"
end
50 changes: 15 additions & 35 deletions src/compiler/crystal/tools/doc/markd_doc_renderer.cr
Expand Up @@ -44,13 +44,11 @@ class Crystal::Doc::MarkdDocRenderer < Markd::HTMLRenderer
end
end

def code(node : Markd::Node, entering : Bool)
tag("code") do
if in_link?(node)
output(node.text)
else
literal(expand_code_links(node.text))
end
def code_body(node : Markd::Node)
if in_link?(node)
output(node.text)
else
literal(expand_code_links(node.text))
end
end

Expand Down Expand Up @@ -115,39 +113,21 @@ class Crystal::Doc::MarkdDocRenderer < Markd::HTMLRenderer
end
end

def code_block(node : Markd::Node, entering : Bool)
languages = node.fence_language ? node.fence_language.split : nil
code_tag_attrs = attrs(node)
pre_tag_attrs = if @options.prettyprint
{"class" => "prettyprint"}
else
nil
end

language = languages.try &.first?.try &.strip
language = nil if language.try &.empty?

def code_block_language(languages)
language = languages.try(&.first?).try(&.strip.presence)
if language.nil? || language == "cr"
language = "crystal"
end
language
end

if language
code_tag_attrs ||= {} of String => String
code_tag_attrs["class"] = "language-#{escape(language)}"
end

newline
tag("pre", pre_tag_attrs) do
tag("code", code_tag_attrs) do
code = node.text.chomp
if language == "crystal"
literal(Highlighter.highlight code)
else
output(code)
end
end
def code_block_body(node : Markd::Node, language : String?)
code = node.text.chomp
if language == "crystal"
literal(Highlighter.highlight code)
else
output(code)
end
newline
end

private def type_link(type, text)
Expand Down

0 comments on commit 120f0ab

Please sign in to comment.