Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Add support for multi-line and root commands when using commandline. #107

Merged
merged 1 commit into from

2 participants

@mudge

When using the "commandline" slide style, you can now start commands
with either $ or # and split commands over multiple lines by using a
back slash.

e.g.

# some root command
some output
$ some really long \
  command over several \
  lines
some output
that goes over
several lines
$ some command \( with back slashes \)
output

Please note that this adds the Parslet library as a dependency so that commandline slides can be parsed in a robust fashion (rather than using a naïve regular expression).

Due to the way the ShowOff gemspec requires './lib/showoff', you will need to manually run "gem install parslet" to try out the new behaviour. (I'm planning to extract ShowOff::VERSION into a separate file in a separate commit to alleviate this issue.)

@mudge mudge Add support for multi-line and root commands when using commandline.
When using the "commandline" slide style, you can now start commands
with either $ or # and split commands over multiple lines by using a
back slash.

e.g.

    # some root command
    some output
    $ some really long \
      command over several \
      lines
    some output
    that goes over
    several lines
    $ some command \( with back slashes \)
    output
    with a

    gap
e7c25db
@schacon schacon merged commit e7c25db into schacon:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Aug 4, 2011
  1. @mudge

    Add support for multi-line and root commands when using commandline.

    mudge authored
    When using the "commandline" slide style, you can now start commands
    with either $ or # and split commands over multiple lines by using a
    back slash.
    
    e.g.
    
        # some root command
        some output
        $ some really long \
          command over several \
          lines
        some output
        that goes over
        several lines
        $ some command \( with back slashes \)
        output
        with a
    
        gap
This page is out of date. Refresh to see the latest.
View
16 example/one/slidesB.md
@@ -32,3 +32,19 @@
[cmaster ac5fd8a] incremental bullet points working
2 files changed, 32 insertions(+), 5 deletions(-)
+!SLIDE commandline incremental
+
+ # root command
+ some output
+
+ $ command over \
+ several lines
+ some more output
+ over several lines
+
+ $ no output command with \( backslashes \)
+ $ command
+ output with
+ a
+
+ blank line
View
67 lib/commandline_parser.rb
@@ -0,0 +1,67 @@
+require 'parslet'
+
+# For parsing commandline slide content.
+class CommandlineParser < Parslet::Parser
+
+ rule(:prompt) do
+ str('$') | str('#')
+ end
+
+ rule(:text) do
+ match['[:print:]'].repeat
+ end
+
+ rule(:singleline_input) do
+ (str("\\\n").absent? >> match['[:print:]']).repeat
+ end
+
+ rule(:input) do
+ multiline_input | singleline_input
+ end
+
+ rule(:multiline_input) do
+
+ # some command \
+ # continued \
+ # \
+ # and stop
+ ( singleline_input >> str('\\') >> newline ).repeat(1) >> singleline_input
+ end
+
+ rule(:command) do
+
+ # $ some command
+ # some output
+ ( prompt.as(:prompt) >> space? >> input.as(:input) >> output? ).as(:command)
+ end
+
+ rule(:output) do
+
+ # output
+ prompt.absent? >> text
+ end
+
+ rule(:output?) do
+
+ #
+ # some text
+ # some text
+ #
+ # some text
+ ( newline >> ( ( output >> newline ).repeat >> output.maybe ).as(:output) ).maybe
+ end
+
+ rule(:commands) do
+ command.repeat
+ end
+
+ rule(:newline) do
+ str("\n") | str("\r\n")
+ end
+
+ rule(:space?) do
+ match['[:space:]'].repeat
+ end
+
+ root(:commands)
+end
View
37 lib/showoff.rb
@@ -7,6 +7,7 @@
here = File.expand_path(File.dirname(__FILE__))
require "#{here}/showoff_utils"
require "#{here}/princely"
+require "#{here}/commandline_parser"
begin
require 'RMagick'
@@ -163,6 +164,7 @@ def get_image_size(path)
def update_commandline_code(slide)
html = Nokogiri::XML.parse(slide)
+ parser = CommandlineParser.new
html.css('pre').each do |pre|
pre.css('code').each do |code|
@@ -178,21 +180,30 @@ def update_commandline_code(slide)
html.css('.commandline > pre > code').each do |code|
out = code.text
- lines = out.split(/^\$(.*?)$/)
- lines.delete('')
code.content = ''
- while(lines.size > 0) do
- command = lines.shift
- result = lines.shift
- c = Nokogiri::XML::Node.new('code', html)
- c.set_attribute('class', 'command')
- c.content = '$' + command
- code << c
- c = Nokogiri::XML::Node.new('code', html)
- c.set_attribute('class', 'result')
- c.content = result
- code << c
+ tree = parser.parse(out)
+ transform = Parslet::Transform.new do
+ rule(:prompt => simple(:prompt), :input => simple(:input), :output => simple(:output)) do
+ command = Nokogiri::XML::Node.new('code', html)
+ command.set_attribute('class', 'command')
+ command.content = "#{prompt} #{input}"
+ code << command
+
+ # Add newline after the input so that users can
+ # advance faster than the typewriter effect
+ # and still keep inputs on separate lines.
+ code << "\n"
+
+ unless output.to_s.empty?
+
+ result = Nokogiri::XML::Node.new('code', html)
+ result.set_attribute('class', 'result')
+ result.content = output
+ code << result
+ end
+ end
end
+ transform.apply(tree)
end
html.root.to_s
end
View
1  showoff.gemspec
@@ -19,6 +19,7 @@ Gem::Specification.new do |s|
s.add_dependency "bluecloth"
s.add_dependency "nokogiri"
s.add_dependency "json"
+ s.add_dependency "parslet"
s.add_dependency("gli",">= 1.2.5")
s.add_development_dependency "mg"
s.description = <<-desc
Something went wrong with that request. Please try again.