hx 0.3.2 → 0.3.3

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/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009 MenTaLguY <mental@rydia.net>
1
+ Copyright (c) 2009-2010 MenTaLguY <mental@rydia.net>
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.2
1
+ 0.3.3
data/lib/hx.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # hx - A very small website generator.
2
2
  #
3
- # Copyright (c) 2009 MenTaLguY <mental@rydia.net>
3
+ # Copyright (c) 2009-2010 MenTaLguY <mental@rydia.net>
4
4
  #
5
5
  # Permission is hereby granted, free of charge, to any person obtaining
6
6
  # a copy of this software and associated documentation files (the
@@ -21,17 +21,10 @@
21
21
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
22
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
23
 
24
- require 'cgi'
25
24
  require 'rubygems'
26
- require 'ostruct'
27
25
  require 'set'
28
- require 'date'
29
- require 'time'
30
- require 'fileutils'
31
26
  require 'pathname'
32
27
  require 'yaml'
33
- require 'liquid'
34
- require 'redcloth'
35
28
 
36
29
  module Hx
37
30
 
@@ -126,17 +119,6 @@ class Overlay
126
119
  @sources = sources
127
120
  end
128
121
 
129
- def edit_entry(path, prototype=nil)
130
- @sources.each do |source|
131
- begin
132
- source.edit_entry(path, prototype) { |text| yield text }
133
- break
134
- rescue EditingNotSupportedError
135
- end
136
- end
137
- self
138
- end
139
-
140
122
  def each_entry
141
123
  seen = Set[]
142
124
  @sources.each do |source|
@@ -222,10 +204,11 @@ class Cache
222
204
 
223
205
  def each_entry
224
206
  unless @entries
225
- @entries = []
207
+ entries = []
226
208
  @source.each_entry do |path, entry|
227
- @entries << [path, entry]
209
+ entries << [path, entry]
228
210
  end
211
+ @entries = entries
229
212
  end
230
213
  @entries.each do |path, entry|
231
214
  yield path, entry.dup
@@ -489,261 +472,18 @@ end
489
472
 
490
473
  class FileBuilder
491
474
  def initialize(output_dir)
492
- @output_dir = output_dir
475
+ @output_dir = Pathname.new(output_dir)
493
476
  end
494
477
 
495
478
  def build_file(path, entry)
496
- filename = File.join(@output_dir, path)
497
- dirname = File.dirname(filename)
498
- FileUtils.mkdir_p dirname
499
- File.open(filename, "wb") do |stream|
479
+ filename = @output_dir + path
480
+ dirname = filename.parent
481
+ dirname.mkpath()
482
+ filename.open("wb") do |stream|
500
483
  stream.write entry['content'].to_s
501
484
  end
502
- end
503
- end
504
-
505
- module Backend
506
-
507
- class Hobix
508
- include Source
509
-
510
- def initialize(source, options)
511
- @entry_dir = Hx.get_pathname(options, :entry_dir)
512
- end
513
-
514
- def yaml_repr(value)
515
- YAML.parse(YAML.dump(value))
516
- end
517
- private :yaml_repr
518
-
519
- def edit_entry(path, prototype=nil)
520
- entry_filename = @entry_dir + "#{path}.yaml"
521
- begin
522
- text = entry_filename.read
523
- previous_mtime = entry_filename.mtime
524
- rescue Errno::ENOENT
525
- raise NoSuchEntryError, path unless prototype
526
- prototype = prototype.dup
527
- prototype['content'] = (prototype['content'] || "").dup
528
- content = prototype['content']
529
- def content.to_yaml_style ; :literal ; end
530
- native = YAML::DomainType.new('hobix.com,2004', 'entry', prototype)
531
- text = YAML.dump(native)
532
- previous_mtime = nil
533
- end
534
- text = yield text
535
- repr = YAML.parse(text)
536
- keys = {}
537
- repr.value.each_key { |key| keys[key.value] = key }
538
- %w(created updated).each { |name| keys[name] ||= yaml_repr(name) }
539
- update_time = Time.now
540
- update_time_repr = yaml_repr(update_time)
541
- previous_mtime ||= update_time
542
- previous_mtime_repr = yaml_repr(previous_mtime)
543
- repr.add(keys['created'], previous_mtime_repr) unless repr['created']
544
- repr.add(keys['updated'], update_time_repr)
545
- entry_filename.parent.mkpath()
546
- entry_filename.open('w') { |stream| stream << repr.emit }
547
- self
548
- end
549
-
550
- def each_entry
551
- Pathname.glob(@entry_dir + '**/*.yaml') do |entry_filename|
552
- path = entry_filename.relative_path_from(@entry_dir).to_s
553
- path.sub!(/\.yaml$/, '')
554
- entry = entry_filename.open('r') do |stream|
555
- YAML.load(stream).value
556
- end
557
- entry['updated'] ||= entry_filename.mtime
558
- entry['created'] ||= entry['updated']
559
- yield path, entry
560
- end
561
- self
562
- end
563
- end
564
-
565
- end
566
-
567
- module Listing
568
-
569
- class RecursiveIndex
570
- include Source
571
-
572
- def self.new(source, options)
573
- listing = super(source, options)
574
- if options.has_key? :limit
575
- listing = Limit.new(listing, :limit => options[:limit])
576
- end
577
- if options.has_key? :page_size
578
- listing = Paginate.new(listing, :page_size => options[:page_size])
579
- end
580
- listing
581
- end
582
-
583
- def initialize(source, options)
584
- @source = source
585
- end
586
-
587
- def each_entry
588
- indexes = Hash.new { |h,k| h[k] = {'items' => []} }
589
- @source.each_entry do |path, entry|
590
- components = path.split("/")
591
- until components.empty?
592
- components.pop
593
- index_path = (components + ["index"]).join("/")
594
- index = indexes[index_path]
595
- index['items'] << {'path' => path, 'entry' => entry}
596
- if entry['modified'] and
597
- (not index['modified'] or entry['modified'] > index['modified'])
598
- index['modified'] = entry['modified']
599
- end
600
- end
601
- end
602
- indexes.each do |path, entry|
603
- yield path, entry
604
- end
605
485
  self
606
486
  end
607
487
  end
608
488
 
609
- class Paginate
610
- include Source
611
-
612
- def initialize(source, options)
613
- @source = source
614
- @page_size = options[:page_size]
615
- end
616
-
617
- def each_entry
618
- @source.each_entry do |index_path, index_entry|
619
- items = index_entry['items'] || []
620
- if items.empty?
621
- index_entry = index_entry.dup
622
- index_entry['pages'] = [index_entry]
623
- index_entry['page_index'] = 0
624
- yield index_path, index_entry
625
- else
626
- pages = []
627
- n_pages = (items.size + @page_size - 1) / @page_size
628
- for num in 0...n_pages
629
- page_items = items[@page_size * num, @page_size]
630
- entry = index_entry.dup
631
- entry['items'] = page_items
632
- entry['prev_page'] = "#{num}"
633
- entry['next_page'] = "#{num+2}"
634
- entry['pages'] = pages
635
- entry['page_index'] = num
636
- pages << {'path' => "#{index_path}/#{num+1}", 'entry' => entry}
637
- end
638
- pages[0]['path'] = index_path
639
- pages[0]['entry'].delete('prev_page')
640
- if pages.size > 1
641
- index_name = index_path.split('/').last
642
- pages[0]['entry']['next_page'] = "#{index_name}/2"
643
- pages[1]['entry']['prev_page'] = "../#{index_name}"
644
- end
645
- pages[-1]['entry'].delete('next_page')
646
- pages.each do |page|
647
- yield page['path'], page['entry']
648
- end
649
- end
650
- end
651
- self
652
- end
653
- end
654
-
655
- class Limit
656
- include Source
657
-
658
- def initialize(source, options)
659
- @source = source
660
- @limit = options[:limit]
661
- end
662
-
663
- def each_entry
664
- @source.each_entry do |path, entry|
665
- if entry['items']
666
- trimmed_entry = entry.dup
667
- trimmed_entry['items'] = entry['items'][0...@limit]
668
- else
669
- trimmed_entry = entry
670
- end
671
- yield path, trimmed_entry
672
- end
673
- self
674
- end
675
- end
676
-
677
- end
678
-
679
- module Output
680
-
681
- class LiquidTemplate
682
- include Source
683
-
684
- module TextFilters
685
- def textilize(input)
686
- RedCloth.new(input).to_html
687
- end
688
-
689
- def escape_url(input)
690
- CGI.escape(input)
691
- end
692
-
693
- def escape_xml(input)
694
- CGI.escapeHTML(input)
695
- end
696
-
697
- def path_to_url(input, base_url)
698
- "#{base_url}#{input}"
699
- end
700
-
701
- def handleize(input)
702
- "id_#{input.to_s.gsub(/[^A-Za-z0-9]/, '_')}"
703
- end
704
-
705
- def xsd_datetime(input)
706
- input = Time.parse(input) unless Time === input
707
- input.xmlschema
708
- end
709
- end
710
-
711
- def initialize(source, options)
712
- @source = source
713
- @options = {}
714
- for key, value in options
715
- @options[key.to_s] = value
716
- end
717
- template_dir = Hx.get_pathname(options, :template_dir)
718
- # global, so all LiquidTemplate instances kind of have to agree on the
719
- # same template directory for things to work right
720
- Liquid::Template.file_system = Liquid::LocalFileSystem.new(template_dir)
721
- Liquid::Template.register_filter(TextFilters)
722
- template_file = template_dir + options[:template]
723
- @template = template_file.open('r') { |s| Liquid::Template.parse(s.read) }
724
- @extension = options[:extension]
725
- end
726
-
727
- def each_entry
728
- @source.each_entry do |path, entry|
729
- unless @extension.nil?
730
- output_path = "#{path}.#{@extension}"
731
- else
732
- output_path = path
733
- end
734
- output_entry = entry.dup
735
- output_entry['content'] = @template.render(
736
- 'now' => Time.now,
737
- 'options' => @options,
738
- 'path' => path,
739
- 'entry' => entry
740
- )
741
- yield output_path, output_entry
742
- end
743
- self
744
- end
745
- end
746
-
747
- end
748
-
749
489
  end
@@ -0,0 +1,92 @@
1
+ # hx/backend/hobix - Hobix filesystem backend for Hx
2
+ #
3
+ # Copyright (c) 2009-2010 MenTaLguY <mental@rydia.net>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ require 'rubygems'
25
+ require 'time'
26
+ require 'pathname'
27
+ require 'yaml'
28
+ require 'hx'
29
+
30
+ module Hx
31
+ module Backend
32
+
33
+ class Hobix
34
+ include Hx::Source
35
+
36
+ def initialize(source, options)
37
+ @entry_dir = Hx.get_pathname(options, :entry_dir)
38
+ end
39
+
40
+ def yaml_repr(value)
41
+ YAML.parse(YAML.dump(value))
42
+ end
43
+ private :yaml_repr
44
+
45
+ def edit_entry(path, prototype=nil)
46
+ entry_filename = @entry_dir + "#{path}.yaml"
47
+ begin
48
+ text = entry_filename.read
49
+ previous_mtime = entry_filename.mtime
50
+ rescue Errno::ENOENT
51
+ raise NoSuchEntryError, path unless prototype
52
+ prototype = prototype.dup
53
+ prototype['content'] = (prototype['content'] || "").dup
54
+ content = prototype['content']
55
+ def content.to_yaml_style ; :literal ; end
56
+ native = YAML::DomainType.new('hobix.com,2004', 'entry', prototype)
57
+ text = YAML.dump(native)
58
+ previous_mtime = nil
59
+ end
60
+ text = yield text
61
+ repr = YAML.parse(text)
62
+ keys = {}
63
+ repr.value.each_key { |key| keys[key.value] = key }
64
+ %w(created updated).each { |name| keys[name] ||= yaml_repr(name) }
65
+ update_time = Time.now
66
+ update_time_repr = yaml_repr(update_time)
67
+ previous_mtime ||= update_time
68
+ previous_mtime_repr = yaml_repr(previous_mtime)
69
+ repr.add(keys['created'], previous_mtime_repr) unless repr['created']
70
+ repr.add(keys['updated'], update_time_repr)
71
+ entry_filename.parent.mkpath()
72
+ entry_filename.open('w') { |stream| stream << repr.emit }
73
+ self
74
+ end
75
+
76
+ def each_entry
77
+ Pathname.glob(@entry_dir + '**/*.yaml') do |entry_filename|
78
+ path = entry_filename.relative_path_from(@entry_dir).to_s
79
+ path.sub!(/\.yaml$/, '')
80
+ entry = entry_filename.open('r') do |stream|
81
+ YAML.load(stream).value
82
+ end
83
+ entry['updated'] ||= entry_filename.mtime
84
+ entry['created'] ||= entry['updated']
85
+ yield path, entry
86
+ end
87
+ self
88
+ end
89
+ end
90
+
91
+ end
92
+ end
@@ -1,6 +1,6 @@
1
- # hx/commandline - A very small website generator; commandline interface
1
+ # hx/commandline - Commandline interface for Hx
2
2
  #
3
- # Copyright (c) 2009 MenTaLguY <mental@rydia.net>
3
+ # Copyright (c) 2009-2010 MenTaLguY <mental@rydia.net>
4
4
  #
5
5
  # Permission is hereby granted, free of charge, to any person obtaining
6
6
  # a copy of this software and associated documentation files (the
@@ -0,0 +1,53 @@
1
+ # hx/listing/limit - Listing length limiter
2
+ #
3
+ # Copyright (c) 2009-2010 MenTaLguY <mental@rydia.net>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ require 'rubygems'
25
+ require 'hx'
26
+
27
+ module Hx
28
+ module Listing
29
+
30
+ class Limit
31
+ include Hx::Source
32
+
33
+ def initialize(source, options)
34
+ @source = source
35
+ @limit = options[:limit]
36
+ end
37
+
38
+ def each_entry
39
+ @source.each_entry do |path, entry|
40
+ if entry['items']
41
+ trimmed_entry = entry.dup
42
+ trimmed_entry['items'] = entry['items'][0...@limit]
43
+ else
44
+ trimmed_entry = entry
45
+ end
46
+ yield path, trimmed_entry
47
+ end
48
+ self
49
+ end
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,77 @@
1
+ # hx/listing/paginate - Listing paginator
2
+ #
3
+ # Copyright (c) 2009-2010 MenTaLguY <mental@rydia.net>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ require 'rubygems'
25
+ require 'hx'
26
+
27
+ module Hx
28
+ module Listing
29
+
30
+ class Paginate
31
+ include Hx::Source
32
+
33
+ def initialize(source, options)
34
+ @source = source
35
+ @page_size = options[:page_size]
36
+ end
37
+
38
+ def each_entry
39
+ @source.each_entry do |index_path, index_entry|
40
+ items = index_entry['items'] || []
41
+ if items.empty?
42
+ index_entry = index_entry.dup
43
+ index_entry['pages'] = [index_entry]
44
+ index_entry['page_index'] = 0
45
+ yield index_path, index_entry
46
+ else
47
+ pages = []
48
+ n_pages = (items.size + @page_size - 1) / @page_size
49
+ for num in 0...n_pages
50
+ page_items = items[@page_size * num, @page_size]
51
+ entry = index_entry.dup
52
+ entry['items'] = page_items
53
+ entry['prev_page'] = "#{num}"
54
+ entry['next_page'] = "#{num+2}"
55
+ entry['pages'] = pages
56
+ entry['page_index'] = num
57
+ pages << {'path' => "#{index_path}/#{num+1}", 'entry' => entry}
58
+ end
59
+ pages[0]['path'] = index_path
60
+ pages[0]['entry'].delete('prev_page')
61
+ if pages.size > 1
62
+ index_name = index_path.split('/').last
63
+ pages[0]['entry']['next_page'] = "#{index_name}/2"
64
+ pages[1]['entry']['prev_page'] = "../#{index_name}"
65
+ end
66
+ pages[-1]['entry'].delete('next_page')
67
+ pages.each do |page|
68
+ yield page['path'], page['entry']
69
+ end
70
+ end
71
+ end
72
+ self
73
+ end
74
+ end
75
+
76
+ end
77
+ end
@@ -0,0 +1,73 @@
1
+ # hx/listing/recursiveindex - Recursive index generator
2
+ #
3
+ # Copyright (c) 2009-2010 MenTaLguY <mental@rydia.net>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ require 'rubygems'
25
+ require 'hx'
26
+ require 'hx/listing/limit'
27
+ require 'hx/listing/paginate'
28
+
29
+ module Hx
30
+ module Listing
31
+
32
+ class RecursiveIndex
33
+ include Hx::Source
34
+
35
+ def self.new(source, options)
36
+ listing = super(source, options)
37
+ if options.has_key? :limit
38
+ listing = Limit.new(listing, :limit => options[:limit])
39
+ end
40
+ if options.has_key? :page_size
41
+ listing = Paginate.new(listing, :page_size => options[:page_size])
42
+ end
43
+ listing
44
+ end
45
+
46
+ def initialize(source, options)
47
+ @source = source
48
+ end
49
+
50
+ def each_entry
51
+ indexes = Hash.new { |h,k| h[k] = {'items' => []} }
52
+ @source.each_entry do |path, entry|
53
+ components = path.split("/")
54
+ until components.empty?
55
+ components.pop
56
+ index_path = (components + ["index"]).join("/")
57
+ index = indexes[index_path]
58
+ index['items'] << {'path' => path, 'entry' => entry}
59
+ if entry['modified'] and
60
+ (not index['modified'] or entry['modified'] > index['modified'])
61
+ index['modified'] = entry['modified']
62
+ end
63
+ end
64
+ end
65
+ indexes.each do |path, entry|
66
+ yield path, entry
67
+ end
68
+ self
69
+ end
70
+ end
71
+
72
+ end
73
+ end
@@ -0,0 +1,101 @@
1
+ # hx/output/liquidtemplate - Liquid templates for Hx
2
+ #
3
+ # Copyright (c) 2009-2010 MenTaLguY <mental@rydia.net>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ require 'rubygems'
25
+ require 'time'
26
+ require 'liquid'
27
+ require 'redcloth'
28
+ require 'cgi'
29
+ require 'hx'
30
+
31
+ module Hx
32
+ module Output
33
+
34
+ class LiquidTemplate
35
+ include Hx::Source
36
+
37
+ module TextFilters
38
+ def textilize(input)
39
+ RedCloth.new(input).to_html
40
+ end
41
+
42
+ def escape_url(input)
43
+ CGI.escape(input)
44
+ end
45
+
46
+ def escape_xml(input)
47
+ CGI.escapeHTML(input)
48
+ end
49
+
50
+ def path_to_url(input, base_url)
51
+ "#{base_url}#{input}"
52
+ end
53
+
54
+ def handleize(input)
55
+ "id_#{input.to_s.gsub(/[^A-Za-z0-9]/, '_')}"
56
+ end
57
+
58
+ def xsd_datetime(input)
59
+ input = Time.parse(input) unless Time === input
60
+ input.xmlschema
61
+ end
62
+ end
63
+
64
+ def initialize(source, options)
65
+ @source = source
66
+ @options = {}
67
+ for key, value in options
68
+ @options[key.to_s] = value
69
+ end
70
+ template_dir = Hx.get_pathname(options, :template_dir)
71
+ # global, so all LiquidTemplate instances kind of have to agree on the
72
+ # same template directory for things to work right
73
+ Liquid::Template.file_system = Liquid::LocalFileSystem.new(template_dir)
74
+ Liquid::Template.register_filter(TextFilters)
75
+ template_file = template_dir + options[:template]
76
+ @template = template_file.open('r') { |s| Liquid::Template.parse(s.read) }
77
+ @extension = options[:extension]
78
+ end
79
+
80
+ def each_entry
81
+ @source.each_entry do |path, entry|
82
+ unless @extension.nil?
83
+ output_path = "#{path}.#{@extension}"
84
+ else
85
+ output_path = path
86
+ end
87
+ output_entry = entry.dup
88
+ output_entry['content'] = @template.render(
89
+ 'now' => Time.now,
90
+ 'options' => @options,
91
+ 'path' => path,
92
+ 'entry' => entry
93
+ )
94
+ yield output_path, output_entry
95
+ end
96
+ self
97
+ end
98
+ end
99
+
100
+ end
101
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hx
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - MenTaLguY
@@ -41,7 +41,12 @@ files:
41
41
  - VERSION
42
42
  - bin/hx
43
43
  - lib/hx.rb
44
+ - lib/hx/backend/hobix.rb
44
45
  - lib/hx/commandline.rb
46
+ - lib/hx/listing/limit.rb
47
+ - lib/hx/listing/paginate.rb
48
+ - lib/hx/listing/recursiveindex.rb
49
+ - lib/hx/output/liquidtemplate.rb
45
50
  - spec/cache_spec.rb
46
51
  - spec/hx_dummy.rb
47
52
  - spec/hx_dummy2.rb