genit 1.0.1 → 2.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/NEWS +12 -28
- data/README.markdown +6 -2
- data/Rakefile +1 -1
- data/TODO +177 -12
- data/VERSION +1 -1
- data/bin/genit +18 -20
- data/data/styles/screen.css +5 -9
- data/data/templates/main.html +0 -1
- data/lib/genit.rb +9 -4
- data/lib/genit/builders/body_link_builder.rb +8 -8
- data/lib/genit/builders/builder_base.rb +11 -11
- data/lib/genit/builders/head_link_builder.rb +8 -8
- data/lib/genit/builders/relativizer.rb +12 -12
- data/lib/genit/builders/script_builder.rb +7 -7
- data/lib/genit/documents/document_writer.rb +14 -14
- data/lib/genit/documents/fragment.rb +23 -22
- data/lib/genit/documents/xml_document.rb +5 -1
- data/lib/genit/project.rb +1 -0
- data/lib/genit/project/compiler.rb +54 -73
- data/lib/genit/project/page_compiler.rb +41 -41
- data/lib/genit/project/pages_finder.rb +6 -6
- data/lib/genit/project/project_creator.rb +116 -111
- data/lib/genit/project/root_cleaner.rb +31 -0
- data/lib/genit/project/rss_feed.rb +14 -14
- data/lib/genit/server.rb +2 -0
- data/lib/genit/server/server.rb +33 -0
- data/lib/genit/tags/class_fragment_tag.rb +2 -2
- data/lib/genit/tags/class_menu_tag.rb +2 -1
- data/lib/genit/tags/class_news_tag.rb +24 -24
- data/lib/genit/tags/class_pages_tag.rb +1 -1
- data/lib/genit/tags/here_tag.rb +22 -18
- data/lib/genit/utils/news_utils.rb +3 -3
- data/spec/class_news_tag_spec.rb +5 -5
- data/spec/compiler_spec.rb +51 -60
- data/spec/fragment_spec.rb +19 -19
- data/spec/html_document_spec.rb +10 -10
- data/spec/page_compiler_spec.rb +13 -9
- data/spec/pages_finder_spec.rb +11 -11
- data/spec/project_creator_spec.rb +53 -102
- data/spec/test-files/malformed.html +5 -0
- data/spec/xml_document_spec.rb +5 -0
- metadata +6 -9
- data/data/styles/alsa/all.css +0 -130
- data/data/styles/yui/all.css +0 -3
- data/data/styles/yui/base.css +0 -80
- data/data/styles/yui/fonts.css +0 -47
- data/data/styles/yui/reset.css +0 -126
- data/data/templates/xhtml_1.0_strict +0 -5
- data/data/templates/xhtml_1.0_transitional +0 -5
@@ -4,7 +4,7 @@ module Genit
|
|
4
4
|
|
5
5
|
# Compile a single page.
|
6
6
|
class PageCompiler
|
7
|
-
|
7
|
+
|
8
8
|
# Public: Constructor.
|
9
9
|
#
|
10
10
|
# working_dir - The String working directory, where live the project.
|
@@ -12,10 +12,10 @@ module Genit
|
|
12
12
|
def initialize working_dir, filename
|
13
13
|
@working_dir = working_dir
|
14
14
|
@filename = filename
|
15
|
-
|
16
|
-
|
15
|
+
file = File.join(@working_dir, 'src/templates/main.html')
|
16
|
+
@template = XmlDocument.open(file)
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
# Public: Compile the page.
|
20
20
|
#
|
21
21
|
# Returns a Nokogiri::XML document.
|
@@ -26,44 +26,44 @@ module Genit
|
|
26
26
|
builder = ScriptBuilder.new @template
|
27
27
|
builder.build_for_page @filename
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
private
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
44
|
-
|
45
|
-
def build a_class
|
46
|
-
@template = a_class.new(@template).build_for_page(@filename)
|
47
|
-
end
|
48
|
-
|
49
|
-
def replace_all_genit_tags
|
50
|
-
genit_tags_in_template.each do |tag|
|
51
|
-
next if tag.genit_what?
|
52
|
-
tp = TagProcessor.new(@working_dir, @template, @filename, tag)
|
53
|
-
@template = tp.process
|
31
|
+
|
32
|
+
def compile_body
|
33
|
+
# Pourquoi 2 fois ?
|
34
|
+
# Parce que la 1ere fois, on inclus essentiellement la page au sein du
|
35
|
+
# template, et la seconde fois, on s'occupe des tags restants (ceux qui
|
36
|
+
# étaient dans la page).
|
37
|
+
# Suivant comment la hiérarchie de tag évoluera, il est possible qu'on
|
38
|
+
# ai un jour besoin de faire une boucle du genre :
|
39
|
+
# "Tant qu'il reste des tags"
|
40
|
+
2.times { replace_all_genit_tags }
|
41
|
+
build BodyLinkBuilder
|
42
|
+
build ImgBuilder
|
54
43
|
end
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
44
|
+
|
45
|
+
def replace_all_genit_tags
|
46
|
+
genit_tags_in_template.each do |tag|
|
47
|
+
next if tag.genit_what?
|
48
|
+
tp = TagProcessor.new(@working_dir, @template, @filename, tag)
|
49
|
+
@template = tp.process
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def build a_class
|
54
|
+
@template = a_class.new(@template).build_for_page(@filename)
|
55
|
+
end
|
56
|
+
|
57
|
+
def compile_head
|
58
|
+
builder = HeadLinkBuilder.new @template
|
59
|
+
builder.build_for_page @filename
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns all <genit> tags found in the template.
|
63
|
+
def genit_tags_in_template
|
64
|
+
HtmlDocument.genit_tags_from @template
|
65
|
+
end
|
66
|
+
|
67
67
|
end
|
68
|
-
|
68
|
+
|
69
69
|
end
|
@@ -5,15 +5,15 @@ module Genit
|
|
5
5
|
# I can find the list of all page names, named from
|
6
6
|
# the site root.
|
7
7
|
class PagesFinder
|
8
|
-
|
8
|
+
|
9
9
|
# Public: Constructor.
|
10
10
|
#
|
11
11
|
# working_dir - The String working directory, where live the project.
|
12
12
|
def initialize working_dir
|
13
13
|
@working_dir = working_dir
|
14
|
-
@pages_folder = File.join(@working_dir,
|
14
|
+
@pages_folder = File.join(@working_dir, PAGES_DIR)
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
# Public: Retrieve the list of all page names.
|
18
18
|
#
|
19
19
|
# Returns an Array of String.
|
@@ -22,11 +22,11 @@ module Genit
|
|
22
22
|
list.map! { |name| name.gsub(@pages_folder + '/', '')}
|
23
23
|
list.map { |name| name.force_html_extension }
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
def self.pagenames2urls array, url_string
|
27
27
|
array.map { |name| File.join(url_string, name) }
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
end
|
@@ -7,18 +7,16 @@ module Genit
|
|
7
7
|
|
8
8
|
# Create a skeleton project.
|
9
9
|
class ProjectCreator
|
10
|
-
|
10
|
+
|
11
11
|
# Sole constructor.
|
12
12
|
#
|
13
13
|
# name - The String name of the future project folder.
|
14
|
-
# doctype - The String document type definition.
|
15
14
|
# empty - A Boolean telling if we produce a smoke test or not.
|
16
|
-
def initialize name,
|
15
|
+
def initialize name, empty
|
17
16
|
@project_name = name
|
18
|
-
@doctype = doctype
|
19
17
|
@empty = empty
|
20
18
|
end
|
21
|
-
|
19
|
+
|
22
20
|
# Public: Create the structure of the project, that is many
|
23
21
|
# files and folders.
|
24
22
|
#
|
@@ -30,120 +28,127 @@ module Genit
|
|
30
28
|
puts "Cannot create project..."
|
31
29
|
end
|
32
30
|
end
|
33
|
-
|
31
|
+
|
34
32
|
private
|
35
|
-
|
36
|
-
def create_the_project
|
37
|
-
create_the_project_folders
|
38
|
-
copy_the_project_files
|
39
|
-
create_the_project_config
|
40
|
-
end
|
41
|
-
|
42
|
-
def create_the_project_folders
|
43
|
-
FileUtils.makedirs @project_name
|
44
|
-
create_subfolders ['fragments', 'news', 'pages', 'scripts', 'styles', 'templates', 'www',
|
45
|
-
'styles/alsa', 'styles/yui', 'styles/images', 'public']
|
46
|
-
end
|
47
|
-
|
48
|
-
def copy_the_project_files
|
49
|
-
copy_main_template
|
50
|
-
copy_files ['templates/menu.html', 'styles/handheld.css', 'styles/print.css',
|
51
|
-
'styles/alsa/all.css', 'styles/yui/all.css', 'styles/yui/base.css',
|
52
|
-
'styles/yui/fonts.css', 'styles/yui/reset.css']
|
53
|
-
copy_index
|
54
|
-
copy_screen_css
|
55
|
-
end
|
56
33
|
|
57
|
-
|
58
|
-
|
59
|
-
|
34
|
+
def create_the_project
|
35
|
+
create_the_project_folders
|
36
|
+
copy_the_project_files
|
37
|
+
create_the_project_config
|
38
|
+
end
|
60
39
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
40
|
+
def create_the_project_folders
|
41
|
+
FileUtils.makedirs @project_name
|
42
|
+
create_subfolders ['src', 'src/fragments', 'src/news', 'src/pages',
|
43
|
+
'scripts', 'styles', 'src/templates',
|
44
|
+
'styles/images', 'public']
|
45
|
+
end
|
46
|
+
|
47
|
+
# Create some subfolders inside the project folder.
|
48
|
+
#
|
49
|
+
# a_array - An Array of String subfolder names
|
50
|
+
#
|
51
|
+
# Examples
|
52
|
+
#
|
53
|
+
# create_subfolders ['styles', 'scripts']
|
54
|
+
#
|
55
|
+
# create_subfolders ['styles/css/alsa', 'styles/css/yui',
|
56
|
+
# 'styles/css/images']
|
57
|
+
#
|
58
|
+
# Returns nothing.
|
59
|
+
def create_subfolders a_array
|
60
|
+
a_array.each {|dir| FileUtils.makedirs File.join(@project_name, dir) }
|
61
|
+
end
|
62
|
+
|
63
|
+
def copy_the_project_files
|
64
|
+
copy_main_template
|
65
|
+
copy_menu_template
|
66
|
+
copy_files ['styles/handheld.css', 'styles/print.css']
|
67
|
+
copy_index
|
68
|
+
copy_screen_css
|
69
|
+
end
|
70
|
+
|
71
|
+
def create_the_project_config
|
72
|
+
version = File.read(File.join($GENIT_PATH, 'VERSION')).strip
|
73
|
+
write_config version, '.genit'
|
74
|
+
|
75
|
+
config_file = { :address => 'http://www.example.com',
|
76
|
+
:rss => true,
|
77
|
+
:rss_title => 'RSS TITLE',
|
78
|
+
:rss_description => 'RSS DESCRIPTION'}.to_yaml
|
79
|
+
write_config config_file, 'config'
|
80
|
+
end
|
81
|
+
|
82
|
+
def write_config content, filename
|
83
|
+
dest = File.join @project_name, filename
|
84
|
+
File.open(dest, "w") {|out| out.puts content }
|
85
|
+
end
|
86
|
+
|
87
|
+
# Copy files to project.
|
88
|
+
#
|
89
|
+
# a_array - An Array of String "subfolder/file" names
|
90
|
+
#
|
91
|
+
# Example
|
92
|
+
#
|
93
|
+
# copy_files ['templates/main.html', 'pages/index.html']
|
94
|
+
#
|
95
|
+
# Returns nothing.
|
96
|
+
def copy_files a_array
|
97
|
+
a_array.each do |file|
|
98
|
+
src = File.join $GENIT_PATH, 'data', file
|
99
|
+
dest = File.join @project_name, file
|
100
|
+
FileUtils.cp src, dest
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# TODO document
|
105
|
+
def copy_index
|
106
|
+
dest = File.join @project_name, 'src/pages/index.html'
|
107
|
+
if @empty
|
108
|
+
src = File.join $GENIT_PATH, 'data/pages/index2.html'
|
109
|
+
else
|
110
|
+
src = File.join $GENIT_PATH, 'data/pages/index.html'
|
111
|
+
end
|
101
112
|
FileUtils.cp src, dest
|
102
113
|
end
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
114
|
+
|
115
|
+
# TODO document
|
116
|
+
def copy_screen_css
|
117
|
+
dest = File.join @project_name, 'styles/screen.css'
|
118
|
+
if @empty
|
119
|
+
FileUtils.touch dest
|
120
|
+
else
|
121
|
+
src = File.join $GENIT_PATH, 'data/styles/screen.css'
|
122
|
+
FileUtils.cp src, dest
|
123
|
+
end
|
112
124
|
end
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
125
|
+
|
126
|
+
# TODO document
|
127
|
+
def copy_main_template
|
128
|
+
dest = File.join @project_name, 'src/templates', 'main.html'
|
129
|
+
copy_first_part dest
|
130
|
+
ProjectCreator.append_last_part dest
|
131
|
+
end
|
132
|
+
|
133
|
+
def copy_menu_template
|
134
|
+
dest = File.join @project_name, 'src/templates', 'menu.html'
|
135
|
+
src = File.join $GENIT_PATH, 'data', 'templates', 'menu.html'
|
123
136
|
FileUtils.cp src, dest
|
124
137
|
end
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
# @TODO document
|
141
|
-
def self.append_last_part dest
|
142
|
-
src = File.join $GENIT_PATH, 'data', 'templates', 'main.html'
|
143
|
-
content = File.open(src, "r").read
|
144
|
-
File.open(dest, "a") {|out| out.puts content }
|
145
|
-
end
|
146
|
-
|
138
|
+
|
139
|
+
# TODO document
|
140
|
+
def copy_first_part dest
|
141
|
+
src = File.join $GENIT_PATH, 'data', 'templates', "html_5"
|
142
|
+
FileUtils.cp src, dest
|
143
|
+
end
|
144
|
+
|
145
|
+
# TODO document
|
146
|
+
def self.append_last_part dest
|
147
|
+
src = File.join $GENIT_PATH, 'data', 'templates', 'main.html'
|
148
|
+
content = File.open(src, "r").read
|
149
|
+
File.open(dest, "a") {|out| out.puts content }
|
150
|
+
end
|
151
|
+
|
147
152
|
end
|
148
153
|
|
149
154
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
module Genit
|
6
|
+
|
7
|
+
# My responsability is to clean the root directory before a
|
8
|
+
# compilation. I have to keep alive some files (.genit, config) and
|
9
|
+
# some folders (src/, public/, etc).
|
10
|
+
class RootCleaner
|
11
|
+
|
12
|
+
# Public: Constructor.
|
13
|
+
#
|
14
|
+
# wd - The String working directory, where live the project.
|
15
|
+
def initialize wd
|
16
|
+
@wd = wd
|
17
|
+
end
|
18
|
+
|
19
|
+
# Public: Clean the root directory.
|
20
|
+
#
|
21
|
+
# Returns nothing.
|
22
|
+
def clean
|
23
|
+
Dir.foreach(@wd) do |file|
|
24
|
+
next if file.start_with?('.') or (file == "config")
|
25
|
+
filename = File.join(@wd, file)
|
26
|
+
FileUtils.remove_file(filename) if File.file?(filename)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -8,7 +8,7 @@ module Genit
|
|
8
8
|
# To generate the RSS file, we need data from the project config
|
9
9
|
# file (.config) and the list of the news.
|
10
10
|
class RssFeed
|
11
|
-
|
11
|
+
|
12
12
|
# Public: Constructor.
|
13
13
|
#
|
14
14
|
# working_dir - The String working directory, where live the project.
|
@@ -19,9 +19,9 @@ module Genit
|
|
19
19
|
@working_dir = working_dir
|
20
20
|
@news_files = news_files
|
21
21
|
@config = config
|
22
|
-
@destination = File.join(@working_dir, '
|
22
|
+
@destination = File.join(@working_dir, 'rss.xml')
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
# Public: Generate the RSS file (named rss.xml) at the web site
|
26
26
|
# root (www/).
|
27
27
|
def generate_rss
|
@@ -31,9 +31,9 @@ module Genit
|
|
31
31
|
end
|
32
32
|
File.open(@destination, "w") { |file| file.write(content) }
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
# Meta data of an RSS Field
|
38
38
|
class RssFeedMeta
|
39
39
|
def self.fill feed, config
|
@@ -44,16 +44,16 @@ module Genit
|
|
44
44
|
feed.items.do_sort = true
|
45
45
|
end
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
# Items of an RSS Field
|
49
49
|
class RssFeedItems
|
50
|
-
|
50
|
+
|
51
51
|
def initialize feed, news_files, config
|
52
52
|
@feed = feed
|
53
53
|
@news_files = news_files
|
54
54
|
@config = config
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
def fill
|
58
58
|
@news_files.each do |news|
|
59
59
|
item = @feed.items.new_item
|
@@ -62,13 +62,13 @@ module Genit
|
|
62
62
|
item.date = Time.parse(NewsUtils.get_date_from_filename(news))
|
63
63
|
end
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
66
|
end
|
67
|
-
|
67
|
+
|
68
68
|
# Retrieve the title element of an item element of an RSS feed
|
69
69
|
# from a news article.
|
70
70
|
class RssFeedItemTitle
|
71
|
-
|
71
|
+
|
72
72
|
# Public: Get the first title content from a news article.
|
73
73
|
#
|
74
74
|
# We first search for <h1> header level, then <h2>, etc to <h6>.
|
@@ -78,7 +78,7 @@ module Genit
|
|
78
78
|
#
|
79
79
|
# Returns the String title of the news article.
|
80
80
|
attr_reader :title
|
81
|
-
|
81
|
+
|
82
82
|
def initialize news_pathname
|
83
83
|
@news_pathname = news_pathname
|
84
84
|
@title = NewsUtils.get_date_from_filename @news_pathname
|
@@ -91,7 +91,7 @@ module Genit
|
|
91
91
|
end
|
92
92
|
end
|
93
93
|
end
|
94
|
-
|
94
|
+
|
95
95
|
end
|
96
|
-
|
96
|
+
|
97
97
|
end
|