clerq 0.1.0 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +4 -3
- data/CHANGELOG.md +49 -0
- data/Gemfile.lock +9 -9
- data/README.md +260 -133
- data/Rakefile +1 -0
- data/clerq.gemspec +6 -6
- data/clerq.thor +28 -0
- data/docs/README.md +408 -0
- data/lib/assets/knb/SRS-IEEE-830-1998.md +293 -0
- data/lib/assets/knb/SRS-RUP.md +283 -0
- data/lib/assets/knb/business-case.md +135 -0
- data/lib/assets/knb/ears-with-examples.md +101 -0
- data/lib/assets/knb/problem-statement.md +8 -0
- data/lib/assets/knb/product-statement.md +8 -0
- data/lib/assets/knb/requirement-attributes.md +26 -0
- data/lib/assets/knb/requirement-classification.md +27 -0
- data/lib/assets/knb/requirement-life-cycle.md +47 -0
- data/lib/assets/knb/requirement-quality.md +13 -0
- data/lib/assets/knb/use-case.md +39 -0
- data/lib/assets/knb/vision-document.md +191 -0
- data/lib/assets/lib/clerq_doc.thor +119 -0
- data/lib/assets/lib/colonize_repo.rb +82 -0
- data/lib/assets/lib/spec/colonize_repo_spec.rb +85 -0
- data/lib/assets/new/clerq.thor.tt +32 -5
- data/lib/assets/new/content.md.tt +3 -40
- data/lib/assets/tt/default.md.erb +23 -42
- data/lib/assets/tt/pandoc.md.erb +11 -8
- data/lib/clerq.rb +57 -12
- data/lib/clerq/cli.rb +77 -60
- data/lib/clerq/entities.rb +0 -1
- data/lib/clerq/entities/node.rb +135 -115
- data/lib/clerq/properties.rb +1 -3
- data/lib/clerq/repositories.rb +2 -4
- data/lib/clerq/repositories/file_repository.rb +59 -0
- data/lib/clerq/repositories/node_repository.rb +72 -30
- data/lib/clerq/repositories/text_repository.rb +47 -0
- data/lib/clerq/services.rb +8 -0
- data/lib/clerq/services/check_assembly.rb +108 -0
- data/lib/clerq/{interactors → services}/create_node.rb +12 -11
- data/lib/clerq/services/load_assembly.rb +54 -0
- data/lib/clerq/services/query_node.rb +72 -0
- data/lib/clerq/services/query_template.rb +26 -0
- data/lib/clerq/services/read_node.rb +101 -0
- data/lib/clerq/services/render_erb.rb +29 -0
- data/lib/clerq/services/render_node.rb +37 -0
- data/lib/clerq/services/service.rb +19 -0
- data/lib/clerq/settings.rb +2 -2
- data/lib/clerq/version.rb +1 -1
- metadata +49 -37
- data/TODO.md +0 -3
- data/lib/assets/tt/gitlab.md.erb +0 -93
- data/lib/assets/tt/raw.md.erb +0 -23
- data/lib/clerq/entities/template.rb +0 -19
- data/lib/clerq/gateways.rb +0 -3
- data/lib/clerq/gateways/gateway.rb +0 -17
- data/lib/clerq/gateways/in_files.rb +0 -36
- data/lib/clerq/gateways/in_memory.rb +0 -35
- data/lib/clerq/interactors.rb +0 -5
- data/lib/clerq/interactors/check_nodes.rb +0 -81
- data/lib/clerq/interactors/compile_nodes.rb +0 -31
- data/lib/clerq/interactors/interactor.rb +0 -28
- data/lib/clerq/interactors/join_nodes.rb +0 -59
- data/lib/clerq/interactors/query_nodes.rb +0 -62
- data/lib/clerq/repositories/in_memory.rb +0 -45
- data/lib/clerq/repositories/node_reader.rb +0 -107
- data/lib/clerq/repositories/repository.rb +0 -11
- data/lib/clerq/repositories/template_repository.rb +0 -53
- data/lib/clerq/templater.rb +0 -32
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'clerq'
|
2
|
+
require 'thor'
|
3
|
+
require 'tmpdir'
|
4
|
+
require_relative 'lib/colonize_repo'
|
5
|
+
include Clerq::Repositories
|
6
|
+
include Clerq::Entities
|
7
|
+
include Clerq::Services
|
8
|
+
|
9
|
+
# This thor file sample was created with purpose to show some examples
|
10
|
+
# of using Pandoc for clerq reposiory publishing and even import souce
|
11
|
+
# documents into a clerq repository ... `thor clerq:doc:grab`, `thor clerq:doc:publish`
|
12
|
+
class ClerqDoc < Thor
|
13
|
+
include Thor::Actions
|
14
|
+
namespace 'clerq:doc'.to_sym
|
15
|
+
|
16
|
+
no_commands {
|
17
|
+
def eqid!(node)
|
18
|
+
counter = {}
|
19
|
+
node.to_a.drop(1).each do |n|
|
20
|
+
index = counter[n.parent] || 1
|
21
|
+
counter[n.parent] = index + 1
|
22
|
+
id = index.to_s.rjust(2, '0')
|
23
|
+
id = '.' + id unless n.parent == node
|
24
|
+
n.id = id
|
25
|
+
end
|
26
|
+
end
|
27
|
+
}
|
28
|
+
|
29
|
+
# Why does one need to grab the document?
|
30
|
+
# it started in MS Word but the author decieded to pкoceed in Clerq
|
31
|
+
# it is the source for the clerq project, SRS based on Vision?
|
32
|
+
# something else?
|
33
|
+
# TODO provide -q/--query QUERY_STRING parameter
|
34
|
+
# TODO how about importing images?
|
35
|
+
desc 'grab FILENAME', 'Grab document and populate the clerq repository'
|
36
|
+
def grab(filename)
|
37
|
+
mdown = File.join(Dir.tmpdir, 'clerq.grab.md')
|
38
|
+
optns = [].tap{|o|
|
39
|
+
o << '--wrap=none'
|
40
|
+
o << '--atx-headers'
|
41
|
+
o << "#{filename}"
|
42
|
+
o << "-o #{mdown}"
|
43
|
+
}.join(' ')
|
44
|
+
|
45
|
+
`pandoc #{optns}`
|
46
|
+
|
47
|
+
on_error_callback = lambda {|err| puts err}
|
48
|
+
puts "Reading '#{mdown}'..."
|
49
|
+
|
50
|
+
# TODO handle query parameter
|
51
|
+
arry = ReadNode.(mdown, on_error_callback)
|
52
|
+
node = Node.new(id: '00', title: File.basename(mdown, '.md'))
|
53
|
+
arry.each{|n| node << n}
|
54
|
+
eqid!(node)
|
55
|
+
|
56
|
+
puts "Colonizing this repository..."
|
57
|
+
dir_counter = 0
|
58
|
+
src_counter = 0
|
59
|
+
on_create_dir = lambda {|dir| puts "Created '#{dir}' directory"; dir_counter += 1 }
|
60
|
+
on_create_src = lambda {|src| puts "Created '#{src}' file"; src_counter += 1 }
|
61
|
+
|
62
|
+
Dir.chdir(Clerq.src) { ColonizeRepo.(node, on_create_dir, on_create_src) }
|
63
|
+
|
64
|
+
msg = [].tap do |memo|
|
65
|
+
memo << "#{dir_counter} #{dir_counter == 1 ? 'directory' : 'directories'}" if dir_counter > 0
|
66
|
+
memo << "#{src_counter} #{src_counter == 1 ? 'file' : 'files'}" if src_counter > 0
|
67
|
+
end.join(' and ')
|
68
|
+
|
69
|
+
say "#{node.to_a.size} nodes from '#{filename}' imported to the repositroy. #{msg} created in the repository."
|
70
|
+
end
|
71
|
+
|
72
|
+
desc 'publish', 'Publishing final deliverables'
|
73
|
+
def publish
|
74
|
+
invoke :docx
|
75
|
+
invoke :html
|
76
|
+
end
|
77
|
+
|
78
|
+
desc 'html', 'Publish final deliverable in Html'
|
79
|
+
def html
|
80
|
+
source = File.join(Clerq.bin, Clerq.document + ".md")
|
81
|
+
target = File.join(Clerq.bin, Clerq.document + ".html")
|
82
|
+
optns = [].tap{|o|
|
83
|
+
o << '-s --toc --toc-depth 3'
|
84
|
+
o << "--resource-path #{Clerq.bin}"
|
85
|
+
o << "\"#{source}\""
|
86
|
+
o << "-o \"#{target}\""
|
87
|
+
}.join(" ")
|
88
|
+
|
89
|
+
`clerq build -t pandoc.md.erb`
|
90
|
+
`pandoc #{optns}`
|
91
|
+
say "\"#{target}\" created!"
|
92
|
+
end
|
93
|
+
|
94
|
+
desc 'docx', 'Publish final deliverable in Docx'
|
95
|
+
def docx
|
96
|
+
source = File.join(Clerq.bin, Clerq.document + ".md")
|
97
|
+
target = File.join(Clerq.bin, Clerq.document + ".docx")
|
98
|
+
sample = File.join(Clerq.bin, 'custom-reference.docx')
|
99
|
+
|
100
|
+
unless File.exist?(sample)
|
101
|
+
# produce a custom reference.docx
|
102
|
+
`pandoc -o #{sample} --print-default-data-file reference.docx`
|
103
|
+
end
|
104
|
+
|
105
|
+
optns = [].tap{|o|
|
106
|
+
o << '-s --toc --toc-depth 3'
|
107
|
+
o << '--from markdown+table_captions+implicit_figures'
|
108
|
+
o << "--reference-doc #{sample}"
|
109
|
+
o << "--resource-path #{Clerq.bin}"
|
110
|
+
o << "\"#{source}\""
|
111
|
+
o << "-o \"#{target}\""
|
112
|
+
}.join(" ")
|
113
|
+
|
114
|
+
`clerq build -t pandoc.md.erb`
|
115
|
+
`pandoc #{optns}`
|
116
|
+
say "\"#{target}\" created!"
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'clerq'
|
2
|
+
require 'erb'
|
3
|
+
include Clerq::Entities
|
4
|
+
include Clerq::Services
|
5
|
+
|
6
|
+
# Creates clerq repository sources in current work directory
|
7
|
+
# Warning! Change work dierectory before calling for the serice
|
8
|
+
# Usage
|
9
|
+
# node = Clerq.node_repository.assembly
|
10
|
+
# Dir.chdir(Clerq.src) { ColonizeRepo.(node) }
|
11
|
+
class ColonizeRepo < Service
|
12
|
+
private_class_method :new
|
13
|
+
|
14
|
+
def call
|
15
|
+
write(@node)
|
16
|
+
end
|
17
|
+
|
18
|
+
# TODO callback? and calback for ReadNode.()?
|
19
|
+
def write(node)
|
20
|
+
dir = folder(node)
|
21
|
+
src = source(node)
|
22
|
+
txt = text(node)
|
23
|
+
unless dir.empty? || Dir.exist?(dir)
|
24
|
+
Dir.mkdir(dir)
|
25
|
+
@on_create_dir.call(dir) if @on_create_dir
|
26
|
+
end
|
27
|
+
File.write(src, txt)
|
28
|
+
@on_create_file.call(src) if @on_create_file
|
29
|
+
node.items.reject{|n| n.items.empty?}.each{|n| write(n)}
|
30
|
+
end
|
31
|
+
|
32
|
+
# @param node [Node] the node for colonization
|
33
|
+
# @param on_create_file [Block(arg)] on create new file callback
|
34
|
+
# @param on_create_dir [Block(arg)] on create new directory callback
|
35
|
+
def initialize(node, on_create_dir = nil, on_create_file = nil)
|
36
|
+
@node = node
|
37
|
+
@on_create_dir = on_create_dir
|
38
|
+
@on_create_file = on_create_file
|
39
|
+
end
|
40
|
+
|
41
|
+
def source(node)
|
42
|
+
fld = folder(node)
|
43
|
+
src = filename(node)
|
44
|
+
fld.empty? ? src : File.join(fld, src)
|
45
|
+
end
|
46
|
+
|
47
|
+
def folder(node)
|
48
|
+
dir = ''
|
49
|
+
n = node
|
50
|
+
while n != @node.root && n.parent != @node.root
|
51
|
+
dir = File.join("#{n.parent.id} #{n.parent.title}", dir)
|
52
|
+
n = n.parent
|
53
|
+
end
|
54
|
+
dir
|
55
|
+
end
|
56
|
+
|
57
|
+
def filename(node)
|
58
|
+
"#{node.id} #{node.title}.md"
|
59
|
+
end
|
60
|
+
|
61
|
+
# TODO replace to services
|
62
|
+
def text(node)
|
63
|
+
RenderErb.(erb: TEMPLATE, object: node)
|
64
|
+
end
|
65
|
+
|
66
|
+
TEMPLATE = <<~EOF
|
67
|
+
# <%= @object.title %>
|
68
|
+
{{id: <%= @object.id %><%= ", parent: " + @object.parent.id if @object.parent %>, order_index: <%= @object.items.map(&:id).join(' ') %>}}
|
69
|
+
|
70
|
+
<%= @object.body %>
|
71
|
+
|
72
|
+
<% for n in @object.items -%>
|
73
|
+
<% next unless n.items.empty? -%>
|
74
|
+
## <%= n.title %>
|
75
|
+
{{id: <%= n.id %>}}
|
76
|
+
|
77
|
+
<%= n.body %>
|
78
|
+
|
79
|
+
<% end %>
|
80
|
+
EOF
|
81
|
+
|
82
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'clerq'
|
2
|
+
require 'erb'
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require_relative 'colonize_repo'
|
5
|
+
include Clerq::Entities
|
6
|
+
include Clerq::Services
|
7
|
+
|
8
|
+
describe ColonizeRepo do
|
9
|
+
class FakeWriter < ColonizeRepo
|
10
|
+
public_class_method :new
|
11
|
+
attr_reader :node
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:node) {
|
15
|
+
Node.new(id: '0', title: 'Import').tap{|n|
|
16
|
+
n << Node.new(id: '01', title: 'User')
|
17
|
+
n << Node.new(id: '02', title: 'Func')
|
18
|
+
n.item('01') << Node.new(id: '01.01', title: 'Story 1')
|
19
|
+
n.item('01') << Node.new(id: '01.02', title: 'Story 2')
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
let(:writer) { FakeWriter.new(node) }
|
24
|
+
|
25
|
+
describe '#folder' do
|
26
|
+
it 'must return parent.id + parent.name' do
|
27
|
+
spec = writer.node.map{|n| writer.folder(n)}
|
28
|
+
_(spec).must_equal([
|
29
|
+
'', '', '01 User/', '01 User/', ''
|
30
|
+
])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#filename' do
|
35
|
+
it 'must return node.id + node.title' do
|
36
|
+
spec = writer.node.map{|n| writer.filename(n)}
|
37
|
+
_(spec).must_equal([
|
38
|
+
'0 Import.md', '01 User.md', '01.01 Story 1.md',
|
39
|
+
'01.02 Story 2.md', '02 Func.md'
|
40
|
+
])
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '#source' do
|
45
|
+
# title and first level shall be paced in root folder
|
46
|
+
it 'must return node.id + node.title' do
|
47
|
+
spec = writer.node.map{|n| writer.source(n)}
|
48
|
+
_(spec).must_equal([
|
49
|
+
'0 Import.md',
|
50
|
+
'01 User.md',
|
51
|
+
'01 User/01.01 Story 1.md',
|
52
|
+
'01 User/01.02 Story 2.md',
|
53
|
+
'02 Func.md'
|
54
|
+
])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '#write(node)' do
|
59
|
+
let(:node) {
|
60
|
+
Node.new(id: '0', title: 'Import').tap{|n|
|
61
|
+
n << Node.new(id: '01', title: 'User')
|
62
|
+
n << Node.new(id: '02', title: 'Func')
|
63
|
+
n.item('01') << Node.new(id: '01.01', title: 'Story 1')
|
64
|
+
n.item('01') << Node.new(id: '01.02', title: 'Story 2')
|
65
|
+
n.node('01.01') << Node.new(id: '01.01.01', title: 'Story 1.1')
|
66
|
+
n.node('01.01') << Node.new(id: '01.01.02', title: 'Story 1.2')
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
it 'must build repo' do
|
71
|
+
files = ['0 Import.md', '01 User.md', '01 User/01.01 Story 1.md']
|
72
|
+
Dir.mktmpdir(['clerq']) do |dir|
|
73
|
+
Dir.chdir(dir) do
|
74
|
+
ColonizeRepo.(node)
|
75
|
+
files.each{|fn| _(File.exist?(fn)).must_equal true }
|
76
|
+
_(File.read('0 Import.md')).wont_match "parent:"
|
77
|
+
_(File.read('01 User.md')).must_match "parent: 0"
|
78
|
+
_(File.read('01 User/01.01 Story 1.md')).must_match "parent: 01"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
@@ -1,15 +1,42 @@
|
|
1
|
-
# TODO how about to include commands automatically from 'lib' folder
|
2
|
-
|
3
|
-
require 'thor'
|
4
1
|
require 'clerq'
|
2
|
+
require 'thor'
|
5
3
|
|
6
|
-
class <%=config[:
|
4
|
+
class <%=config[:klass]%> < Thor
|
7
5
|
include Thor::Actions
|
8
6
|
|
9
7
|
desc "stat", "Print statistic"
|
10
8
|
def stat
|
11
|
-
nodes = Clerq
|
9
|
+
nodes = Clerq.assemble
|
12
10
|
say "#{nodes.to_a.drop(1).size} nodes total"
|
13
11
|
end
|
14
12
|
|
13
|
+
desc "mm", "Create meeting minutes"
|
14
|
+
def mm
|
15
|
+
minutes = "meeting minutes #{Time.new.strftime('%Y-%m-%d')}.md"
|
16
|
+
content = "% #{minutes.capitalize}\n\n" + MINUTES_TEMPLATE
|
17
|
+
Dir.mkdir('mm') unless Dir.exist?('mm')
|
18
|
+
File.write("mm/#{minutes}", content)
|
19
|
+
say "'mm/#{minutes}' created!"
|
20
|
+
end
|
21
|
+
|
22
|
+
MINUTES_TEMPLATE = <<~EOF
|
23
|
+
# Attendants
|
24
|
+
|
25
|
+
1.
|
26
|
+
2.
|
27
|
+
3.
|
28
|
+
|
29
|
+
# Questions
|
30
|
+
|
31
|
+
1.
|
32
|
+
2.
|
33
|
+
3.
|
34
|
+
|
35
|
+
# Resolutions
|
36
|
+
|
37
|
+
1.
|
38
|
+
2.
|
39
|
+
3.
|
40
|
+
EOF
|
41
|
+
|
15
42
|
end
|
@@ -1,41 +1,4 @@
|
|
1
|
-
#
|
2
|
-
{{
|
1
|
+
# <%=config[:project]%>
|
2
|
+
{{id: 0}}
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
This file was created automatically from the premise that you could want to have the high-level structure of the project (document) in a single place.
|
7
|
-
|
8
|
-
For the usual descriptive parts (nodes) that do not need unique identifiers - use `skip_meta: true` attribute. To output child parts in appropriate order - use the `order_index: nx ny nz` attribute.
|
9
|
-
|
10
|
-
Pay attention that this content placed under `skip` macro that means this content won't be included in the output document.}}
|
11
|
-
|
12
|
-
## Purpose
|
13
|
-
{{skip_meta: true}}
|
14
|
-
|
15
|
-
The purpose of this document is to provide a detailed product description of the <%= config[:project] %>. The document describes the product from user and software requirements perspectives.
|
16
|
-
|
17
|
-
All parties who are responsible for the definition and implementation of the project should read and understand this document.
|
18
|
-
|
19
|
-
## Scope
|
20
|
-
{{skip_meta: true}}
|
21
|
-
|
22
|
-
## Definitions, acronyms, and abbreviations
|
23
|
-
{{skip_meta: true}}
|
24
|
-
|
25
|
-
## References
|
26
|
-
{{skip_meta: true}}
|
27
|
-
|
28
|
-
## Overview
|
29
|
-
{{skip_meta: true}}
|
30
|
-
|
31
|
-
# Users and Stakeholders
|
32
|
-
{{skip_meta: true}}
|
33
|
-
|
34
|
-
# User requirements
|
35
|
-
{{skip_meta: true}}
|
36
|
-
|
37
|
-
# Functional requirements
|
38
|
-
{{skip_meta: true}}
|
39
|
-
|
40
|
-
# Nonfunctional requirements
|
41
|
-
{{skip_meta: true}}
|
4
|
+
This file was created automatically by the `clerq new` command as the root node of your project. To familiarize yourself with how to start writing with the Clerq - please read the [Writing](https://github.com/nvoynov/clerq/blob/master/README.md#writing) section and then just delete the content of the paragraph.
|
@@ -1,64 +1,45 @@
|
|
1
1
|
<%
|
2
|
-
|
2
|
+
|
3
3
|
require 'delegate'
|
4
|
+
|
4
5
|
class MarkupNode < SimpleDelegator
|
5
6
|
def title
|
6
|
-
|
7
|
+
s = super
|
8
|
+
s = ".#{id.split(/\./).last}" if s.empty?
|
9
|
+
'#' * nesting_level + ' ' + s
|
7
10
|
end
|
8
11
|
|
9
12
|
def meta
|
10
13
|
return '' if nesting_level == 0
|
11
|
-
|
12
|
-
|
13
|
-
hsh = {id: id}.merge(super)
|
14
|
-
hsh.delete(:order_index)
|
14
|
+
hsh = {}.merge(super)
|
15
15
|
hsh.delete(:parent)
|
16
|
-
hsh.delete(:
|
17
|
-
|
18
|
-
|
19
|
-
ary << "--------- | -----"
|
20
|
-
hsh.each{|k,v| ary << "#{k} | #{v}"}
|
21
|
-
}.join("\n")
|
22
|
-
end
|
23
|
-
|
24
|
-
def body
|
25
|
-
return '' if super.empty?
|
26
|
-
# replace links
|
27
|
-
txt = String.new(super)
|
28
|
-
links.each{|l| txt.gsub!("[[#{l}]]", link(l))}
|
29
|
-
txt
|
30
|
-
end
|
31
|
-
|
32
|
-
def link(id)
|
33
|
-
r = find_node(id)
|
34
|
-
return "[#{id}](#unknown)" unless r
|
35
|
-
"[#{r.title}](##{url(r.id)})"
|
36
|
-
end
|
16
|
+
hsh.delete(:order_index)
|
17
|
+
hsh.delete(:filename)
|
18
|
+
return '' if hsh.empty?
|
37
19
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
def find_node(id)
|
43
|
-
return find{|n| n.id.end_with? id[1..-1]} if id.start_with? '.'
|
44
|
-
return root.find{|n| n.id.end_with? id[1..-1]} if id.start_with? '*'
|
45
|
-
root.find{|n| n.id.eql? id}
|
20
|
+
hsh.map{|k, v| "#{k}: #{v}"}
|
21
|
+
.unshift("{{")
|
22
|
+
.push("}}")
|
23
|
+
.join("\n")
|
46
24
|
end
|
47
25
|
|
48
|
-
def
|
49
|
-
|
50
|
-
|
51
|
-
.
|
52
|
-
.
|
26
|
+
def markup
|
27
|
+
[].tap do |o|
|
28
|
+
o << title
|
29
|
+
o << meta unless meta.empty?
|
30
|
+
unless body.empty?
|
31
|
+
o << "\n#{body}"
|
32
|
+
end
|
33
|
+
end.join("\n")
|
53
34
|
end
|
54
|
-
|
55
35
|
end
|
56
36
|
-%>
|
57
37
|
% <%= @object.title %>
|
58
38
|
% generated by Clerq on <%= Time.now.strftime('%B %e, %Y at %H:%M') %>
|
39
|
+
% default template
|
59
40
|
|
60
41
|
<% for @node in @object.to_a.drop(1) -%>
|
61
42
|
<% n = MarkupNode.new(@node) -%>
|
62
|
-
<%=
|
43
|
+
<%= n.markup %>
|
63
44
|
|
64
45
|
<% end %>
|