Skip to content

Commit

Permalink
Add a way to change a slide theme displayed in the terminal output
Browse files Browse the repository at this point in the history
  • Loading branch information
piotrmurach committed Dec 24, 2022
1 parent c52d661 commit 7c12857
Show file tree
Hide file tree
Showing 12 changed files with 183 additions and 36 deletions.
6 changes: 4 additions & 2 deletions lib/slideck/converter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,17 @@ def initialize(markdown_parser, color: nil)
# the content to convert
# @param [Hash, String, Symbol] symbols
# the converted content symbols
# @param [Hash{Symbol => Array, String, Symbol}] theme
# the converted content theme
# @param [Integer] width
# the slide width
#
# @return [String]
#
# @api public
def convert(content, symbols: nil, width: nil)
def convert(content, symbols: nil, theme: nil, width: nil)
@markdown_parser.parse(
content, color: @color, symbols: symbols, width: width)
content, color: @color, symbols: symbols, theme: theme, 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 @@ -82,6 +82,11 @@ def self.define_meta(key)
# @return [Hash, String, Symbol]
define_meta :symbols

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

# Create a Metadata instance
#
# @param [Hash{Symbol => Object}] metadata
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 @@ -52,7 +52,8 @@ def create_defaults
footer: default_footer,
margin: @margin[0, 0, 0, 0],
pager: default_pager,
symbols: :unicode
symbols: :unicode,
theme: {}
}.freeze
end

Expand Down
23 changes: 14 additions & 9 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, margin, symbols =
*select_metadata(slide[:metadata], :align, :margin, :symbols)
converted = convert_markdown(slide[:content], margin, symbols)
alignment, margin, symbols, theme =
*select_metadata(slide[:metadata], :align, :margin, :symbols, :theme)
converted = convert_markdown(slide[:content], margin, symbols, theme)

render_section(converted.lines, alignment, margin)
end
Expand All @@ -107,8 +107,9 @@ def render_footer(slide_metadata)
return if (text = footer_metadata[:text]).empty?

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

render_section(converted.lines, alignment, margin)
end
Expand All @@ -130,9 +131,10 @@ def render_pager(slide_metadata, current_num, num_of_slides)
return if (text = pager_metadata[:text]).empty?

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

render_section(converted.lines, alignment, margin)
end
Expand Down Expand Up @@ -244,12 +246,15 @@ def find_top_row(alignment, margin, num_of_lines)
# the slide margin
# @param [Hash, String, Symbol] symbols
# the converted content symbols
# @param [Hash{Symbol => Array, String, Symbol}] theme
# the converted content theme
#
# @return [String]
#
# @api private
def convert_markdown(content, margin, symbols)
@converter.convert(content, symbols: symbols, width: slide_width(margin))
def convert_markdown(content, margin, symbols, theme)
@converter.convert(
content, symbols: symbols, theme: theme, width: slide_width(margin))
end

# Find maximum line length
Expand Down
7 changes: 7 additions & 0 deletions spec/fixtures/slides.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ footer: "**footer content**"
margin: 1 2
pager: "page %<page>d of %<total>d"
symbols: ascii
theme:
header:
- magenta
- underline
link: cyan
list: green
strong: blue
--- symbols: {base: ascii, override: {arrow: ">>"}}

# [Title](url)
Expand Down
23 changes: 18 additions & 5 deletions spec/unit/converter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@
it "converts markdown title to terminal output" do
converter = described_class.new(markdown_parser, color: true)

converted = converter.convert("# Title", symbols: :unicode, width: 20)
converted = converter.convert("# Title", symbols: :unicode, theme: {},
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", symbols: :unicode, width: 20)
converted = converter.convert("# Title", symbols: :unicode, theme: {},
width: 20)

expect(converted).to eq("Title\n")
end
Expand All @@ -23,7 +25,7 @@
converter = described_class.new(markdown_parser, color: true)

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

expect(converted).to eq([
"\e[36;1;4mVery Long \e[0m\n",
Expand All @@ -35,7 +37,7 @@
converter = described_class.new(markdown_parser, color: false)

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

expect(converted).to eq([
"Very Long \n",
Expand All @@ -46,8 +48,19 @@
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)
converted = converter.convert("- list item", symbols: :ascii, theme: {},
width: 20)

expect(converted).to eq("\e[33m*\e[0m list item\n")
end

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

converted = converter.convert("- list item", symbols: :unicode,
theme: {list: :magenta},
width: 20)

expect(converted).to eq("\e[35m●\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 @@ -102,4 +102,16 @@
symbols: {base: :ascii, override: {bullet: "x"}}
})
end

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

converted = converter.convert({
theme: {list: :magenta, strong: %i[magenta bold]}
})

expect(converted).to eq({
theme: {list: :magenta, strong: %i[magenta bold]}
})
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 @@ -20,7 +20,8 @@
align: alignment["right", "bottom"],
text: "%<page>d / %<total>d"
},
symbols: :unicode
symbols: :unicode,
theme: {}
})
end

Expand All @@ -35,7 +36,8 @@
pager: {
text: "%<page>d of %<total>d"
},
symbols: :ascii
symbols: :ascii,
theme: {link: :magenta}
})

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

Expand All @@ -65,7 +68,8 @@
pager: {
align: alignment["right", "top"]
},
symbols: :ascii
symbols: :ascii,
theme: {link: :magenta}
})

expect(merged).to eq({
Expand All @@ -79,7 +83,8 @@
align: alignment["right", "top"],
text: "%<page>d / %<total>d"
},
symbols: :ascii
symbols: :ascii,
theme: {link: :magenta}
})
end
end
16 changes: 15 additions & 1 deletion spec/unit/metadata_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,20 @@
expect(metadata.symbols).to eq(:ascii)
end

it "defaults :theme to an empty hash" do
metadata = described_class.from(converter, {}, defaults)

expect(metadata.theme).to eq({})
end

it "creates metadata from :theme with a custom :link value" do
config = {theme: {link: :magenta}}

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

expect(metadata.theme).to eq({link: :magenta})
end

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

Expand All @@ -252,6 +266,6 @@
}.to raise_error(Slideck::InvalidMetadataKeyError,
"unknown 'invalid' configuration key\n" \
"Available keys are: :align, :footer, :margin, " \
":pager, :symbols")
":pager, :symbols, :theme")
end
end
29 changes: 21 additions & 8 deletions spec/unit/parser_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

RSpec.describe Slideck::Parser, "#parse" do
let(:metadata_parser) {
Slideck::MetadataParser.new(::YAML, permitted_classes: [Symbol],
symbolize_names: true)
Slideck::MetadataParser.new(YAML, permitted_classes: [Symbol],
symbolize_names: true)
}

it "parses empty content" do
Expand Down Expand Up @@ -80,6 +80,8 @@
margin: 2
pager: "page %<page>d of %<total>d"
symbols: ascii
theme:
list: green
EOS
parser = described_class.new(StringScanner, metadata_parser)

Expand All @@ -91,7 +93,8 @@
footer: "footer content",
margin: 2,
pager: "page %<page>d of %<total>d",
symbols: "ascii"
symbols: "ascii",
theme: {list: "green"}
},
slides: []
})
Expand All @@ -104,6 +107,8 @@
:margin: 2
:pager: "page %<page>d of %<total>d"
:symbols: ascii
:theme:
list: green
EOS
parser = described_class.new(StringScanner, metadata_parser)

Expand All @@ -115,7 +120,8 @@
footer: "footer content",
margin: 2,
pager: "page %<page>d of %<total>d",
symbols: "ascii"
symbols: "ascii",
theme: {list: "green"}
},
slides: []
})
Expand All @@ -128,6 +134,8 @@
margin: [1, 2]
pager: "page %<page>d of %<total>d"
symbols: ascii
theme:
list: green
---
# Slide 1
---
Expand All @@ -145,7 +153,8 @@
footer: "footer content",
margin: [1, 2],
pager: "page %<page>d of %<total>d",
symbols: "ascii"
symbols: "ascii",
theme: {list: "green"}
},
slides: [
{content: "# Slide 1", metadata: {}},
Expand All @@ -163,6 +172,8 @@
margin: {top: 1, left: 2}
pager: "page %<page>d of %<total>d"
symbols: ascii
theme:
list: green
---
# Slide 1
---
Expand All @@ -181,7 +192,8 @@
footer: "footer content",
margin: {top: 1, left: 2},
pager: "page %<page>d of %<total>d",
symbols: "ascii"
symbols: "ascii",
theme: {list: "green"}
},
slides: [
{content: "# Slide 1", metadata: {}},
Expand Down Expand Up @@ -209,7 +221,7 @@
Slide 4
---{symbols: {override: {bullet: "x"}}}
---{symbols: {override: {bullet: "x"}}, theme: {list: green}}
Slide 5
EOS
Expand All @@ -229,7 +241,8 @@
{content: "\nSlide 4\n",
metadata: {pager: {text: "page %<page>d of %<total>d"}}},
{content: "\nSlide 5",
metadata: {symbols: {override: {bullet: "x"}}}}
metadata: {symbols: {override: {bullet: "x"}},
theme: {list: "green"}}}
]
})
end
Expand Down
Loading

0 comments on commit 7c12857

Please sign in to comment.