amber 0.3.8 → 0.3.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/amber.rb +7 -2
- data/lib/amber/cli.rb +20 -9
- data/lib/amber/render/apache.rb +1 -1
- data/lib/amber/render/asset.rb +2 -2
- data/lib/amber/render/filter/autolink.rb +84 -0
- data/lib/amber/render/filter/bracketlink.rb +39 -0
- data/lib/amber/render/filter/variables.rb +29 -0
- data/lib/amber/render/helpers/blog_helper.rb +1 -1
- data/lib/amber/render/helpers/navigation_helper.rb +1 -1
- data/lib/amber/render/table_of_contents.rb +1 -0
- data/lib/amber/render/template.rb +23 -8
- data/lib/amber/render/view.rb +20 -16
- data/lib/amber/server.rb +3 -3
- data/lib/amber/site.rb +5 -5
- data/lib/amber/site_configuration.rb +3 -2
- data/lib/amber/site_loader.rb +95 -0
- data/lib/amber/static_page.rb +15 -3
- data/lib/amber/static_page/filesystem.rb +139 -16
- data/lib/amber/static_page/property_set.rb +13 -2
- data/lib/amber/static_page/render.rb +1 -1
- data/lib/amber/templates/config.rb +4 -0
- data/lib/amber/version.rb +1 -1
- metadata +8 -4
- data/lib/amber/render/autolink.rb +0 -78
- data/lib/amber/render/bracketlink.rb +0 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f07ec2e5c2a86cec442c924598f935a40955a32
|
4
|
+
data.tar.gz: 4eaecfe55678b175942014c5e17f6e90381021b6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: efa8c04a618b8ba9052c6b4f0f1387bb750e20a3544e6afe79668cee9de9278c44168c2ce00fe70fc14c8dc4a3faebdb6a5b069e059cd913adc37373f8ade543
|
7
|
+
data.tar.gz: 78c14db10c74f733f0cc1899715ccbf771a3bd9b29aebdf84af8d24bd0025845ced2b0df3adfa5c7237e63619defe0932eae0280561f66f1a0051f8d8c21d3b7
|
data/lib/amber.rb
CHANGED
@@ -21,6 +21,10 @@ module Amber
|
|
21
21
|
# Possible page suffixes. Only files with these suffixes are treated as pages
|
22
22
|
PAGE_SUFFIXES = %w(haml md markdown text textile rst html html.haml)
|
23
23
|
|
24
|
+
# Possible variable file suffixes. Only files with these suffixesare treated
|
25
|
+
# as variable files.
|
26
|
+
VAR_SUFFIXES = %w(json yaml yml)
|
27
|
+
|
24
28
|
DEFAULT_HOST = '127.0.0.1'
|
25
29
|
DEFAULT_PORT = '8000'
|
26
30
|
|
@@ -56,7 +60,8 @@ require 'amber/render/layout'
|
|
56
60
|
require 'amber/render/view'
|
57
61
|
require 'amber/render/template'
|
58
62
|
require 'amber/render/asset'
|
59
|
-
require 'amber/render/autolink'
|
60
|
-
require 'amber/render/bracketlink'
|
61
63
|
require 'amber/render/table_of_contents'
|
62
64
|
require 'amber/render/apache'
|
65
|
+
require 'amber/render/filter/autolink'
|
66
|
+
require 'amber/render/filter/bracketlink'
|
67
|
+
require 'amber/render/filter/variables'
|
data/lib/amber/cli.rb
CHANGED
@@ -13,7 +13,7 @@ module Amber
|
|
13
13
|
new_dir = options[:arg]
|
14
14
|
mkdir(new_dir, nil)
|
15
15
|
mkdir('amber', new_dir)
|
16
|
-
|
16
|
+
copy_template_file('config.rb', 'amber', new_dir)
|
17
17
|
touch('amber/menu.txt', new_dir)
|
18
18
|
mkdir('amber/layouts', new_dir)
|
19
19
|
mkdir('amber/locales', new_dir)
|
@@ -40,8 +40,8 @@ module Amber
|
|
40
40
|
site = Site.new(@root)
|
41
41
|
site.continue_on_error = false
|
42
42
|
site.load_pages
|
43
|
-
FileUtils.mkdir_p(site.dest_dir) unless File.
|
44
|
-
gitkeep = File.
|
43
|
+
FileUtils.mkdir_p(site.dest_dir) unless File.exist?(site.dest_dir)
|
44
|
+
gitkeep = File.exist?(File.join(site.dest_dir, '.gitkeep'))
|
45
45
|
temp_render = File.join(File.dirname(site.dest_dir), 'public-tmp')
|
46
46
|
temp_old_pages = File.join(File.dirname(site.dest_dir), 'remove-me')
|
47
47
|
site.with_destination(temp_render) do
|
@@ -58,8 +58,8 @@ module Amber
|
|
58
58
|
end
|
59
59
|
ensure
|
60
60
|
# cleanup if something goes wrong.
|
61
|
-
FileUtils.rm_r(temp_render) if temp_render && File.
|
62
|
-
FileUtils.rm_r(temp_old_pages) if temp_old_pages && File.
|
61
|
+
FileUtils.rm_r(temp_render) if temp_render && File.exist?(temp_render)
|
62
|
+
FileUtils.rm_r(temp_old_pages) if temp_old_pages && File.exist?(temp_old_pages)
|
63
63
|
end
|
64
64
|
|
65
65
|
def server(options)
|
@@ -100,8 +100,8 @@ module Amber
|
|
100
100
|
path = dir
|
101
101
|
print_path = dir
|
102
102
|
end
|
103
|
-
unless Dir.
|
104
|
-
if File.
|
103
|
+
unless Dir.exist?(path)
|
104
|
+
if File.exist?(path)
|
105
105
|
puts "Could not make directory `#{print_path}`. File already exists."
|
106
106
|
exit(1)
|
107
107
|
end
|
@@ -112,11 +112,22 @@ module Amber
|
|
112
112
|
|
113
113
|
def touch(file, context)
|
114
114
|
path = File.join(context, file)
|
115
|
-
unless File.
|
115
|
+
unless File.exist?(path)
|
116
116
|
FileUtils.touch(path)
|
117
117
|
puts "* Creating `#{File.basename(context)}/#{file}`"
|
118
118
|
end
|
119
119
|
end
|
120
120
|
|
121
|
+
def copy_template_file(template_file, destination, context)
|
122
|
+
template_file_path = File.dirname(__FILE__) + "/templates/#{template_file}"
|
123
|
+
copy(template_file_path, destination, context)
|
124
|
+
end
|
125
|
+
|
126
|
+
def copy(source, destination, context)
|
127
|
+
destination_path = File.join(context, destination)
|
128
|
+
FileUtils.copy(source, destination_path)
|
129
|
+
puts "* Creating `#{File.basename(context)}/#{destination}/#{File.basename(source)}`"
|
130
|
+
end
|
131
|
+
|
121
132
|
end
|
122
|
-
end
|
133
|
+
end
|
data/lib/amber/render/apache.rb
CHANGED
@@ -8,7 +8,7 @@ module Amber
|
|
8
8
|
template = Tilt::ERBTemplate.new(template_path("htaccess.erb"))
|
9
9
|
|
10
10
|
tail_content = nil
|
11
|
-
if File.
|
11
|
+
if File.exist?(src_htaccess_file)
|
12
12
|
tail_content = File.read(src_htaccess_file)
|
13
13
|
end
|
14
14
|
File.open(dst_htaccess_file, 'w', :encoding => 'UTF-8') do |f|
|
data/lib/amber/render/asset.rb
CHANGED
@@ -19,10 +19,10 @@ module Amber
|
|
19
19
|
}
|
20
20
|
|
21
21
|
def self.render(src_file, dst_file)
|
22
|
-
unless Dir.
|
22
|
+
unless Dir.exist?(File.dirname(dst_file))
|
23
23
|
FileUtils.mkdir_p(File.dirname(dst_file))
|
24
24
|
end
|
25
|
-
File.unlink(dst_file) if File.
|
25
|
+
File.unlink(dst_file) if File.exist?(dst_file)
|
26
26
|
src_ext = File.extname(src_file)
|
27
27
|
renderer = RENDER_MAP[src_ext]
|
28
28
|
if renderer
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# adapted from https://github.com/tenderlove/rails_autolink
|
3
|
+
# MIT license
|
4
|
+
|
5
|
+
module Amber
|
6
|
+
module Render
|
7
|
+
module Filter
|
8
|
+
module Autolink
|
9
|
+
|
10
|
+
def self.run(text)
|
11
|
+
auto_link_email_addresses(auto_link_urls(text))
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
AUTO_LINK_RE = %r{
|
17
|
+
(?: ((?:ed2k|ftp|http|https|irc|mailto|news|gopher|nntp|telnet|webcal|xmpp|callto|feed|svn|urn|aim|rsync|tag|ssh|sftp|rtsp|afs|file):)// | www\. )
|
18
|
+
[^\s<\u00A0]+
|
19
|
+
}ix
|
20
|
+
|
21
|
+
# regexps for determining context, used high-volume
|
22
|
+
AUTO_LINK_CRE = [/<[^>]+$/, /^[^>]*>/, /<a\b.*?>/i, /<\/a>/i]
|
23
|
+
|
24
|
+
AUTO_EMAIL_LOCAL_RE = /[\w.!#\$%&'*\/=?^`{|}~+-]/
|
25
|
+
AUTO_EMAIL_RE = /[\w.!#\$%+-]\.?#{AUTO_EMAIL_LOCAL_RE}*@[\w-]+(?:\.[\w-]+)+/
|
26
|
+
|
27
|
+
BRACKETS = { ']' => '[', ')' => '(', '}' => '{' }
|
28
|
+
|
29
|
+
WORD_PATTERN = RUBY_VERSION < '1.9' ? '\w' : '\p{Word}'
|
30
|
+
|
31
|
+
# Turns all urls into clickable links. If a block is given, each url
|
32
|
+
# is yielded and the result is used as the link text.
|
33
|
+
def self.auto_link_urls(text)
|
34
|
+
text.gsub(AUTO_LINK_RE) do
|
35
|
+
scheme, href = $1, $&
|
36
|
+
punctuation = []
|
37
|
+
|
38
|
+
if auto_linked?($`, $')
|
39
|
+
# do not change string; URL is already linked
|
40
|
+
href
|
41
|
+
else
|
42
|
+
# don't include trailing punctuation character as part of the URL
|
43
|
+
while href.sub!(/[^#{WORD_PATTERN}\/-]$/, '')
|
44
|
+
punctuation.push $&
|
45
|
+
if opening = BRACKETS[punctuation.last] and href.scan(opening).size > href.scan(punctuation.last).size
|
46
|
+
href << punctuation.pop
|
47
|
+
break
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
#link_text = block_given?? yield(href) : href
|
52
|
+
link_text = href.sub(/^#{scheme}\/\//,'')
|
53
|
+
href = 'http://' + href unless scheme
|
54
|
+
%(<a href="#{href}">#{link_text}</a>) + punctuation.reverse.join('')
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Turns all email addresses into clickable links.
|
60
|
+
def self.auto_link_email_addresses(text)
|
61
|
+
text.gsub(AUTO_EMAIL_RE) do
|
62
|
+
text = $&
|
63
|
+
|
64
|
+
if auto_linked?($`, $')
|
65
|
+
text
|
66
|
+
else
|
67
|
+
#display_text = (block_given?) ? yield(text) : text
|
68
|
+
#display_text = text
|
69
|
+
text.gsub!('@', '@').gsub!('.', '.')
|
70
|
+
%(<a href="mailto:#{text}">#{text}</a>)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Detects already linked context or position in the middle of a tag
|
76
|
+
def self.auto_linked?(left, right)
|
77
|
+
(left =~ AUTO_LINK_CRE[0] and right =~ AUTO_LINK_CRE[1]) or
|
78
|
+
(left.rindex(AUTO_LINK_CRE[2]) and $' !~ AUTO_LINK_CRE[3])
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
#
|
4
|
+
# bracket links are links in the form [[label => target]] or [[page-name]]
|
5
|
+
#
|
6
|
+
|
7
|
+
module Amber
|
8
|
+
module Render
|
9
|
+
module Filter
|
10
|
+
module Bracketlink
|
11
|
+
|
12
|
+
# linking using double square brackets
|
13
|
+
BRACKET_LINK_RE = /
|
14
|
+
\[\[ # start [[
|
15
|
+
([^\[\]]+) # $text : one or more characters that are not [ or ] ($1)
|
16
|
+
\]\] # end ]]
|
17
|
+
/x
|
18
|
+
|
19
|
+
def self.run(text, &block)
|
20
|
+
text.gsub(BRACKET_LINK_RE) do |m|
|
21
|
+
link_text = $~[1].strip
|
22
|
+
if link_text =~ /^.+\s*[-=]>\s*.+$/
|
23
|
+
# link_text == "from -> to"
|
24
|
+
from, to = link_text.split(/\s*[-=]>\s*/)[0..1]
|
25
|
+
from = "" unless from.instance_of? String # \ sanity check for
|
26
|
+
to = "" unless from.instance_of? String # / badly formed links
|
27
|
+
else
|
28
|
+
# link_text == "to" (ie, no link label)
|
29
|
+
from = nil
|
30
|
+
to = link_text
|
31
|
+
end
|
32
|
+
yield(from, to)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
#
|
4
|
+
# bracket links are links in the form [[label => target]] or [[page-name]]
|
5
|
+
#
|
6
|
+
|
7
|
+
module Amber
|
8
|
+
module Render
|
9
|
+
module Filter
|
10
|
+
module Variables
|
11
|
+
|
12
|
+
# variable expansion uses {{ }}
|
13
|
+
VARIABLES_RE = /
|
14
|
+
\{\{ # start {{
|
15
|
+
([^\{\}]+) # $text : one or more characters that are not { or } ($1)
|
16
|
+
\}\} # end }}
|
17
|
+
/x
|
18
|
+
|
19
|
+
def self.run(text, &block)
|
20
|
+
text.gsub(VARIABLES_RE) do |m|
|
21
|
+
variable_name = $~[1].strip
|
22
|
+
yield(variable_name)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -6,7 +6,7 @@ module Amber
|
|
6
6
|
limit = options[:limit] || @site.pagination_size
|
7
7
|
order = options[:order] || :posted_at
|
8
8
|
direction = options[:direction] || :desc
|
9
|
-
partial = options[:partial]
|
9
|
+
#partial = options[:partial]
|
10
10
|
if options[:path]
|
11
11
|
@site.find_page(options[:path])
|
12
12
|
else
|
@@ -108,7 +108,7 @@ module Amber
|
|
108
108
|
levels_max = options[:levels] || 1
|
109
109
|
level = options.delete(:level) || 1
|
110
110
|
heading = options.delete(:heading) || 2
|
111
|
-
locale = @locals[:locale]
|
111
|
+
#locale = @locals[:locale]
|
112
112
|
menu = submenu_for_page(page)
|
113
113
|
if menu && menu.children.any?
|
114
114
|
children = menu.children
|
@@ -125,7 +125,10 @@ module Amber
|
|
125
125
|
|
126
126
|
def render_haml(file_path, view)
|
127
127
|
template = Tilt::HamlTemplate.new(file_path, {:format => :html5, :default_encoding => 'UTF-8'})
|
128
|
-
|
128
|
+
html = template.render(view, view.locals)
|
129
|
+
html = add_variables(view, html)
|
130
|
+
html = add_bracket_links(view, html)
|
131
|
+
return html
|
129
132
|
rescue Haml::Error => ex
|
130
133
|
msg = "Line #{ex.line + 1} of file `#{file_path}`: #{ex.to_s}"
|
131
134
|
Amber::logger.error(msg)
|
@@ -133,34 +136,46 @@ module Amber
|
|
133
136
|
end
|
134
137
|
|
135
138
|
def render_textile(view, content)
|
139
|
+
content = add_variables(view, content)
|
136
140
|
content = add_bracket_links(view, content)
|
137
|
-
Autolink.
|
141
|
+
return Filter::Autolink.run(RedCloth.new(content).to_html)
|
138
142
|
end
|
139
143
|
|
140
144
|
def render_markdown(view, content)
|
145
|
+
content = add_variables(view, content)
|
141
146
|
content = add_bracket_links(view, content)
|
142
|
-
RDiscount.new(content, :smart, :autolink).to_html
|
147
|
+
return RDiscount.new(content, :smart, :autolink).to_html
|
143
148
|
end
|
144
149
|
|
145
150
|
def render_raw(view, content)
|
146
|
-
|
151
|
+
content = add_variables(view, content)
|
152
|
+
content = add_bracket_links(view, content)
|
153
|
+
return content
|
147
154
|
end
|
148
155
|
|
149
156
|
def render_none(view, content)
|
150
|
-
content
|
157
|
+
return content
|
151
158
|
end
|
152
159
|
|
153
160
|
def add_bracket_links(view, content)
|
154
|
-
content = Bracketlink.
|
161
|
+
content = Filter::Bracketlink.run(content) do |from, to|
|
155
162
|
view.link({from => to})
|
156
163
|
end
|
157
|
-
content
|
164
|
+
return content
|
165
|
+
end
|
166
|
+
|
167
|
+
def add_variables(view, content)
|
168
|
+
locale = view.locals[:locale]
|
169
|
+
content = Filter::Variables.run(content) do |var_name|
|
170
|
+
view.page.var(var_name, locale) || var_name
|
171
|
+
end
|
172
|
+
return content
|
158
173
|
end
|
159
174
|
|
160
175
|
def type_from_file(file_path)
|
161
176
|
suffix = File.extname(file_path)
|
162
177
|
if suffix
|
163
|
-
suffix.sub!
|
178
|
+
suffix.sub!(/^\./, '')
|
164
179
|
suffix = suffix.to_sym
|
165
180
|
end
|
166
181
|
suffix
|
data/lib/amber/render/view.rb
CHANGED
@@ -57,6 +57,7 @@ module Amber
|
|
57
57
|
@page = options[:page] if options[:page]
|
58
58
|
render_toc = should_render_toc?(locale, options, @page)
|
59
59
|
template = pick_template(locale, options)
|
60
|
+
return unless template
|
60
61
|
if toc_only
|
61
62
|
template.render(self, :mode => :toc, :href_base => options[:href_base])
|
62
63
|
else
|
@@ -90,32 +91,33 @@ module Amber
|
|
90
91
|
# search possible paths for the file to be rendered.
|
91
92
|
# called only from parse_render_options()
|
92
93
|
#
|
93
|
-
def find_file(
|
94
|
-
return
|
95
|
-
|
96
|
-
|
97
|
-
"#{site.pages_dir}/#{
|
98
|
-
"#{page.file_path}/#{
|
99
|
-
"#{File.dirname(page.file_path)}/#{
|
100
|
-
"#{site.config_dir}/#{
|
94
|
+
def find_file(search_path, site, page, locale)
|
95
|
+
return search_path if File.exist?(search_path)
|
96
|
+
searches = [
|
97
|
+
search_path,
|
98
|
+
"#{site.pages_dir}/#{search_path}",
|
99
|
+
"#{page.file_path}/#{search_path}",
|
100
|
+
"#{File.dirname(page.file_path)}/#{search_path}",
|
101
|
+
"#{site.config_dir}/#{search_path}"
|
101
102
|
]
|
102
103
|
# attempt to find a file with preferred locale
|
103
|
-
|
104
|
-
return path if File.
|
104
|
+
searches.each do |path|
|
105
|
+
return path if File.exist?(path)
|
105
106
|
Dir["#{path}.#{locale}.#{StaticPage::PAGE_SUFFIXES_GLOB}"].each do |path_with_locale|
|
106
|
-
return path_with_locale if File.
|
107
|
+
return path_with_locale if File.exist?(path_with_locale)
|
107
108
|
end
|
108
109
|
Dir["#{path}.#{StaticPage::PAGE_SUFFIXES_GLOB}"].each do |path_with_suffix|
|
109
|
-
return path_with_suffix if File.
|
110
|
+
return path_with_suffix if File.exist?(path_with_suffix)
|
110
111
|
end
|
111
112
|
end
|
112
113
|
# attempt to find a file with default locale
|
113
|
-
|
114
|
-
Dir["#{
|
115
|
-
return path_with_locale if File.
|
114
|
+
searches.each do |path2|
|
115
|
+
Dir["#{path2}.#{I18n.default_locale}.#{StaticPage::PAGE_SUFFIXES_GLOB}"].each do |path_with_locale|
|
116
|
+
return path_with_locale if File.exist?(path_with_locale)
|
116
117
|
end
|
117
118
|
end
|
118
|
-
|
119
|
+
Amber.logger.error("No such path `#{path2}` from `#{page.content_file(locale)}`.")
|
120
|
+
return nil
|
119
121
|
end
|
120
122
|
|
121
123
|
def partialize(path)
|
@@ -181,6 +183,8 @@ module Amber
|
|
181
183
|
Template.new(file: options[:partial], partial: true)
|
182
184
|
elsif options[:text]
|
183
185
|
Template.new(content: options[:text], type: (options[:type] || :text))
|
186
|
+
else
|
187
|
+
nil
|
184
188
|
end
|
185
189
|
end
|
186
190
|
|
data/lib/amber/server.rb
CHANGED
@@ -138,11 +138,11 @@ module Amber
|
|
138
138
|
@server.site.render
|
139
139
|
page.render_to_file(dst_dir, :force => true)
|
140
140
|
file = page.destination_file(dst_dir, locale)
|
141
|
-
if File.
|
141
|
+
if File.exist?(file)
|
142
142
|
content = File.read(file)
|
143
143
|
else
|
144
144
|
file = page.destination_file(dst_dir, I18n.default_locale)
|
145
|
-
if File.
|
145
|
+
if File.exist?(file)
|
146
146
|
content = File.read(file)
|
147
147
|
else
|
148
148
|
view = Render::View.new(page, @server.site)
|
@@ -162,7 +162,7 @@ module Amber
|
|
162
162
|
base_path = path.sub(RENDERABLE_ASSET_RE, '')
|
163
163
|
Amber::Render::Asset::SOURCE_MAP[dest_suffix].each do |source_suffix|
|
164
164
|
source_file_path = File.join(src_dir, base_path + source_suffix)
|
165
|
-
if File.
|
165
|
+
if File.exist?(source_file_path)
|
166
166
|
return source_file_path
|
167
167
|
end
|
168
168
|
end
|
data/lib/amber/site.rb
CHANGED
@@ -81,8 +81,8 @@ module Amber
|
|
81
81
|
# Which would match "/services/chat/security" but not "/services/security"
|
82
82
|
#
|
83
83
|
def find_pages(filter)
|
84
|
-
|
85
|
-
|
84
|
+
filter = filter.downcase
|
85
|
+
if filter =~ /\//
|
86
86
|
path = filter.split('/').map{|segment| segment.gsub(/[^0-9a-z_-]/, '')}
|
87
87
|
path_str = path.join('/')
|
88
88
|
if (page = @pages_by_path[path_str])
|
@@ -152,9 +152,9 @@ module Amber
|
|
152
152
|
@root
|
153
153
|
else
|
154
154
|
name = File.basename(config.path)
|
155
|
-
|
156
|
-
add_page(
|
157
|
-
|
155
|
+
sub_root = StaticPage.new(find_parent(config.path), name, config.pages_dir, config.path_prefix)
|
156
|
+
add_page(sub_root)
|
157
|
+
sub_root
|
158
158
|
end
|
159
159
|
end
|
160
160
|
base_page.config = config
|
@@ -56,6 +56,7 @@ module Amber
|
|
56
56
|
#
|
57
57
|
def initialize(site, root_dir, options={})
|
58
58
|
@children = []
|
59
|
+
@path_prefix = nil
|
59
60
|
@site = site
|
60
61
|
@root_dir = File.expand_path(find_in_directory_tree('amber', 'config.rb', root_dir))
|
61
62
|
if @root_dir == '/'
|
@@ -119,7 +120,7 @@ module Amber
|
|
119
120
|
|
120
121
|
def config_path(file)
|
121
122
|
path = File.join(@config_dir, file)
|
122
|
-
if File.
|
123
|
+
if File.exist?(path)
|
123
124
|
path
|
124
125
|
else
|
125
126
|
nil
|
@@ -134,7 +135,7 @@ module Amber
|
|
134
135
|
search_dir = directory_tree || Dir.pwd
|
135
136
|
while search_dir != "/"
|
136
137
|
Dir.foreach(search_dir) do |f|
|
137
|
-
if f == target_dir_name && File.
|
138
|
+
if f == target_dir_name && File.exist?(File.join(search_dir, f,target_file_name))
|
138
139
|
return search_dir
|
139
140
|
end
|
140
141
|
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
#
|
2
|
+
# responsible for loading all the pages of the site.
|
3
|
+
#
|
4
|
+
|
5
|
+
WORK IN PROGRESS, FACTOR OUT FROM SITE
|
6
|
+
|
7
|
+
module Amber
|
8
|
+
class SiteLoader
|
9
|
+
|
10
|
+
#
|
11
|
+
# page_paths
|
12
|
+
# pages_by_name
|
13
|
+
# pages_by_path
|
14
|
+
# pages_by_locale_path
|
15
|
+
# root
|
16
|
+
# dir_list
|
17
|
+
#
|
18
|
+
def self.load(config)
|
19
|
+
config.reset_timestamp
|
20
|
+
|
21
|
+
# create base_page
|
22
|
+
base_page = begin
|
23
|
+
if config.path.nil?
|
24
|
+
@root = StaticPage.new(nil, 'root', config.pages_dir)
|
25
|
+
add_page(@root)
|
26
|
+
@root
|
27
|
+
else
|
28
|
+
name = File.basename(config.path)
|
29
|
+
page = StaticPage.new(find_parent(config.path), name, config.pages_dir, config.path_prefix)
|
30
|
+
add_page(page)
|
31
|
+
page
|
32
|
+
end
|
33
|
+
end
|
34
|
+
base_page.config = config
|
35
|
+
|
36
|
+
# load menu and locals
|
37
|
+
I18n.load_path += Dir[File.join(config.locales_dir, '/*.{rb,yml,yaml}')] if config.locales_dir
|
38
|
+
|
39
|
+
# add the full directory tree
|
40
|
+
base_page.scan_directory_tree do |page, asset_dir|
|
41
|
+
add_page(page) if page
|
42
|
+
@dir_list << asset_dir if asset_dir
|
43
|
+
end
|
44
|
+
@page_paths += @pages_by_path.keys
|
45
|
+
|
46
|
+
# recursively add sub-sites
|
47
|
+
config.children.each do |sub_config|
|
48
|
+
add_configuration(sub_config)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def self.find_parent(path)
|
55
|
+
so_far = []
|
56
|
+
path.split('/').compact.each do |path_segment|
|
57
|
+
so_far << path_segment
|
58
|
+
if page = @pages_by_path[so_far.join('/')]
|
59
|
+
return page
|
60
|
+
end
|
61
|
+
end
|
62
|
+
return @root
|
63
|
+
end
|
64
|
+
|
65
|
+
#
|
66
|
+
# registers a page with the site, indexing the page path in our various hashes
|
67
|
+
#
|
68
|
+
def add_page(page)
|
69
|
+
@pages_by_name[page.name] = page
|
70
|
+
@pages_by_path[page.path.join('/')] = page
|
71
|
+
add_aliases(I18n.default_locale, page, @pages_by_path)
|
72
|
+
page.locales.each do |locale|
|
73
|
+
next if locale == I18n.default_locale
|
74
|
+
add_aliases(locale, page, @pages_by_locale_path[locale])
|
75
|
+
end
|
76
|
+
@page_list << page
|
77
|
+
end
|
78
|
+
|
79
|
+
#
|
80
|
+
# registers a page's aliases with the site
|
81
|
+
#
|
82
|
+
def add_aliases(locale, page, path_hash)
|
83
|
+
page.aliases(locale).each do |alias_path|
|
84
|
+
alias_path_str = alias_path.join('/')
|
85
|
+
if path_hash[alias_path_str]
|
86
|
+
Amber.logger.warn "WARNING: page `#{page.path.join('/')}` has alias `#{alias_path_str}`, but this path is already taken by `#{path_hash[alias_path_str].path.join('/')}` (locale = #{locale})."
|
87
|
+
else
|
88
|
+
path_hash[alias_path_str] = page
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
data/lib/amber/static_page.rb
CHANGED
@@ -112,6 +112,14 @@ module Amber
|
|
112
112
|
@props.prop(*args)
|
113
113
|
end
|
114
114
|
|
115
|
+
def vars
|
116
|
+
@vars ||= load_variables
|
117
|
+
end
|
118
|
+
|
119
|
+
def var(name, locale=I18n.locale)
|
120
|
+
(vars[locale] || vars[I18n.default_locale] || {})[name.to_s]
|
121
|
+
end
|
122
|
+
|
115
123
|
#
|
116
124
|
# Returns array of locale symbols for all locales with properties set
|
117
125
|
# Note: there might be a content for a locale that does not show up in this array,
|
@@ -121,6 +129,10 @@ module Amber
|
|
121
129
|
@props.locales
|
122
130
|
end
|
123
131
|
|
132
|
+
def path_str
|
133
|
+
self.path.join('/')
|
134
|
+
end
|
135
|
+
|
124
136
|
#
|
125
137
|
# returns an array of normalized aliases based on the :alias property
|
126
138
|
# defined for a page.
|
@@ -132,9 +144,9 @@ module Amber
|
|
132
144
|
def aliases(locale=I18n.default_locale)
|
133
145
|
@aliases ||= begin
|
134
146
|
aliases_hash = Hash.new([])
|
135
|
-
@props.locales.each do |
|
136
|
-
aliases = @props.prop_without_inheritance(
|
137
|
-
aliases_hash[
|
147
|
+
@props.locales.each do |l|
|
148
|
+
aliases = @props.prop_without_inheritance(l, :alias)
|
149
|
+
aliases_hash[l] = begin
|
138
150
|
if aliases.nil?
|
139
151
|
[]
|
140
152
|
else
|
@@ -5,6 +5,8 @@
|
|
5
5
|
require 'i18n'
|
6
6
|
require 'pathname'
|
7
7
|
require 'fileutils'
|
8
|
+
require 'json'
|
9
|
+
require 'yaml'
|
8
10
|
|
9
11
|
module Amber
|
10
12
|
class StaticPage
|
@@ -106,11 +108,19 @@ module Amber
|
|
106
108
|
PAGE_SUFFIXES_RE = /(?<suffix>#{Amber::PAGE_SUFFIXES.join('|')})/
|
107
109
|
PAGE_SUFFIXES_GLOB = "{#{Amber::PAGE_SUFFIXES.join(',')}}"
|
108
110
|
|
111
|
+
# e.g. json, yaml
|
112
|
+
VAR_SUFFIXES_RE = /(?<suffix>#{Amber::VAR_SUFFIXES.join('|')})/
|
113
|
+
VAR_SUFFIXES_GLOB = "{#{Amber::VAR_SUFFIXES.join(',')}}"
|
114
|
+
|
109
115
|
# e.g. en.haml or es.md or index.pt.text
|
110
116
|
LOCALE_FILE_MATCH_RE = /^(index\.)?#{LOCALES_RE}\.#{PAGE_SUFFIXES_RE}$/
|
111
117
|
LOCALE_FILE_MATCH_GLOB = "{index.,}#{LOCALES_GLOB}.#{PAGE_SUFFIXES_GLOB}"
|
112
118
|
|
119
|
+
VAR_FILE_MATCH_RE = /^(index\.)?#{LOCALES_RE}\.#{VAR_SUFFIXES_RE}$/
|
120
|
+
VAR_FILE_MATCH_GLOB = "{index.,}#{LOCALES_GLOB}.#{VAR_SUFFIXES_GLOB}"
|
121
|
+
|
113
122
|
SIMPLE_FILE_MATCH_RE = lambda {|name| /^(#{Regexp.escape(name)})(\.#{LOCALES_RE})?\.#{PAGE_SUFFIXES_RE}$/ }
|
123
|
+
SIMPLE_VAR_MATCH_RE = lambda {|name| /^(#{Regexp.escape(name)})(\.#{LOCALES_RE})?\.#{VAR_SUFFIXES_RE}$/ }
|
114
124
|
|
115
125
|
private
|
116
126
|
|
@@ -198,11 +208,13 @@ module Amber
|
|
198
208
|
if @simple_page
|
199
209
|
[]
|
200
210
|
else
|
201
|
-
assets = {}
|
202
211
|
Dir.foreach(@file_path).collect { |file|
|
203
|
-
|
204
|
-
file
|
205
|
-
|
212
|
+
is_asset = \
|
213
|
+
file &&
|
214
|
+
file !~ /\.#{PAGE_SUFFIXES_RE}$/ &&
|
215
|
+
file !~ /^#{VAR_FILE_MATCH_RE}$/ &&
|
216
|
+
!File.directory?(File.join(@file_path, file))
|
217
|
+
file if is_asset
|
206
218
|
}.compact
|
207
219
|
end
|
208
220
|
end
|
@@ -223,24 +235,22 @@ module Amber
|
|
223
235
|
#
|
224
236
|
# (with or without leading hypen works)
|
225
237
|
#
|
226
|
-
#
|
238
|
+
# This text is extracted and evaluated as ruby to set properties.
|
239
|
+
#
|
240
|
+
# The first paragraph is loaded into the property "excerpt".
|
227
241
|
#
|
228
242
|
def load_properties
|
229
243
|
props = PageProperties.new(self)
|
230
244
|
content_files.each do |locale, content_file|
|
231
|
-
if
|
245
|
+
if type_from_path(content_file) == :haml
|
232
246
|
props.eval(File.read(content_file, :encoding => 'UTF-8'), locale)
|
233
247
|
else
|
234
|
-
headers =
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
line = '- ' + line
|
239
|
-
end
|
240
|
-
headers << line
|
241
|
-
end
|
248
|
+
headers, excerpt = parse_headers(content_file)
|
249
|
+
props.eval(headers, locale)
|
250
|
+
if !excerpt.empty?
|
251
|
+
props.set_prop(locale, "excerpt", excerpt)
|
242
252
|
end
|
243
|
-
props.
|
253
|
+
props.set_prop(locale, "content_type", type_from_path(content_file))
|
244
254
|
end
|
245
255
|
cleanup_properties(props, locale)
|
246
256
|
end
|
@@ -256,10 +266,123 @@ module Amber
|
|
256
266
|
end
|
257
267
|
end
|
258
268
|
|
269
|
+
#
|
270
|
+
# parses a content_file's property headers and tries to extract the
|
271
|
+
# first paragraph.
|
272
|
+
#
|
273
|
+
def parse_headers(content_file)
|
274
|
+
headers = []
|
275
|
+
para1 = []
|
276
|
+
para2 = []
|
277
|
+
file_type = type_from_path(content_file)
|
278
|
+
|
279
|
+
File.open(content_file, :encoding => 'UTF-8') do |f|
|
280
|
+
while (line = f.gets) =~ /^(- |)@\w/
|
281
|
+
if line !~ /^-/
|
282
|
+
line = '- ' + line
|
283
|
+
end
|
284
|
+
headers << line
|
285
|
+
end
|
286
|
+
# eat empty lines
|
287
|
+
while line = f.gets
|
288
|
+
break unless line =~ /^\s*$/
|
289
|
+
end
|
290
|
+
# grab first two paragraphs
|
291
|
+
para1 << line
|
292
|
+
while line = f.gets
|
293
|
+
break if line =~ /^\s*$/
|
294
|
+
para1 << line
|
295
|
+
end
|
296
|
+
while line = f.gets
|
297
|
+
break if line =~ /^\s*$/
|
298
|
+
para2 << line
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
headers = headers.join
|
303
|
+
para1 = para1.join
|
304
|
+
para2 = para2.join
|
305
|
+
excerpt = ""
|
306
|
+
|
307
|
+
# pick the first non-heading paragraph.
|
308
|
+
# this is stupid, and chokes on nested headings.
|
309
|
+
# but is also cheap and fast :)
|
310
|
+
if file_type == :textile
|
311
|
+
if para1 =~ /^h[1-5]\. /
|
312
|
+
excerpt = para2
|
313
|
+
else
|
314
|
+
excerpt = para1
|
315
|
+
end
|
316
|
+
elsif file_type == :markdown
|
317
|
+
if para1 =~ /^#+ / || para1 =~ /^(===+|---+)\s*$/m
|
318
|
+
excerpt = para2
|
319
|
+
else
|
320
|
+
excerpt = para1
|
321
|
+
end
|
322
|
+
end
|
323
|
+
return [headers, excerpt]
|
324
|
+
end
|
325
|
+
|
326
|
+
##
|
327
|
+
## VARIABLES
|
328
|
+
## Variables are associated with a page, but unlike properties they are not
|
329
|
+
## inheritable. Variables are defined in a separate file.
|
330
|
+
##
|
331
|
+
def variable_files
|
332
|
+
if @simple_page
|
333
|
+
directory = File.dirname(@file_path)
|
334
|
+
regexp = SIMPLE_VAR_MATCH_RE.call(@name)
|
335
|
+
else
|
336
|
+
directory = @file_path
|
337
|
+
regexp = VAR_FILE_MATCH_RE
|
338
|
+
end
|
339
|
+
hsh = {}
|
340
|
+
Dir.foreach(directory) do |file|
|
341
|
+
if file && match = regexp.match(file)
|
342
|
+
locale = match['locale'] || I18n.default_locale
|
343
|
+
hsh[locale.to_sym] = File.join(directory, file)
|
344
|
+
end
|
345
|
+
end
|
346
|
+
hsh
|
347
|
+
end
|
348
|
+
|
349
|
+
def load_variables
|
350
|
+
vars = {}
|
351
|
+
variable_files.each do |locale, var_file|
|
352
|
+
begin
|
353
|
+
if var_file =~ /\.ya?ml$/
|
354
|
+
vars[locale] = YAML.load_file(var_file)
|
355
|
+
elsif var_file =~ /\.json$/
|
356
|
+
vars[locale] = JSON.parse(File.read(var_file))
|
357
|
+
end
|
358
|
+
rescue StandardError => exc
|
359
|
+
Amber.logger.error('ERROR: could not load file #{var_file}: ' + exc.to_s)
|
360
|
+
end
|
361
|
+
end
|
362
|
+
return vars
|
363
|
+
end
|
364
|
+
|
365
|
+
def type_from_path(path)
|
366
|
+
case File.extname(path)
|
367
|
+
when ".text", ".textile"
|
368
|
+
:textile
|
369
|
+
when ".md", ".markdown"
|
370
|
+
:markdown
|
371
|
+
when ".haml"
|
372
|
+
:haml
|
373
|
+
when ".html"
|
374
|
+
:html
|
375
|
+
when ".erb"
|
376
|
+
:erb
|
377
|
+
else
|
378
|
+
:unknown
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
259
382
|
# RAILS
|
260
383
|
#def is_haml_template?(locale)
|
261
384
|
# content_file(locale) =~ /\.haml$/
|
262
|
-
# #@suffix == '.haml' || File.
|
385
|
+
# #@suffix == '.haml' || File.exist?(self.absolute_template_path(locale) + '.haml')
|
263
386
|
#end
|
264
387
|
|
265
388
|
end
|
@@ -39,11 +39,11 @@ module Amber
|
|
39
39
|
#
|
40
40
|
def get(property_name, inheritable_only=false)
|
41
41
|
if inheritable_only || @this.nil?
|
42
|
-
|
42
|
+
safe_instance_get("@#{property_name}")
|
43
43
|
else
|
44
44
|
value = @this.get(property_name)
|
45
45
|
if value.nil?
|
46
|
-
value =
|
46
|
+
value = safe_instance_get("@#{property_name}")
|
47
47
|
end
|
48
48
|
value
|
49
49
|
end
|
@@ -68,11 +68,22 @@ module Amber
|
|
68
68
|
def to_s
|
69
69
|
"<" + instance_variables.map{|v| "#{v}=#{instance_variable_get(v)}"}.join(', ') + ">"
|
70
70
|
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def safe_instance_get(prop_name)
|
75
|
+
if !instance_variable_defined?(prop_name)
|
76
|
+
instance_variable_set(prop_name, nil)
|
77
|
+
end
|
78
|
+
instance_variable_get(prop_name)
|
79
|
+
end
|
71
80
|
end
|
72
81
|
|
73
82
|
class ThisPropertySet < PropertySet
|
74
83
|
def initialize
|
84
|
+
@this = nil
|
75
85
|
end
|
76
86
|
end
|
87
|
+
|
77
88
|
end
|
78
89
|
end
|
@@ -122,7 +122,7 @@ module Amber
|
|
122
122
|
content_file = content_file(file_locale)
|
123
123
|
next unless content_file
|
124
124
|
dest = destination_file(dest_dir, file_locale)
|
125
|
-
unless Dir.
|
125
|
+
unless Dir.exist?(File.dirname(dest))
|
126
126
|
FileUtils.mkdir_p(File.dirname(dest))
|
127
127
|
end
|
128
128
|
if options[:force] || !File.exist?(dest) || File.mtime(content_file) > File.mtime(dest)
|
data/lib/amber/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: amber
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Elijah Sparrow
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-07-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: i18n
|
@@ -142,8 +142,9 @@ files:
|
|
142
142
|
- lib/amber/page_array.rb
|
143
143
|
- lib/amber/render/apache.rb
|
144
144
|
- lib/amber/render/asset.rb
|
145
|
-
- lib/amber/render/autolink.rb
|
146
|
-
- lib/amber/render/bracketlink.rb
|
145
|
+
- lib/amber/render/filter/autolink.rb
|
146
|
+
- lib/amber/render/filter/bracketlink.rb
|
147
|
+
- lib/amber/render/filter/variables.rb
|
147
148
|
- lib/amber/render/helpers/blog_helper.rb
|
148
149
|
- lib/amber/render/helpers/date_helper.rb
|
149
150
|
- lib/amber/render/helpers/haml_helper.rb
|
@@ -157,6 +158,7 @@ files:
|
|
157
158
|
- lib/amber/server.rb
|
158
159
|
- lib/amber/site.rb
|
159
160
|
- lib/amber/site_configuration.rb
|
161
|
+
- lib/amber/site_loader.rb
|
160
162
|
- lib/amber/static_page.rb
|
161
163
|
- lib/amber/static_page/filesystem.rb
|
162
164
|
- lib/amber/static_page/page_properties.rb
|
@@ -164,6 +166,7 @@ files:
|
|
164
166
|
- lib/amber/static_page/render.rb
|
165
167
|
- lib/amber/templates/apache_config.erb
|
166
168
|
- lib/amber/templates/apache_config_with_prefix.erb
|
169
|
+
- lib/amber/templates/config.rb
|
167
170
|
- lib/amber/templates/htaccess.erb
|
168
171
|
- lib/amber/version.rb
|
169
172
|
- locales/rails-i18n/af.yml
|
@@ -291,3 +294,4 @@ signing_key:
|
|
291
294
|
specification_version: 4
|
292
295
|
summary: Static website generator
|
293
296
|
test_files: []
|
297
|
+
has_rdoc:
|
@@ -1,78 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
# adapted from https://github.com/tenderlove/rails_autolink
|
3
|
-
# MIT license
|
4
|
-
|
5
|
-
module Amber::Render::Autolink
|
6
|
-
|
7
|
-
def self.auto_link(text)
|
8
|
-
auto_link_email_addresses(auto_link_urls(text))
|
9
|
-
end
|
10
|
-
|
11
|
-
private
|
12
|
-
|
13
|
-
AUTO_LINK_RE = %r{
|
14
|
-
(?: ((?:ed2k|ftp|http|https|irc|mailto|news|gopher|nntp|telnet|webcal|xmpp|callto|feed|svn|urn|aim|rsync|tag|ssh|sftp|rtsp|afs|file):)// | www\. )
|
15
|
-
[^\s<\u00A0]+
|
16
|
-
}ix
|
17
|
-
|
18
|
-
# regexps for determining context, used high-volume
|
19
|
-
AUTO_LINK_CRE = [/<[^>]+$/, /^[^>]*>/, /<a\b.*?>/i, /<\/a>/i]
|
20
|
-
|
21
|
-
AUTO_EMAIL_LOCAL_RE = /[\w.!#\$%&'*\/=?^`{|}~+-]/
|
22
|
-
AUTO_EMAIL_RE = /[\w.!#\$%+-]\.?#{AUTO_EMAIL_LOCAL_RE}*@[\w-]+(?:\.[\w-]+)+/
|
23
|
-
|
24
|
-
BRACKETS = { ']' => '[', ')' => '(', '}' => '{' }
|
25
|
-
|
26
|
-
WORD_PATTERN = RUBY_VERSION < '1.9' ? '\w' : '\p{Word}'
|
27
|
-
|
28
|
-
# Turns all urls into clickable links. If a block is given, each url
|
29
|
-
# is yielded and the result is used as the link text.
|
30
|
-
def self.auto_link_urls(text)
|
31
|
-
text.gsub(AUTO_LINK_RE) do
|
32
|
-
scheme, href = $1, $&
|
33
|
-
punctuation = []
|
34
|
-
|
35
|
-
if auto_linked?($`, $')
|
36
|
-
# do not change string; URL is already linked
|
37
|
-
href
|
38
|
-
else
|
39
|
-
# don't include trailing punctuation character as part of the URL
|
40
|
-
while href.sub!(/[^#{WORD_PATTERN}\/-]$/, '')
|
41
|
-
punctuation.push $&
|
42
|
-
if opening = BRACKETS[punctuation.last] and href.scan(opening).size > href.scan(punctuation.last).size
|
43
|
-
href << punctuation.pop
|
44
|
-
break
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
#link_text = block_given?? yield(href) : href
|
49
|
-
link_text = href.sub(/^#{scheme}\/\//,'')
|
50
|
-
href = 'http://' + href unless scheme
|
51
|
-
%(<a href="#{href}">#{link_text}</a>) + punctuation.reverse.join('')
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
# Turns all email addresses into clickable links.
|
57
|
-
def self.auto_link_email_addresses(text)
|
58
|
-
text.gsub(AUTO_EMAIL_RE) do
|
59
|
-
text = $&
|
60
|
-
|
61
|
-
if auto_linked?($`, $')
|
62
|
-
text
|
63
|
-
else
|
64
|
-
#display_text = (block_given?) ? yield(text) : text
|
65
|
-
#display_text = text
|
66
|
-
text.gsub!('@', '@').gsub!('.', '.')
|
67
|
-
%(<a href="mailto:#{text}">#{text}</a>)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
# Detects already linked context or position in the middle of a tag
|
73
|
-
def self.auto_linked?(left, right)
|
74
|
-
(left =~ AUTO_LINK_CRE[0] and right =~ AUTO_LINK_CRE[1]) or
|
75
|
-
(left.rindex(AUTO_LINK_CRE[2]) and $' !~ AUTO_LINK_CRE[3])
|
76
|
-
end
|
77
|
-
|
78
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
#
|
4
|
-
# bracket links are links in the form [[label => target]] or [[page-name]]
|
5
|
-
#
|
6
|
-
|
7
|
-
module Amber::Render::Bracketlink
|
8
|
-
|
9
|
-
# linking using double square brackets
|
10
|
-
BRACKET_LINK_RE = /
|
11
|
-
\[\[ # start [[
|
12
|
-
([^\[\]]+) # $text : one or more characters that are not [ or ] ($1)
|
13
|
-
\]\] # end ]]
|
14
|
-
/x
|
15
|
-
|
16
|
-
def self.bracket_link(text, &block)
|
17
|
-
text.gsub(BRACKET_LINK_RE) do |m|
|
18
|
-
link_text = $~[1].strip
|
19
|
-
if link_text =~ /^.+\s*[-=]>\s*.+$/
|
20
|
-
# link_text == "from -> to"
|
21
|
-
from, to = link_text.split(/\s*[-=]>\s*/)[0..1]
|
22
|
-
from = "" unless from.instance_of? String # \ sanity check for
|
23
|
-
to = "" unless from.instance_of? String # / badly formed links
|
24
|
-
else
|
25
|
-
# link_text == "to" (ie, no link label)
|
26
|
-
from = nil
|
27
|
-
to = link_text
|
28
|
-
end
|
29
|
-
yield(from, to)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|