gettalong-webgen 0.5.5.20081001 → 0.5.5.20081010
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/doc/extensions.page +1 -1
- data/doc/reference_configuration.page +85 -0
- data/doc/tag/tikz.page +158 -0
- data/lib/webgen/common/sitemap.rb +2 -3
- data/lib/webgen/contentprocessor/blocks.rb +0 -2
- data/lib/webgen/contentprocessor/context.rb +0 -3
- data/lib/webgen/contentprocessor/erubis.rb +0 -2
- data/lib/webgen/default_config.rb +8 -1
- data/lib/webgen/node.rb +49 -24
- data/lib/webgen/page.rb +25 -15
- data/lib/webgen/path.rb +20 -10
- data/lib/webgen/sourcehandler/base.rb +36 -14
- data/lib/webgen/sourcehandler/copy.rb +2 -2
- data/lib/webgen/sourcehandler/directory.rb +16 -13
- data/lib/webgen/sourcehandler/feed.rb +3 -6
- data/lib/webgen/sourcehandler/fragment.rb +6 -11
- data/lib/webgen/sourcehandler/memory.rb +41 -0
- data/lib/webgen/sourcehandler/metainfo.rb +21 -21
- data/lib/webgen/sourcehandler/page.rb +8 -12
- data/lib/webgen/sourcehandler/sitemap.rb +0 -2
- data/lib/webgen/sourcehandler/template.rb +0 -4
- data/lib/webgen/sourcehandler/virtual.rb +18 -18
- data/lib/webgen/sourcehandler.rb +83 -70
- data/lib/webgen/tag/breadcrumbtrail.rb +1 -4
- data/lib/webgen/tag/coderay.rb +0 -3
- data/lib/webgen/tag/date.rb +0 -2
- data/lib/webgen/tag/executecommand.rb +1 -2
- data/lib/webgen/tag/includefile.rb +1 -3
- data/lib/webgen/tag/langbar.rb +1 -4
- data/lib/webgen/tag/menu.rb +1 -4
- data/lib/webgen/tag/metainfo.rb +0 -2
- data/lib/webgen/tag/relocatable.rb +2 -3
- data/lib/webgen/tag/sitemap.rb +0 -3
- data/lib/webgen/tag/tikz.rb +117 -0
- data/lib/webgen/tag.rb +1 -0
- data/lib/webgen/tree.rb +9 -5
- data/test/test_common_sitemap.rb +4 -4
- data/test/test_contentprocessor_context.rb +1 -1
- data/test/test_contentprocessor_redcloth.rb +1 -0
- data/test/test_contentprocessor_tags.rb +1 -1
- data/test/test_node.rb +33 -13
- data/test/test_output_filesystem.rb +1 -1
- data/test/test_page.rb +13 -4
- data/test/test_path.rb +37 -5
- data/test/test_source_filesystem.rb +1 -1
- data/test/test_source_stacked.rb +1 -1
- data/test/test_sourcehandler_base.rb +30 -1
- data/test/test_sourcehandler_copy.rb +1 -1
- data/test/test_sourcehandler_directory.rb +16 -1
- data/test/test_sourcehandler_feed.rb +6 -7
- data/test/test_sourcehandler_fragment.rb +1 -1
- data/test/test_sourcehandler_memory.rb +42 -0
- data/test/test_sourcehandler_metainfo.rb +23 -21
- data/test/test_sourcehandler_page.rb +5 -7
- data/test/test_sourcehandler_template.rb +1 -1
- data/test/test_sourcehandler_virtual.rb +2 -2
- data/test/test_tag_base.rb +0 -1
- data/test/test_tag_breadcrumbtrail.rb +4 -4
- data/test/test_tag_includefile.rb +3 -3
- data/test/test_tag_langbar.rb +5 -6
- data/test/test_tag_menu.rb +7 -7
- data/test/test_tag_metainfo.rb +1 -1
- data/test/test_tag_relocatable.rb +1 -1
- data/test/test_tag_tikz.rb +66 -0
- data/test/test_tree.rb +2 -7
- metadata +7 -2
data/doc/extensions.page
CHANGED
@@ -6,7 +6,7 @@ title: Extensions
|
|
6
6
|
Following is a listing of all available extensions:
|
7
7
|
|
8
8
|
<%
|
9
|
-
pattern = /#{File.join(node.parent.absolute_lcn, '/')}(contentprocessor|output|source|sourcehandler|tag|)
|
9
|
+
pattern = /#{File.join(node.parent.absolute_lcn, '/')}(contentprocessor|output|source|sourcehandler|tag|)\/.*html$/
|
10
10
|
context.content_node.tree.node_access[:alcn].select {|alcn, n| alcn =~ pattern}.sort.each do |alcn, n|
|
11
11
|
next if n.is_fragment?
|
12
12
|
%>
|
@@ -659,6 +659,91 @@ files in Webgen Page Format.
|
|
659
659
|
<a href="\{relocatable: ../features.html}">Some Path</a>
|
660
660
|
|
661
661
|
|
662
|
+
* ### tag.tikz.path
|
663
|
+
|
664
|
+
The default mandatory configuration option for Tag::TikZ that specifies the (naturally
|
665
|
+
non-existing) source path that should be used for creating the TikZ image. The output path is
|
666
|
+
derived from this path the usual way. You shouldn't use a path that does already exist!
|
667
|
+
|
668
|
+
* Syntax: `PATH` where `PATH` is a relative or absolute source path.
|
669
|
+
|
670
|
+
* Examples:
|
671
|
+
|
672
|
+
\{tikz:: images/tikz.png}\tikz \draw (0,0) -- (0,2);{tikz}
|
673
|
+
|
674
|
+
|
675
|
+
* ### tag.tikz.libraries
|
676
|
+
|
677
|
+
Specifies the names of additional TikZ library names that should be used when creating the
|
678
|
+
image.
|
679
|
+
|
680
|
+
* Syntax: `[NAME, ...]` where `NAME` is the name of a TikZ library.
|
681
|
+
|
682
|
+
* Examples:
|
683
|
+
|
684
|
+
\{tikz:: {path: images/tikz.png, libraries: [mindmap, arrows]}}
|
685
|
+
\tikz \draw (0,0) -- (0,2) -- (2,2);
|
686
|
+
{tikz}
|
687
|
+
|
688
|
+
|
689
|
+
* ### tag.tikz.opts
|
690
|
+
|
691
|
+
Specifies additional global options for the `tikzpicture` environment.
|
692
|
+
|
693
|
+
* Syntax: `OPTS` where `OPTS` is the string with the global options.
|
694
|
+
|
695
|
+
* Examples:
|
696
|
+
|
697
|
+
\{tikz:: {path: images/tikz.png, opts: 'scale=3, line cap=round'}}
|
698
|
+
\tikz \draw (0,0) -- (0,2) -- (2,2);
|
699
|
+
{tikz}
|
700
|
+
|
701
|
+
|
702
|
+
* ### tag.tikz.resolution
|
703
|
+
|
704
|
+
Specifies the render and output resolutions that should be used to convert the TikZ image in PDF
|
705
|
+
format to the chosen image format. The first number specifies the render resolution and the
|
706
|
+
second one the output resolution. If the render resolution is higher than the output resolution,
|
707
|
+
the final image quality is better but the image needs to scaled down to the output resolution.
|
708
|
+
|
709
|
+
* Syntax: `RENDER_RES OUTPUT_RES` where `RENDER_RES` is the integer specifying the render
|
710
|
+
resolution and `OUTPUT_RES` is the integer specifying the output resolution.
|
711
|
+
|
712
|
+
* Examples:
|
713
|
+
|
714
|
+
\{tikz:: {path: images/tikz.png, resolution: 300 72}}
|
715
|
+
\tikz \draw (0,0) -- (0,2) -- (2,2);
|
716
|
+
{tikz}
|
717
|
+
|
718
|
+
|
719
|
+
* ### tag.tikz.transparent
|
720
|
+
|
721
|
+
Specifies whether the generated image should be transparent. This only works when the path
|
722
|
+
specified by `tag.tikz.path` option has the extension `.png`! You should probably also set the
|
723
|
+
background of the generated image tag to transparent.
|
724
|
+
|
725
|
+
* Syntax: `BOOLEAN` where `BOOLEAN` is either `true` or `false`.
|
726
|
+
|
727
|
+
* Examples:
|
728
|
+
|
729
|
+
\{tikz:: {path: images/tikz.png, transparent: true}}
|
730
|
+
\tikz \draw (0,0) -- (0,2) -- (2,2);
|
731
|
+
{tikz}
|
732
|
+
|
733
|
+
|
734
|
+
* ### tag.tikz.img\_attr
|
735
|
+
|
736
|
+
Specifies additional HTML attributes that should be set on the generated `img` tag.
|
737
|
+
|
738
|
+
* Syntax: `\{KEY:VALUE, ...}` where `KEY` is a valid HTML `img` tag attribute name and `VALUE`
|
739
|
+
the to-be-set value.
|
740
|
+
|
741
|
+
* Examples:
|
742
|
+
|
743
|
+
\{tikz:: {path: images/tikz.png, img_attr: {alt: Some TikZ picture}}}
|
744
|
+
\tikz \draw (0,0) -- (0,2) -- (2,2);
|
745
|
+
{tikz}
|
746
|
+
|
662
747
|
---
|
663
748
|
|
664
749
|
## Miscelleanous Configuration Options
|
data/doc/tag/tikz.page
ADDED
@@ -0,0 +1,158 @@
|
|
1
|
+
---
|
2
|
+
title: Webgen::Tag::TikZ
|
3
|
+
used_options:
|
4
|
+
- tag.tikz.path
|
5
|
+
- tag.tikz.libraries
|
6
|
+
- tag.tikz.opts
|
7
|
+
- tag.tikz.resolution
|
8
|
+
- tag.tikz.transparent
|
9
|
+
- tag.tikz.img_attr
|
10
|
+
---
|
11
|
+
## Description
|
12
|
+
|
13
|
+
This tag provides support for automatically generating graphics with the fantastic PGF/TikZ library
|
14
|
+
for LaTeX. You will need to have a current LaTeX distribution with the PGF/TikZ library installed
|
15
|
+
and ImageMagick for this to work. You will also need Ghostscript if you want support for transparent
|
16
|
+
PNG images. More exactly, you will need to have the programs `pdflatex` (usually included in the
|
17
|
+
LaTeX distribution - for generating a PDF from the LaTeX document that describes the PGF/TikZ
|
18
|
+
graphic), `pdfcrop` (usually included in the LaTeX distribution - to crop the generated PDF and
|
19
|
+
throw away useless borders), `convert` (provided by ImageMagick - to convert the generated PDF
|
20
|
+
document to an image file format and to optionally resize them) and `gs` (provided by the
|
21
|
+
Ghostscript package - to generate transparent PNG images).
|
22
|
+
|
23
|
+
When using this tag, you need to set at least the default mandatory parameter `tag.tikz.path`. This
|
24
|
+
path specifies the source path that should be used for generating the image and should not
|
25
|
+
exist. The output path is dervied from this path the usual way. The extension used for this
|
26
|
+
parameter specifies the final image format that is used (a good choice is PNG). All other parameters
|
27
|
+
are optional. The commands for creating the PGF/TikZ picture are specified in the body of the
|
28
|
+
tag. Have a look at some of the examples below to set the power of PGF/TikZ.
|
29
|
+
|
30
|
+
If you want to generate transparent images, you will need to set `tag.tikz.transparent` to `true`
|
31
|
+
and specify a `tag.tikz.path` with a `.png` extension.
|
32
|
+
|
33
|
+
## Examples
|
34
|
+
|
35
|
+
These examples are taken (sometimes a little bit altered) from the great PGF Manual included in the
|
36
|
+
PGF/TikZ distribution.
|
37
|
+
|
38
|
+
<table class="examples">
|
39
|
+
<tr>
|
40
|
+
<th>Usage</th><th>Output</th>
|
41
|
+
</tr>
|
42
|
+
|
43
|
+
<tr>
|
44
|
+
<td>
|
45
|
+
<pre>
|
46
|
+
\{tikz:: house.png}
|
47
|
+
\tikz \draw[thick,rounded corners=8pt]
|
48
|
+
(0,0) -- (0,2) -- (1,3.25) -- (2,2) -- (2,0) -- (0,2) -- (2,2) -- (0,0) -- (2,0);
|
49
|
+
{tikz}
|
50
|
+
</pre>
|
51
|
+
</td>
|
52
|
+
<td>
|
53
|
+
{tikz:: house.png}
|
54
|
+
\tikz \draw[thick,rounded corners=8pt]
|
55
|
+
(0,0) -- (0,2) -- (1,3.25) -- (2,2) -- (2,0) -- (0,2) -- (2,2) -- (0,0) -- (2,0);
|
56
|
+
{tikz}
|
57
|
+
</td>
|
58
|
+
</tr>
|
59
|
+
|
60
|
+
<tr>
|
61
|
+
<td>
|
62
|
+
<pre>
|
63
|
+
\{tikz:: {path: chain.png, libraries: [arrows,automata,shadows,positioning],
|
64
|
+
opts: "->,>=stealth,shorten >=1pt,auto,node distance=2.8cm,on grid,semithick,
|
65
|
+
every state/.style={fill=red,draw=none,circular drop shadow,text=white}",
|
66
|
+
resolution: 300 72}}
|
67
|
+
\node[initial,state] (A) {$q_a$};
|
68
|
+
\node[state] (B) [above right=of A] {$q_b$};
|
69
|
+
\node[state] (D) [below right=of A] {$q_d$};
|
70
|
+
\node[state] (C) [below right=of B] {$q_c$};
|
71
|
+
\node[state] (E) [below=of D] {$q_e$};
|
72
|
+
\path (A) edge node {0,1,L} (B)
|
73
|
+
edge node {1,1,R} (C)
|
74
|
+
(B) edge [loop above] node {1,1,L} (B)
|
75
|
+
edge node {0,1,L} (C)
|
76
|
+
(C) edge node {0,1,L} (D)
|
77
|
+
edge [bend left] node {1,0,R} (E)
|
78
|
+
(D) edge [loop below] node {1,1,R} (D)
|
79
|
+
edge node {0,1,R} (A)
|
80
|
+
(E) edge [bend left] node {1,0,R} (A);
|
81
|
+
{tikz}
|
82
|
+
</pre>
|
83
|
+
</td>
|
84
|
+
<td>
|
85
|
+
{tikz:: {path: chain.png, libraries: [arrows,automata,shadows,positioning],
|
86
|
+
opts: "->,>=stealth,shorten >=1pt,auto,node distance=2.8cm,on grid,semithick,
|
87
|
+
every state/.style={fill=red,draw=none,circular drop shadow,text=white}"}}
|
88
|
+
\node[initial,state] (A) {$q_a$};
|
89
|
+
\node[state] (B) [above right=of A] {$q_b$};
|
90
|
+
\node[state] (D) [below right=of A] {$q_d$};
|
91
|
+
\node[state] (C) [below right=of B] {$q_c$};
|
92
|
+
\node[state] (E) [below=of D] {$q_e$};
|
93
|
+
\path (A) edge node {0,1,L} (B)
|
94
|
+
edge node {1,1,R} (C)
|
95
|
+
(B) edge [loop above] node {1,1,L} (B)
|
96
|
+
edge node {0,1,L} (C)
|
97
|
+
(C) edge node {0,1,L} (D)
|
98
|
+
edge [bend left] node {1,0,R} (E)
|
99
|
+
(D) edge [loop below] node {1,1,R} (D)
|
100
|
+
edge node {0,1,R} (A)
|
101
|
+
(E) edge [bend left] node {1,0,R} (A);
|
102
|
+
{tikz}
|
103
|
+
</td>
|
104
|
+
</tr>
|
105
|
+
|
106
|
+
<tr>
|
107
|
+
<td>
|
108
|
+
Not transparent and standard res
|
109
|
+
<pre>
|
110
|
+
\{tikz:: {path: mindmap.png, libraries: [mindmap]}}
|
111
|
+
\path[mindmap,concept color=black,text=white]
|
112
|
+
node[concept] {Computer Science}
|
113
|
+
[clockwise from=0]
|
114
|
+
child[concept color=red] { node[concept] {technical} }
|
115
|
+
child[concept color=orange] { node[concept] {theoretical} };
|
116
|
+
{tikz}
|
117
|
+
</pre>
|
118
|
+
</td>
|
119
|
+
<td>
|
120
|
+
{tikz:: {path: mindmap.png, libraries: [mindmap]}}
|
121
|
+
\path[mindmap,concept color=black,text=white]
|
122
|
+
node[concept] {Computer Science}
|
123
|
+
[clockwise from=0]
|
124
|
+
child[concept color=red] { node[concept] {technical} }
|
125
|
+
child[concept color=orange] { node[concept] {theoretical} };
|
126
|
+
{tikz}
|
127
|
+
</td>
|
128
|
+
</tr>
|
129
|
+
|
130
|
+
<tr>
|
131
|
+
<td>
|
132
|
+
Transparent and high res
|
133
|
+
<pre>
|
134
|
+
\{tikz:: {path: mindmap-low.png, libraries: [mindmap],
|
135
|
+
img_attr: {style: 'background:transparent'},
|
136
|
+
transparent: true, resolution: 300 72}}
|
137
|
+
\path[mindmap,concept color=black,text=white]
|
138
|
+
node[concept] {Computer Science}
|
139
|
+
[clockwise from=0]
|
140
|
+
child[concept color=red] { node[concept] {technical} }
|
141
|
+
child[concept color=orange] { node[concept] {theoretical} };
|
142
|
+
{tikz}
|
143
|
+
</pre>
|
144
|
+
</td>
|
145
|
+
<td>
|
146
|
+
{tikz:: {path: mindmap-high.png, libraries: [mindmap],
|
147
|
+
img_attr: {style: 'background:transparent'},
|
148
|
+
transparent: true, resolution: 300 72}}
|
149
|
+
\path[mindmap,concept color=black,text=white]
|
150
|
+
node[concept] {Computer Science}
|
151
|
+
[clockwise from=0]
|
152
|
+
child[concept color=red] { node[concept] {technical} }
|
153
|
+
child[concept color=orange] { node[concept] {theoretical} };
|
154
|
+
{tikz}
|
155
|
+
</td>
|
156
|
+
</tr>
|
157
|
+
|
158
|
+
</table>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'webgen/tag
|
1
|
+
require 'webgen/tag'
|
2
2
|
require 'webgen/websiteaccess'
|
3
3
|
|
4
4
|
module Webgen::Common
|
@@ -64,13 +64,12 @@ module Webgen::Common
|
|
64
64
|
(tree.flatten.any? do |alcn|
|
65
65
|
(n = node.tree[alcn]) && (r = n.routing_node(lang)) && r.meta_info_changed?
|
66
66
|
end)
|
67
|
-
node.dirty
|
67
|
+
node.flag(:dirty)
|
68
68
|
break
|
69
69
|
end
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
|
-
|
74
73
|
end
|
75
74
|
|
76
75
|
end
|
@@ -54,7 +54,7 @@ config.sourcehandler.patterns({
|
|
54
54
|
'Webgen::SourceHandler::Sitemap' => ['**/*.sitemap']
|
55
55
|
}, :doc => 'Source handler to path pattern map')
|
56
56
|
config.sourcehandler.invoke({
|
57
|
-
1 => ['Webgen::SourceHandler::Directory', 'Webgen::SourceHandler::Metainfo'
|
57
|
+
1 => ['Webgen::SourceHandler::Directory', 'Webgen::SourceHandler::Metainfo'],
|
58
58
|
5 => ['Webgen::SourceHandler::Copy', 'Webgen::SourceHandler::Template',
|
59
59
|
'Webgen::SourceHandler::Page', 'Webgen::SourceHandler::Feed',
|
60
60
|
'Webgen::SourceHandler::Sitemap'],
|
@@ -148,6 +148,7 @@ config.contentprocessor.tags.map({
|
|
148
148
|
'coderay' => 'Webgen::Tag::Coderay',
|
149
149
|
'date' => 'Webgen::Tag::Date',
|
150
150
|
'sitemap' => 'Webgen::Tag::Sitemap',
|
151
|
+
'tikz' => 'Webgen::Tag::TikZ',
|
151
152
|
:default => 'Webgen::Tag::Metainfo'
|
152
153
|
}, :doc => 'Tag processor name to class map')
|
153
154
|
|
@@ -190,6 +191,12 @@ config.tag.coderay.tab_width(8, :doc => 'Number of spaces used for a tabulator')
|
|
190
191
|
|
191
192
|
config.tag.date.format('%Y-%m-%d %H:%M:%S', :doc => 'The format of the date (same options as Ruby\'s Time#strftime)')
|
192
193
|
|
194
|
+
config.tag.tikz.path(nil, :doc => 'The source path of the created image', :mandatory => 'default')
|
195
|
+
config.tag.tikz.libraries(nil, :doc => 'An array of additional TikZ library names')
|
196
|
+
config.tag.tikz.opts(nil, :doc => 'A string with global options for the tikzpicture environment')
|
197
|
+
config.tag.tikz.resolution('72 72', :doc => 'A string specifying the render and output resolutions')
|
198
|
+
config.tag.tikz.transparent(false, :doc => 'Specifies whether the generated image should be transparent (only png)')
|
199
|
+
config.tag.tikz.img_attr({}, :doc => 'A hash of additional HTML attributes for the created img tag')
|
193
200
|
|
194
201
|
# All things regarding common functionality
|
195
202
|
website.autoload_service(:create_sitemap, 'Webgen::Common::Sitemap')
|
data/lib/webgen/node.rb
CHANGED
@@ -46,17 +46,6 @@ module Webgen
|
|
46
46
|
# Meta information associated with the node.
|
47
47
|
attr_reader :meta_info
|
48
48
|
|
49
|
-
# Set by other objects to +true+ if they think the object has changed since the last run. Must
|
50
|
-
# not be set to +false+ once it is +true+!
|
51
|
-
attr_accessor :dirty
|
52
|
-
|
53
|
-
# Set by other objects to +true+ if the meta information of the node has changed since the last
|
54
|
-
# run. Must not be set to +false+ once it is +true+!
|
55
|
-
attr_accessor :dirty_meta_info
|
56
|
-
|
57
|
-
# Has the node been created or has it been read from the cache?
|
58
|
-
attr_accessor :created
|
59
|
-
|
60
49
|
# Create a new Node instance.
|
61
50
|
#
|
62
51
|
# +parent+ (immutable)::
|
@@ -78,15 +67,27 @@ module Webgen
|
|
78
67
|
# found, the node is language neutral.
|
79
68
|
def initialize(parent, path, cn, meta_info = {})
|
80
69
|
@parent = parent
|
81
|
-
@path = path.freeze
|
82
70
|
@cn = cn.chomp('/').freeze
|
71
|
+
@children = []
|
72
|
+
reinit(path, meta_info)
|
73
|
+
init_rest
|
74
|
+
end
|
75
|
+
|
76
|
+
# Re-initializes an already initialized node and resets it to its pristine state.
|
77
|
+
def reinit(path, meta_info = {})
|
78
|
+
old_path = @path
|
79
|
+
@path = path.freeze
|
83
80
|
@lang = meta_info.delete('lang').freeze
|
84
81
|
@lang = nil unless is_file?
|
85
82
|
@meta_info = meta_info
|
86
|
-
@
|
87
|
-
@
|
88
|
-
|
89
|
-
|
83
|
+
@flags = Set.new([:dirty, :created])
|
84
|
+
if @tree
|
85
|
+
@tree.node_access[:path].delete(old_path) if old_path
|
86
|
+
@tree.register_path(self)
|
87
|
+
self.node_info.clear
|
88
|
+
self.node_info[:used_nodes] = Set.new
|
89
|
+
self.node_info[:used_meta_info_nodes] = Set.new
|
90
|
+
end
|
90
91
|
end
|
91
92
|
|
92
93
|
# Return the meta information item for +key+.
|
@@ -116,26 +117,50 @@ module Webgen
|
|
116
117
|
# Check if the node is the root node.
|
117
118
|
def is_root?; self == tree.root; end
|
118
119
|
|
120
|
+
# Check if the node is flagged with one of the following:
|
121
|
+
#
|
122
|
+
# :created:: Has the node been created or has it been read from the cache?
|
123
|
+
# :reinit:: Does the node need to be reinitialized?
|
124
|
+
# :dirty:: Set by other objects to +true+ if they think the object has changed since the last
|
125
|
+
# run. Must not be set to +false+ once it is +true+!
|
126
|
+
# :dirty_meta_info:: Set by other objects to +true+ if the meta information of the node has
|
127
|
+
# changed since the last run. Must not be set to +false+ once it is +true+!
|
128
|
+
def flagged(key)
|
129
|
+
@flags.include?(key)
|
130
|
+
end
|
131
|
+
|
132
|
+
# Flag the node with the +keys+. See #flagged for valid keys.
|
133
|
+
def flag(*keys)
|
134
|
+
@flags += keys
|
135
|
+
website.blackboard.dispatch_msg(:node_flagged, self, keys)
|
136
|
+
end
|
137
|
+
|
138
|
+
# Remove the flags +keys+ from the node.
|
139
|
+
def unflag(*keys)
|
140
|
+
@flags.subtract(keys)
|
141
|
+
website.blackboard.dispatch_msg(:node_unflagged, self, keys)
|
142
|
+
end
|
143
|
+
|
119
144
|
# Return +true+ if the node has changed since the last webgen run. If it has changed, +dirty+ is
|
120
145
|
# set to +true+.
|
121
146
|
def changed?
|
122
147
|
if_not_checked(:node) do
|
123
|
-
|
124
|
-
|
125
|
-
website.blackboard.dispatch_msg(:node_changed?, self) unless
|
148
|
+
flag(:dirty) if meta_info_changed? ||
|
149
|
+
node_info[:used_nodes].any? {|n| n != @absolute_lcn && (!tree[n] || tree[n].changed?)}
|
150
|
+
website.blackboard.dispatch_msg(:node_changed?, self) unless flagged(:dirty)
|
126
151
|
end
|
127
|
-
|
152
|
+
flagged(:dirty)
|
128
153
|
end
|
129
154
|
|
130
155
|
# Return +true+ if the meta information of the node has changed.
|
131
156
|
def meta_info_changed?
|
132
157
|
if_not_checked(:meta_info) do
|
133
|
-
|
158
|
+
flag(:dirty_meta_info) if node_info[:used_meta_info_nodes].any? do |n|
|
134
159
|
n != @absolute_lcn && (!tree[n] || tree[n].meta_info_changed?)
|
135
|
-
end
|
136
|
-
website.blackboard.dispatch_msg(:node_meta_info_changed?, self) unless
|
160
|
+
end
|
161
|
+
website.blackboard.dispatch_msg(:node_meta_info_changed?, self) unless flagged(:dirty_meta_info)
|
137
162
|
end
|
138
|
-
|
163
|
+
flagged(:dirty_meta_info)
|
139
164
|
end
|
140
165
|
|
141
166
|
# Return an informative representation of the node.
|
data/lib/webgen/page.rb
CHANGED
@@ -55,14 +55,17 @@ module Webgen
|
|
55
55
|
# the information. The +meta_info+ parameter can be used to provide default meta information.
|
56
56
|
def from_data(data, meta_info = {})
|
57
57
|
md = /(#{RE_META_INFO})?(.*)/m.match(normalize_eol(data))
|
58
|
-
|
59
|
-
raise WebgenPageFormatError, 'Found start line for meta information block but no valid meta information block'
|
60
|
-
end
|
61
|
-
meta_info = meta_info.merge(md[1].nil? ? {} : parse_meta_info(md[1]))
|
58
|
+
meta_info = meta_info.merge(parse_meta_info(md[1], data))
|
62
59
|
blocks = parse_blocks(md[2] || '', meta_info)
|
63
60
|
new(meta_info, blocks)
|
64
61
|
end
|
65
62
|
|
63
|
+
# Parse the given string +data+ in Webgen Page Format and return the found meta information.
|
64
|
+
def meta_info_from_data(data)
|
65
|
+
md = /(#{RE_META_INFO})?/m.match(normalize_eol(data))
|
66
|
+
parse_meta_info(md[1], data)
|
67
|
+
end
|
68
|
+
|
66
69
|
#######
|
67
70
|
private
|
68
71
|
#######
|
@@ -72,17 +75,24 @@ module Webgen
|
|
72
75
|
data.gsub(/\r\n?/, "\n")
|
73
76
|
end
|
74
77
|
|
75
|
-
# Parse the meta info string +
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
78
|
+
# Parse the meta info string in +mi_data+ and return the hash with the meta information. The
|
79
|
+
# original +data+ is used for checking the validness of the meta information block.
|
80
|
+
def parse_meta_info(mi_data, data)
|
81
|
+
if mi_data.nil? && data =~ RE_META_INFO_START
|
82
|
+
raise WebgenPageFormatError, 'Found start line for meta information block but no valid meta information block'
|
83
|
+
elsif mi_data.nil?
|
84
|
+
{}
|
85
|
+
else
|
86
|
+
begin
|
87
|
+
meta_info = YAML::load(mi_data.to_s)
|
88
|
+
unless meta_info.kind_of?(Hash)
|
89
|
+
raise WebgenPageFormatError, "Invalid structure of meta information block: expected YAML hash but found #{meta_info.class}"
|
90
|
+
end
|
91
|
+
rescue ArgumentError => e
|
92
|
+
raise WebgenPageFormatError, e.message
|
81
93
|
end
|
82
|
-
|
83
|
-
raise WebgenPageFormatError, e.message
|
94
|
+
meta_info
|
84
95
|
end
|
85
|
-
meta_info
|
86
96
|
end
|
87
97
|
|
88
98
|
# Parse all blocks in +data+ and return them. Meta information can be provided in +meta_info+
|
@@ -118,12 +128,12 @@ module Webgen
|
|
118
128
|
# The contents of the meta information block.
|
119
129
|
attr_reader :meta_info
|
120
130
|
|
121
|
-
# The
|
131
|
+
# The hash of blocks for the page.
|
122
132
|
attr_reader :blocks
|
123
133
|
|
124
134
|
# Create a new Page object with the meta information provided in +meta_info+ and the given
|
125
135
|
# +blocks+.
|
126
|
-
def initialize(meta_info = {}, blocks =
|
136
|
+
def initialize(meta_info = {}, blocks = {})
|
127
137
|
@meta_info = meta_info
|
128
138
|
@blocks = blocks
|
129
139
|
end
|
data/lib/webgen/path.rb
CHANGED
@@ -35,11 +35,24 @@ module Webgen
|
|
35
35
|
end
|
36
36
|
|
37
37
|
|
38
|
+
# Return +true+ if the given +path+ matches the given +pattern+ (trailing slashes of directories
|
39
|
+
# are not respected). For information on which patterns are supported, have a look at the
|
40
|
+
# documentation of File.fnmatch.
|
41
|
+
def self.match(path, pattern)
|
42
|
+
path = path.to_s.chomp('/') unless path == '/'
|
43
|
+
pattern = pattern.to_s.chomp('/') unless pattern == '/'
|
44
|
+
File.fnmatch(pattern, path, File::FNM_DOTMATCH|File::FNM_CASEFOLD|File::FNM_PATHNAME)
|
45
|
+
end
|
46
|
+
|
47
|
+
|
38
48
|
include Comparable
|
39
49
|
|
40
|
-
# The full
|
50
|
+
# The full path.
|
41
51
|
attr_accessor :path
|
42
52
|
|
53
|
+
# The source path that lead to the creation of this path.
|
54
|
+
attr_accessor :source_path
|
55
|
+
|
43
56
|
# The basename part of the path.
|
44
57
|
attr_accessor :basename
|
45
58
|
|
@@ -55,11 +68,13 @@ module Webgen
|
|
55
68
|
# Extracted meta information for the path.
|
56
69
|
attr_accessor :meta_info
|
57
70
|
|
58
|
-
# Create a new Path object for +path+. The optional
|
59
|
-
#
|
60
|
-
|
71
|
+
# Create a new Path object for +path+. The optional +source_path+ parameter specifies the path
|
72
|
+
# that lead to the creation of this path. The optional block needs to return an IO object for
|
73
|
+
# the content of the path.
|
74
|
+
def initialize(path, source_path = path, &ioblock)
|
61
75
|
@meta_info = {}
|
62
76
|
@io = SourceIO.new(&ioblock) if block_given?
|
77
|
+
@source_path = source_path
|
63
78
|
analyse(path)
|
64
79
|
end
|
65
80
|
|
@@ -70,6 +85,7 @@ module Webgen
|
|
70
85
|
temp.path = temp.path.sub(/^#{Regexp.escape(prefix.chomp("/"))}/, '') if prefix #"
|
71
86
|
reanalyse = (@path == '/' || temp.path == '/')
|
72
87
|
temp.path = File.join(mp, temp.path)
|
88
|
+
temp.source_path = temp.path if @path == @source_path
|
73
89
|
if reanalyse
|
74
90
|
temp.send(:analyse, temp.path)
|
75
91
|
else
|
@@ -131,12 +147,6 @@ module Webgen
|
|
131
147
|
end
|
132
148
|
alias_method(:eql?, :==)
|
133
149
|
|
134
|
-
# Return +true+ if the localized path matches the given +pattern+. For information on which
|
135
|
-
# patterns are supported, have a look at the documentation of File.fnmatch.
|
136
|
-
def =~(pattern)
|
137
|
-
File.fnmatch(pattern, File.join(@directory, lcn), File::FNM_DOTMATCH|File::FNM_CASEFOLD|File::FNM_PATHNAME)
|
138
|
-
end
|
139
|
-
|
140
150
|
# Implemented sothat a Path looks like a String when used as key in a hash.
|
141
151
|
def <=>(other)
|
142
152
|
@path <=> other.to_str
|
@@ -42,9 +42,18 @@ module Webgen::SourceHandler
|
|
42
42
|
# <tt>node_info[:processor]</tt>:: Has to be set to the class name of the source handler. This is
|
43
43
|
# used by the Node class: all unknown method calls are forwarded
|
44
44
|
# to the node processor.
|
45
|
-
# <tt>node_info[:src]</tt>:: Has to be set to the string version of the
|
45
|
+
# <tt>node_info[:src]</tt>:: Has to be set to the string version of the path that lead to the
|
46
|
+
# creation of the node.
|
47
|
+
# <tt>node_info[:creation_path]</tt>:: Has to be set to the string version of the path that is
|
48
|
+
# used to create the path.
|
46
49
|
# <tt>meta_info['no_output']</tt>:: Has to be set to +true+ on nodes that are used during a
|
47
50
|
# webgen run but do not produce an output file.
|
51
|
+
# <tt>meta_info['modified_at']</tt>:: Is automatically set to the current time if not already set
|
52
|
+
# correctly (ie. if not a Time object).
|
53
|
+
#
|
54
|
+
# Note: The difference between +:src+ and +:creation_path+ is that a creation path need not have
|
55
|
+
# an existing source path representation. For example, fragments created from a page source path
|
56
|
+
# have a different +:creation_path+ which includes the fragment part.
|
48
57
|
#
|
49
58
|
# Additional information that is used only for processing purposes should be stored in the
|
50
59
|
# #node_info hash of a node as the #meta_info hash is reserved for real node meta information and
|
@@ -55,7 +64,8 @@ module Webgen::SourceHandler
|
|
55
64
|
# Path patterns define which paths are handled by a specific source handler. These patterns are
|
56
65
|
# specified in the <tt>sourcehandler.patterns</tt> configuration hash as a mapping from the source
|
57
66
|
# handler class name to an array of path patterns. The patterns need to have a format that
|
58
|
-
# <tt>Dir.glob</tt> can handle.
|
67
|
+
# <tt>Dir.glob</tt> can handle. You can use the configuration helper +patterns+ to set this (is
|
68
|
+
# shown in the example below).
|
59
69
|
#
|
60
70
|
# Specifying a path pattern does not mean that webgen uses the source handler. One also needs to
|
61
71
|
# provide an entry in the configuration value <tt>sourcehandler.invoke</tt>. This is a hash that
|
@@ -97,7 +107,7 @@ module Webgen::SourceHandler
|
|
97
107
|
#
|
98
108
|
# end
|
99
109
|
#
|
100
|
-
# WebsiteAccess.website.config.
|
110
|
+
# WebsiteAccess.website.config.patterns('SimpleCopy' => ['**/*.jpg', '**/*.png'])
|
101
111
|
# WebsiteAccess.website.config.sourcehandler.invoke[5] << 'SimpleCopy'
|
102
112
|
#
|
103
113
|
module Base
|
@@ -156,7 +166,9 @@ module Webgen::SourceHandler
|
|
156
166
|
if OutputPathHelpers.public_instance_methods(false).include?(method)
|
157
167
|
name = send(method, parent, path, use_lang_part)
|
158
168
|
name += '/' if path.path =~ /\/$/ && name !~ /\/$/
|
159
|
-
if node_exists?(parent, path, name)
|
169
|
+
if (node = node_exists?(parent, path, name)) && node.lang == path.meta_info['lang']
|
170
|
+
name = node.path
|
171
|
+
elsif node
|
160
172
|
name = send(method, parent, path, (path.meta_info['lang'].nil? ? false : true))
|
161
173
|
name += '/' if path.path =~ /\/$/ && name !~ /\/$/
|
162
174
|
end
|
@@ -172,21 +184,31 @@ module Webgen::SourceHandler
|
|
172
184
|
parent.tree[Webgen::Node.absolute_name(parent, path.lcn, :alcn)] || (!path.meta_info['no_output'] && parent.tree[output_path, :path])
|
173
185
|
end
|
174
186
|
|
175
|
-
# Create
|
187
|
+
# Create a node under +parent+ from +path+ if it does not already exists or needs to be
|
188
|
+
# re-initialized. The found node or the newly created node is returned afterwards. +nil+ is
|
189
|
+
# returned if no node can be created (e.g. when <tt>path.meta_info['draft']</tt> is set). Some
|
176
190
|
# additional node information like <tt>:src</tt> and <tt>:processor</tt> is set and the meta
|
177
|
-
# information is checked for validness. The created node is yielded if a block is
|
191
|
+
# information is checked for validness. The created/re-initialized node is yielded if a block is
|
192
|
+
# given.
|
178
193
|
def create_node(parent, path, output_path = self.output_path(parent, path))
|
179
|
-
return if path.meta_info['draft']
|
180
|
-
|
194
|
+
return nil if path.meta_info['draft']
|
195
|
+
node = node_exists?(parent, path, output_path)
|
196
|
+
if node && (node.node_info[:src] != path.source_path || node.node_info[:processor] != self.class.name)
|
197
|
+
log(:warn) { "Node already exists: source = #{path.source_path} | path = #{node.path} | alcn = #{node.absolute_lcn}"}
|
198
|
+
return node
|
199
|
+
elsif !node
|
181
200
|
node = Webgen::Node.new(parent, output_path, path.cn, path.meta_info)
|
182
|
-
|
183
|
-
node.
|
184
|
-
node.node_info[:processor] = self.class.name
|
185
|
-
yield(node) if block_given?
|
186
|
-
node
|
201
|
+
elsif node.flagged(:reinit)
|
202
|
+
node.reinit(output_path, path.meta_info)
|
187
203
|
else
|
188
|
-
|
204
|
+
return node
|
189
205
|
end
|
206
|
+
node['modified_at'] = Time.now unless node['modified_at'].kind_of?(Time)
|
207
|
+
node.node_info[:src] = path.source_path
|
208
|
+
node.node_info[:creation_path] = path.path
|
209
|
+
node.node_info[:processor] = self.class.name
|
210
|
+
yield(node) if block_given?
|
211
|
+
node
|
190
212
|
end
|
191
213
|
|
192
214
|
# Return the content of the given +node+. This default +content+ method just returns +nil+.
|