Skip to content

Commit

Permalink
Add the ability to change slide symbols displayed in the terminal output
Browse files Browse the repository at this point in the history
  • Loading branch information
piotrmurach committed Nov 20, 2022
1 parent d7be72c commit 51be475
Show file tree
Hide file tree
Showing 13 changed files with 233 additions and 50 deletions.
7 changes: 5 additions & 2 deletions lib/slideck/converter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,17 @@ def initialize(markdown_parser, color: nil)
#
# @param [String] content
# the content to convert
# @param [Hash{Symbol => String, Symbol}, Symbol] symbols
# the converted content symbols
# @param [Integer] width
# the slide width
#
# @return [String]
#
# @api public
def convert(content, width: nil)
@markdown_parser.parse(content, color: @color, width: width)
def convert(content, symbols: nil, width: nil)
@markdown_parser.parse(
content, color: @color, symbols: symbols, width: width)
end
end # Converter
end # Slideck
5 changes: 5 additions & 0 deletions lib/slideck/metadata.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ def self.define_meta(key)
# @return [Hash{Symbol => Slideck::Alignment,String}]
define_meta :pager

# The symbols configuration
#
# @return [Hash{Symbol => String, Symbol}, Symbol]
define_meta :symbols

# Create a Metadata instance
#
# @param [Hash{Symbol => Object}] metadata
Expand Down
4 changes: 3 additions & 1 deletion lib/slideck/metadata_converter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def convert(custom_metadata)
# @param [Object] value
# the metadata value
#
# @return [Hash, Slideck::Alignment, Slideck::Margin]
# @return [Hash, Slideck::Alignment, Slideck::Margin, Symbol]
#
# @api private
def convert_for(key, value)
Expand All @@ -58,6 +58,8 @@ def convert_for(key, value)
@margin.from(value)
when :footer, :pager
convert_align_key(wrap_with_text_key(value), "bottom")
else
value
end
end

Expand Down
3 changes: 2 additions & 1 deletion lib/slideck/metadata_defaults.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ def create_defaults
align: @alignment["left", "top"],
footer: default_footer,
margin: @margin[0, 0, 0, 0],
pager: default_pager
pager: default_pager,
symbols: :unicode
}.freeze
end

Expand Down
54 changes: 36 additions & 18 deletions lib/slideck/renderer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ def clear
#
# @api private
def render_content(slide)
alignment = slide[:metadata].align || @metadata.align
margin = slide[:metadata].margin || @metadata.margin
converted = convert_markdown(slide[:content], margin)
alignment, margin, symbols =
*select_metadata(slide[:metadata], :align, :margin, :symbols)
converted = convert_markdown(slide[:content], margin, symbols)

render_section(converted.lines, alignment, margin)
end
Expand All @@ -103,13 +103,12 @@ def render_content(slide)
#
# @api private
def render_footer(slide_metadata)
footer_metadata = slide_metadata && slide_metadata.footer
footer_metadata ||= @metadata.footer
footer_metadata = pick_metadata(slide_metadata, :footer)
return if (text = footer_metadata[:text]).empty?

alignment = footer_metadata[:align] || @metadata.footer[:align]
margin = slide_margin(slide_metadata)
converted = convert_markdown(text, margin).chomp
margin, symbols = *select_metadata(slide_metadata, :margin, :symbols)
converted = convert_markdown(text, margin, symbols).chomp

render_section(converted.lines, alignment, margin)
end
Expand All @@ -127,29 +126,46 @@ def render_footer(slide_metadata)
#
# @api private
def render_pager(slide_metadata, current_num, num_of_slides)
pager_metadata = slide_metadata && slide_metadata.pager
pager_metadata ||= @metadata.pager
pager_metadata = pick_metadata(slide_metadata, :pager)
return if (text = pager_metadata[:text]).empty?

alignment = pager_metadata[:align] || @metadata.pager[:align]
margin = slide_margin(slide_metadata)
margin, symbols = *select_metadata(slide_metadata, :margin, :symbols)
formatted_text = format(text, page: current_num, total: num_of_slides)
converted = convert_markdown(formatted_text, margin).chomp
converted = convert_markdown(formatted_text, margin, symbols).chomp

render_section(converted.lines, alignment, margin)
end

# Select slide margin from metadata
# Select configuration(s) by name(s) from metadata
#
# @param [Slideck::Metadata] slide_metadata
# the slide metadata
# @param [Array<Symbol>] names
# the configuration names
#
# @return [Slideck::Margin]
# @return [Array<Object>]
#
# @api private
def slide_margin(slide_metadata)
slide_margin = slide_metadata && slide_metadata.margin
slide_margin || @metadata.margin
def select_metadata(slide_metadata, *names)
names.each_with_object([]) do |name, selected|
selected << pick_metadata(slide_metadata, name)
end
end

# Pick configuration by name from metadata
#
# @param [Slideck::Metadata] slide_metadata
# the slide metadata
# @param [Symbol] name
# the configuration name
#
# @return [Object]
#
# @api private
def pick_metadata(slide_metadata, name)
metadata_item = slide_metadata && slide_metadata.send(name)
metadata_item || @metadata.send(name)
end

# Render section with aligned lines
Expand Down Expand Up @@ -226,12 +242,14 @@ def find_top_row(alignment, margin, num_of_lines)
# the content to convert to terminal output
# @param [Slideck::Margin] margin
# the slide margin
# @param [Hash{Symbol => String, Symbol}, Symbol] symbols
# the converted content symbols
#
# @return [String]
#
# @api private
def convert_markdown(content, margin)
@converter.convert(content, width: slide_width(margin))
def convert_markdown(content, margin, symbols)
@converter.convert(content, symbols: symbols, width: slide_width(margin))
end

# Find maximum line length
Expand Down
5 changes: 5 additions & 0 deletions spec/fixtures/slides.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@ align: center
footer: "**footer content**"
margin: 1 2
pager: "page %<page>d of %<total>d"
symbols: :ascii
---

# Title

- Item 1
- Item 2
- Item 3

--- align: left

Slide 1
Expand Down
18 changes: 14 additions & 4 deletions spec/unit/converter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,24 @@
it "converts markdown title to terminal output" do
converter = described_class.new(markdown_parser, color: true)

converted = converter.convert("# Title", width: 20)
converted = converter.convert("# Title", symbols: :unicode, width: 20)

expect(converted).to eq("\e[36;1;4mTitle\e[0m\n")
end

it "converts markdown title to terminal output without color" do
converter = described_class.new(markdown_parser, color: false)

converted = converter.convert("# Title", width: 20)
converted = converter.convert("# Title", symbols: :unicode, width: 20)

expect(converted).to eq("Title\n")
end

it "converts markdown title limited by slide width" do
converter = described_class.new(markdown_parser, color: true)

converted = converter.convert("# Very Long Title", width: 10)
converted = converter.convert("# Very Long Title", symbols: :unicode,
width: 10)

expect(converted).to eq([
"\e[36;1;4mVery Long \e[0m\n",
Expand All @@ -33,11 +34,20 @@
it "converts markdown title limited by slide width and without color" do
converter = described_class.new(markdown_parser, color: false)

converted = converter.convert("# Very Long Title", width: 10)
converted = converter.convert("# Very Long Title", symbols: :unicode,
width: 10)

expect(converted).to eq([
"Very Long \n",
"Title\n"
].join)
end

it "converts a markdown list to terminal output with ascii symbols" do
converter = described_class.new(markdown_parser, color: true)

converted = converter.convert("- list item", symbols: :ascii, width: 20)

expect(converted).to eq("\e[33m*\e[0m list item\n")
end
end
12 changes: 12 additions & 0 deletions spec/unit/metadata_converter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,16 @@
}
})
end

it "doesn't convert :symbols value" do
converter = described_class.new(alignment, margin)

converted = converter.convert({
symbols: {base: :ascii, override: {bullet: "x"}}
})

expect(converted).to eq({
symbols: {base: :ascii, override: {bullet: "x"}}
})
end
end
15 changes: 10 additions & 5 deletions spec/unit/metadata_defaults_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
pager: {
align: alignment["right", "bottom"],
text: "%<page>d / %<total>d"
}
},
symbols: :unicode
})
end

Expand All @@ -33,7 +34,8 @@
margin: margin[1, 2, 3, 4],
pager: {
text: "%<page>d of %<total>d"
}
},
symbols: :ascii
})

expect(merged).to eq({
Expand All @@ -46,7 +48,8 @@
pager: {
align: alignment["right", "bottom"],
text: "%<page>d of %<total>d"
}
},
symbols: :ascii
})
end

Expand All @@ -61,7 +64,8 @@
margin: margin[1, 2, 3, 4],
pager: {
align: alignment["right", "top"]
}
},
symbols: :ascii
})

expect(merged).to eq({
Expand All @@ -74,7 +78,8 @@
pager: {
align: alignment["right", "top"],
text: "%<page>d / %<total>d"
}
},
symbols: :ascii
})
end
end
17 changes: 16 additions & 1 deletion spec/unit/metadata_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -230,13 +230,28 @@
expect(metadata.pager?).to eq(true)
end

it "defaults :symbols to :unicode" do
metadata = described_class.from(converter, {}, defaults)

expect(metadata.symbols).to eq(:unicode)
end

it "creates metadata from :symbols with an :ascii value" do
config = {symbols: :ascii}

metadata = described_class.from(converter, config, defaults)

expect(metadata.symbols).to eq(:ascii)
end

it "raises when invalid metadata key" do
config = {invalid: ""}

expect {
described_class.from(converter, config, defaults)
}.to raise_error(Slideck::InvalidMetadataKeyError,
"unknown 'invalid' configuration key\n" \
"Available keys are: :align, :footer, :margin, :pager")
"Available keys are: :align, :footer, :margin, " \
":pager, :symbols")
end
end
16 changes: 12 additions & 4 deletions spec/unit/parser_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
footer: footer content
margin: 2
pager: "page %<page>d of %<total>d"
symbols: :ascii
EOS
parser = described_class.new(StringScanner, metadata_parser)

Expand All @@ -89,7 +90,8 @@
align: "center",
footer: "footer content",
margin: 2,
pager: "page %<page>d of %<total>d"
pager: "page %<page>d of %<total>d",
symbols: :ascii
},
slides: []
})
Expand All @@ -101,6 +103,7 @@
:footer: footer content
:margin: 2
:pager: "page %<page>d of %<total>d"
:symbols: :ascii
EOS
parser = described_class.new(StringScanner, metadata_parser)

Expand All @@ -111,7 +114,8 @@
align: "center",
footer: "footer content",
margin: 2,
pager: "page %<page>d of %<total>d"
pager: "page %<page>d of %<total>d",
symbols: :ascii
},
slides: []
})
Expand All @@ -123,6 +127,7 @@
footer: footer content
margin: [1, 2]
pager: "page %<page>d of %<total>d"
symbols: :ascii
---
# Slide 1
---
Expand All @@ -139,7 +144,8 @@
align: "center",
footer: "footer content",
margin: [1, 2],
pager: "page %<page>d of %<total>d"
pager: "page %<page>d of %<total>d",
symbols: :ascii
},
slides: [
{content: "# Slide 1", metadata: {}},
Expand All @@ -156,6 +162,7 @@
footer: footer content
margin: {top: 1, left: 2}
pager: "page %<page>d of %<total>d"
symbols: :ascii
---
# Slide 1
---
Expand All @@ -173,7 +180,8 @@
align: "center",
footer: "footer content",
margin: {top: 1, left: 2},
pager: "page %<page>d of %<total>d"
pager: "page %<page>d of %<total>d",
symbols: :ascii
},
slides: [
{content: "# Slide 1", metadata: {}},
Expand Down
Loading

0 comments on commit 51be475

Please sign in to comment.