jekyll-pseudo 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .idea
6
+ *.iml
@@ -0,0 +1 @@
1
+ ruby-head
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in jekyll-pseudo.gemspec
4
+ gemspec
@@ -0,0 +1,44 @@
1
+ # jekyll-pseudo
2
+ A pseudocode/algorithm formatter for sites powered by jekyll.
3
+
4
+ Sometimes you don't want to use a particular programming language to
5
+ demonstrate a concept because of the syntactic overhead. Jekyll-Pseudo lets
6
+ you use a gently styled free-formated representation.
7
+
8
+ ## Language
9
+ * indentation is preserved
10
+ * a word beginning with a capital letter is a keyword
11
+ * a word followed by parentheses is a function name
12
+ * all other words are variables
13
+ * words within double quotes are generally strings
14
+
15
+ * these symbols are auto-formatted: `<-- <= >= --> =`
16
+
17
+
18
+ Sample output:
19
+
20
+ {% pseudo %}
21
+ Function swap(old, new)
22
+ remaining <- quorumSize
23
+ success <- False
24
+ For Each host
25
+ result[host] <- send(host, propose(old, new))
26
+ If result[host] = "ok"
27
+ remaining--
28
+
29
+ If remaining > 1+quorumSize/2
30
+ success <- True
31
+
32
+ For Each result
33
+ If success
34
+ send(host, confirm(old, new))
35
+ Else
36
+ send(host, cancel(old, new))
37
+ {% endpseudo %}
38
+
39
+ ## Output
40
+ Output is annotated with `<span>` classes and can be styled using CSS. Typically keywords are made bold and variables are italicized.
41
+
42
+ With a bit of formatting, the above code becomes:
43
+
44
+ ![Image](https://raw.github.com/wkm/jekyll-pseudo/master/doc/samplecode.png)
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
Binary file
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "jekyll-pseudo/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "jekyll-pseudo"
7
+ s.version = Jekyll::Pseudo::VERSION
8
+ s.authors = ["Wiktor Macura"]
9
+ s.email = ["wmacura@gmail.com"]
10
+ s.homepage = "http://github.com/wkm/jekyll-pseudo"
11
+ s.summary = %q{A trivial jekyll plugin for formatting pseudocode}
12
+ s.description = %q{jekyll-pseudo helps typeset pseudocode with minimal formatting}
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.require_paths = ["lib"]
18
+
19
+ # specify any dependencies here; for example:
20
+ s.add_runtime_dependency "jekyll"
21
+ end
@@ -0,0 +1,23 @@
1
+ require 'liquid'
2
+ require 'jekyll-pseudo/version'
3
+ require 'jekyll-pseudo/grammar'
4
+ require 'jekyll-pseudo/html_brush'
5
+
6
+ module Jekyll
7
+ class PseudoBlock < Liquid::Block
8
+ def initialize(tag_name, text, tokens)
9
+ super
10
+ @brush = Pseudo::HtmlBrush.new
11
+ @grammar = Pseudo::Grammar.new
12
+ end
13
+
14
+ def render(context)
15
+ @text = @nodelist.join('')
16
+ @formatted = @grammar.format(@text, @brush)
17
+ "<div class='pseudo'>#{@formatted}</div>"
18
+ end
19
+ end
20
+ end
21
+
22
+
23
+ Liquid::Template.register_tag('pseudo', Jekyll::PseudoBlock)
@@ -0,0 +1,40 @@
1
+ module Jekyll
2
+ module Pseudo
3
+ class Brush
4
+ # format a symbol
5
+ def sym(txt)
6
+ raise 'not implemented'
7
+ end
8
+
9
+ # format a function
10
+ def fn(txt)
11
+ raise 'not implemented'
12
+ end
13
+
14
+ # format a variable
15
+ def var(txt)
16
+ raise 'not implemented'
17
+ end
18
+
19
+ # format a comment
20
+ def comment(txt)
21
+ raise 'not implemented'
22
+ end
23
+
24
+ # format an operator
25
+ def op(txt)
26
+ raise 'not implemented'
27
+ end
28
+
29
+ # format a string
30
+ def string(txt)
31
+ raise 'not implemented'
32
+ end
33
+
34
+ # render plain text
35
+ def plain(txt)
36
+ raise 'not implemented'
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,56 @@
1
+ module Jekyll
2
+ module Pseudo
3
+ class Grammar
4
+ # format a block of text, giving html as output
5
+ def format(txt, brush)
6
+ results = []
7
+
8
+ mappings = [
9
+ [/\#(.*$)/, :comment],
10
+ [/\b([A-Z]\w+)/, :sym],
11
+ [/(\w+)(?=[({\[])/, :fn],
12
+ [/(\".*?\")/, :string],
13
+ [/(<-|->|\+\+|<=|>=|--)/, :op], # try these operations first
14
+ [/([-()\[\]{}=<>+])/, :op], # and these second
15
+ [/^(\s)+/, :indent]
16
+ ]
17
+
18
+ txt.strip!
19
+
20
+ # lazy man's parser (we don't do that backtracking business)
21
+ cursor = 0
22
+ while true
23
+ matches = mappings.map do |pair|
24
+ [pair[0].match(txt, cursor), pair[1]]
25
+ end
26
+
27
+ upto = matches.min_by do |pair|
28
+ matchdata = pair[0]
29
+ if matchdata == nil
30
+ txt.size
31
+ else
32
+ matchdata.begin(0)
33
+ end
34
+ end
35
+
36
+ if upto[0] != nil
37
+ results << brush.plain(txt.slice(cursor, upto[0].begin(0)-cursor))
38
+
39
+ match = upto[0][1]
40
+ # which match?
41
+ results << brush.method(upto[1]).call(match)
42
+ cursor = upto[0].end(1)
43
+ else
44
+ # no matches remaining
45
+ results << brush.plain(txt.slice(cursor, txt.size))
46
+ break
47
+ end
48
+ end
49
+
50
+ # puts "FINAL: #{results.inspect}"
51
+ # puts " = #{results.join('').inspect}"
52
+ return results.join('')
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,49 @@
1
+ require 'jekyll-pseudo/brush'
2
+
3
+ module Jekyll
4
+ module Pseudo
5
+ class HtmlBrush < Jekyll::Pseudo::Brush
6
+ def sym(txt)
7
+ "<span class='symbol'>#{txt}</span>"
8
+ end
9
+
10
+ def fn(txt)
11
+ "<span class='function'>#{txt}</span>"
12
+ end
13
+
14
+ def var(txt)
15
+ "<span class='variable'>#{var}</span>"
16
+ end
17
+
18
+ def comment(txt)
19
+ "<span class='comment'>/* #{txt.strip} */</span>"
20
+ end
21
+
22
+ def string(txt)
23
+ "<span class='string'>#{txt}</span>"
24
+ end
25
+
26
+ def indent(txt)
27
+ "<span class='indent'>#{txt}</span>"
28
+ end
29
+
30
+ def op(txt)
31
+ symbol = case txt
32
+ when '<' then '&lt;'
33
+ when '>' then '&gt;'
34
+ when '<=' then '&le;'
35
+ when '>=' then '&ge;'
36
+ when '<-' then '&larr;'
37
+ when '->' then '&rarr;'
38
+ else txt
39
+ end
40
+ # FIXME: html conversion for some operators
41
+ "<span class='op'>#{symbol}</span>"
42
+ end
43
+
44
+ def plain(txt)
45
+ txt
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,39 @@
1
+ require 'jekyll-pseudo/brush'
2
+
3
+ module Jekyll
4
+ module Pseudo
5
+ class MockBrush < Brush
6
+ def sym(txt)
7
+ "sym(#{txt})"
8
+ end
9
+
10
+ def fn(txt)
11
+ "fn(#{txt})"
12
+ end
13
+
14
+ def var(txt)
15
+ "var(#{var})"
16
+ end
17
+
18
+ def comment(txt)
19
+ "c(#{txt})"
20
+ end
21
+
22
+ def op(txt)
23
+ "op(#{txt})"
24
+ end
25
+
26
+ def string(txt)
27
+ "str(#{txt})"
28
+ end
29
+
30
+ def indent(txt)
31
+ "i(#{txt})"
32
+ end
33
+
34
+ def plain(txt)
35
+ txt
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,5 @@
1
+ module Jekyll
2
+ module Pseudo
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,43 @@
1
+ require_relative '../lib/jekyll-pseudo.rb'
2
+ require_relative '../lib/jekyll-pseudo/mock_brush.rb'
3
+ # require 'spec_helper'
4
+
5
+ include Jekyll::Pseudo
6
+
7
+ describe Grammar do
8
+ def format(txt)
9
+ g = Grammar.new
10
+ g.format(txt, MockBrush.new)
11
+ end
12
+
13
+ describe "#format" do
14
+ it "ignores plain text" do
15
+ format("plain text").should eql "plain text"
16
+ end
17
+
18
+ it "formats symbols" do
19
+ format("For").should eql "sym(For)"
20
+ format("For this").should eql "sym(For) this"
21
+ format("If Then").should eql "sym(If) sym(Then)"
22
+ format("If Then that").should eql ("sym(If) sym(Then) that")
23
+ end
24
+
25
+ it "formats comments" do
26
+ format("oh #hi\n there").should eql "oh c(hi)\ni( )there"
27
+ end
28
+
29
+ it "formats operators" do
30
+ format("For a < b").should eql("sym(For) a op(<) b")
31
+ end
32
+
33
+ it 'formats strings' do
34
+ format('oh "what" a world!').should eql 'oh str("what") a world!'
35
+ end
36
+
37
+ it 'formats functions' do
38
+ format('fn(b,c)').should eql('fn(fn)op(()b,cop())')
39
+ format('fn[b,c]').should eql('fn(fn)op([)b,cop(])')
40
+ format('fn{b,c}').should eql('fn(fn)op({)b,cop(})')
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,26 @@
1
+ require_relative '../lib/jekyll-pseudo.rb'
2
+ require_relative '../lib/jekyll-pseudo/mock_brush.rb'
3
+ # require 'spec_helper'
4
+
5
+ include Jekyll::Pseudo
6
+
7
+ describe HtmlBrush do
8
+ def format(txt)
9
+ g = Grammar.new
10
+ g.format(txt, HtmlBrush.new)
11
+ end
12
+
13
+ describe "#format" do
14
+ it "symbol span" do
15
+ format("For").should eql "<span class='symbol'>For</span>"
16
+ end
17
+
18
+ it "fn span" do
19
+ format("fn()").should eql "<span class='function'>fn</span><span class='op'>(</span><span class='op'>)</span>"
20
+ end
21
+
22
+ it "comment span" do
23
+ format("# hi!").should eql "<span class='comment'>/* hi! */</span>"
24
+ end
25
+ end
26
+ end
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll-pseudo
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Wiktor Macura
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2013-06-17 00:00:00 -04:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: jekyll
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :runtime
31
+ version_requirements: *id001
32
+ description: jekyll-pseudo helps typeset pseudocode with minimal formatting
33
+ email:
34
+ - wmacura@gmail.com
35
+ executables: []
36
+
37
+ extensions: []
38
+
39
+ extra_rdoc_files: []
40
+
41
+ files:
42
+ - .gitignore
43
+ - .ruby-version
44
+ - Gemfile
45
+ - README.md
46
+ - Rakefile
47
+ - doc/samplecode.png
48
+ - jekyll-pseudo.gemspec
49
+ - lib/jekyll-pseudo.rb
50
+ - lib/jekyll-pseudo/brush.rb
51
+ - lib/jekyll-pseudo/grammar.rb
52
+ - lib/jekyll-pseudo/html_brush.rb
53
+ - lib/jekyll-pseudo/mock_brush.rb
54
+ - lib/jekyll-pseudo/version.rb
55
+ - spec/grammar_spec.rb
56
+ - spec/html_spec.rb
57
+ has_rdoc: true
58
+ homepage: http://github.com/wkm/jekyll-pseudo
59
+ licenses: []
60
+
61
+ post_install_message:
62
+ rdoc_options: []
63
+
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ segments:
71
+ - 0
72
+ version: "0"
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ segments:
78
+ - 0
79
+ version: "0"
80
+ requirements: []
81
+
82
+ rubyforge_project:
83
+ rubygems_version: 1.3.6
84
+ signing_key:
85
+ specification_version: 3
86
+ summary: A trivial jekyll plugin for formatting pseudocode
87
+ test_files:
88
+ - spec/grammar_spec.rb
89
+ - spec/html_spec.rb