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.
- data/.gitignore +6 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/README.md +44 -0
- data/Rakefile +1 -0
- data/doc/samplecode.png +0 -0
- data/jekyll-pseudo.gemspec +21 -0
- data/lib/jekyll-pseudo.rb +23 -0
- data/lib/jekyll-pseudo/brush.rb +40 -0
- data/lib/jekyll-pseudo/grammar.rb +56 -0
- data/lib/jekyll-pseudo/html_brush.rb +49 -0
- data/lib/jekyll-pseudo/mock_brush.rb +39 -0
- data/lib/jekyll-pseudo/version.rb +5 -0
- data/spec/grammar_spec.rb +43 -0
- data/spec/html_spec.rb +26 -0
- metadata +89 -0
data/.gitignore
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-head
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -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
|
+

|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/doc/samplecode.png
ADDED
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 '<'
|
33
|
+
when '>' then '>'
|
34
|
+
when '<=' then '≤'
|
35
|
+
when '>=' then '≥'
|
36
|
+
when '<-' then '←'
|
37
|
+
when '->' then '→'
|
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,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
|
data/spec/html_spec.rb
ADDED
@@ -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
|