-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathxco-file-util.xqm
222 lines (201 loc) · 6.92 KB
/
xco-file-util.xqm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
(:
: xco-file-util.xqm - utility functions dealing with the file system
:)
module namespace fu="http://www.parsqube.de/ns/xco/file-util";
import module namespace u="http://www.parsqube.de/ns/xco/util"
at "xco-util.xqm";
declare namespace z="http://www.parsqube.de/ns/xco/structure";
(:
:
: P u b l i c f u n c t i o n s
:
:)
(:~
: Applies a relative path to a context path. A relative context path is
: resolved against the current working directory. The result is an
: absolute path.
:
: @param contextPath the relative path starts at this location
: @param relPath a relative path
: @return a relative path
:)
declare function fu:applyRelPath($contextPath as xs:string, $relPath as xs:string)
as xs:string {
let $cpath := $contextPath ! u:normalizeUri(., ())
return
if ($relPath = ('', '.')) then $cpath else
fu:applyRelPathREC($cpath, tokenize($relPath, '/'))
};
(:~
: Returns the parent path of a given path.
:
: @param path a path
: @return the parent path
:)
declare function fu:getParentPath($path as xs:string)
as xs:string {
if (not($path)) then '..'
else $path ! u:normalizeUri(., ()) ! replace(., '/[^/]*$', '')
};
(:~
: Returns the parent path of a given path. If the path is a
: relative path, the returned path is also relative.
:
: @param path a path
: @return the parent path
:)
declare function fu:getRelParentPath($path as xs:string)
as xs:string {
if (not($path)) then '..'
else if (not(contains($path, '/'))) then ''
else $path ! replace(., '/[^/]*$', '')
};
(:~
: Returns the relative path leading from a context path to a target location.
: A relative context path or target location is resolved against the current
: working directory.
:
: @param contextPath the relative path starts at this location
: @param targetPath the relative path leads to this location
: @return a relative path
:)
declare function fu:getRelPath($contextPath as xs:string, $targetPath as xs:string)
as xs:string {
let $cpath := $contextPath ! u:normalizeUri(., ())
let $tpath := $targetPath ! u:normalizeUri(., ())
return
if ($cpath eq $tpath) then '' else fu:getRelPathREC($cpath, $tpath, ())
};
(:~
: Applies the relative path leading from a context path to a target location to
: a different context path.
:)
declare function fu:shiftRelPath($contextPath as xs:string,
$targetPath as xs:string,
$newContextPath as xs:string*)
as xs:string {
fu:getRelPath($contextPath, $targetPath) ! fu:applyRelPath($newContextPath, .)
};
(:~
: Returns the file name extension.
:)
declare function fu:getFileExtension($path as xs:string)
as xs:string? {
let $fname := file:name($path)
return $fname ! replace($path, '.*(\.[^.]+$)', '$1')[not(. eq $fname)]
};
(:~
: Removes the file name extension.
:)
declare function fu:removeFileExtension($path as xs:string)
as xs:string {
let $fext := fu:getFileExtension($path)
return substring($path, 1, string-length($path) - string-length($fext))
};
(:~
: Inserts a label string immediately before the file name extension.
: The label is inserted before the dot.
:)
declare function fu:insertLabelBeforeFileNameExtension($path as xs:string,
$label as xs:string)
as xs:string {
let $fext := fu:getFileExtension($path)
let $suffix := $label||$fext
return fu:removeFileExtension($path)||$suffix
};
(:~
: Replaces the file name extension with a different extension.
:)
declare function fu:changeFileNameExtension($path as xs:string,
$newExtension as xs:string)
as xs:string {
fu:removeFileExtension($path)||'.'||$newExtension
};
(:~
: Copies the standard css file into the report folder, if appropriate.
:)
declare function fu:copyCssFile($options as map(xs:string, item()*))
as empty-sequence() {
let $odir := $options?odir
return if (not($odir)) then () else
let $reportType := $options?reportType
return
if ($reportType ne 'contab') then () else
let $fname := 'asciidoc.css'
let $fpathTarget := $odir||'/'||$fname
return
if (file:exists($fpathTarget)) then ()
else
let $sourceDir := static-base-uri() ! fu:getParentPath(.)
let $fpathSource := $sourceDir||'/'||$fname
return file:copy($fpathSource, $fpathTarget)
};
(:
: f t r e e c o n s t r u c t o r
:
:)
(:~
: Maps a sequence of file paths to a tree representation of folders
: and files (<fo> and <fi> elements).
:
: @param filePaths a sequence of file paths
: @param context context folder
: @return a tree of <fo> and <fi> elements
:)
declare function fu:ftree($filePaths as xs:string*, $context as xs:string?)
as element(fo) {
let $paths := $filePaths ! replace(., '^'||$context||'/', '')
=> sort((), lower-case#1)
return <fo context="{$context}">{fu:ftreeREC($paths)}</fo>
};
declare function fu:ftreeREC($paths as xs:string*)
as element()* {
let $files := $paths[not(contains(., '/'))]
let $folders := $paths[not(. = $files)]
let $folderTrees :=
for $fo in $folders
let $step1 := replace($fo, '/.*', '')
group by $step1
return
<fo name="{$step1}">{
$fo ! replace(., '^'||$step1||'/', '') => fu:ftreeREC()
}</fo>
return (
$folderTrees,
$files ! <fi name="{.}"/>
)
};
(:
:
: P r i v a t e f u n c t i o n s
:
:)
(:~
: Recursive helper function of `getRelPath`.
:)
declare %private function fu:getRelPathREC($contextPath as xs:string,
$targetPath as xs:string,
$prefix as xs:string*)
as xs:string {
let $suffix := replace($targetPath, '^'||$contextPath||'/', '')
[. ne $targetPath]
return
if ($suffix) then string-join(($prefix, $suffix), '/')
else
fu:getRelPathREC($contextPath ! fu:getParentPath(.), $targetPath,
($prefix, '..'))
};
(:~
: Recursive helper function of `applyRelPath`.
:)
declare function fu:applyRelPathREC($contextPath as xs:string, $pathSteps as xs:string*)
as xs:string {
let $step := head($pathSteps)
let $tail := tail($pathSteps)
let $newContextPath :=
if ($step eq '..') then $contextPath ! fu:getParentPath(.)
else $contextPath||'/'||$step
return
if (empty($tail)) then $newContextPath
else fu:applyRelPathREC($newContextPath, $tail)
};