amber 0.3.8 → 0.3.11
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.
- 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
|