Révision 1384
tmp/org.txm.groovy.core/src/groovy/org/txm/macro/xml/CombineNumberElementMacro.groovy (revision 1384) | ||
---|---|---|
1 |
// Copyright © 2018 ENS de Lyon, CNRS, University of Franche-Comté |
|
2 |
// Licensed under the terms of the GNU General Public License (http://www.gnu.org/licenses) |
|
3 |
// @author sheiden |
|
4 |
|
|
5 |
/* |
|
6 |
|
|
7 |
This macro calls NumberElement successively |
|
8 |
|
|
9 |
*/ |
|
10 |
|
|
11 |
package org.txm.macro.xml |
|
12 |
|
|
13 |
res = gse.run(NumberElementMacro, [ |
|
14 |
"args":[ |
|
15 |
"inputDirectory":new File("/home/sheiden/Documents/projet-susana-mars-reers/corpus/tei"), |
|
16 |
"outputDirectory":new File("/home/sheiden/Documents/projet-susana-mars-reers/corpus/tei/out"), |
|
17 |
"elementName":"pb", |
|
18 |
"elementAttribute":"n", |
|
19 |
"countStart":94, |
|
20 |
"valuePrefix":"", |
|
21 |
"valueSuffix":"", |
|
22 |
"debug":"true" |
|
23 |
], |
|
24 |
"selection":selection, |
|
25 |
"selections":selections, |
|
26 |
"corpusViewSelection":corpusViewSelection, |
|
27 |
"corpusViewSelections":corpusViewSelections, |
|
28 |
"monitor":monitor]) |
|
29 |
if (!res) println "** problem calling NumberElementMacro." |
|
30 |
|
|
31 |
res = gse.run(NumberElementMacro, [ |
|
32 |
"args":["inputDirectory":new File("/home/sheiden/Documents/projet-susana-mars-reers/corpus/tei/out"), |
|
33 |
"outputDirectory":new File("/home/sheiden/Documents/projet-susana-mars-reers/corpus/tei/out/out"), |
|
34 |
"elementName":"pb", |
|
35 |
"elementAttribute":"facs", |
|
36 |
"countStart":102, |
|
37 |
"valuePrefix":"https://gallica.bnf.fr/iiif/ark:/12148/bpt6k35936/f", |
|
38 |
"valueSuffix":"/full/full/0/native.jpg", |
|
39 |
"debug":"true" |
|
40 |
], |
|
41 |
"selection":selection, |
|
42 |
"selections":selections, |
|
43 |
"corpusViewSelection":corpusViewSelection, |
|
44 |
"corpusViewSelections":corpusViewSelections, |
|
45 |
"monitor":monitor]) |
|
46 |
if (!res) println "** problem calling NumberElementMacro." |
|
47 |
|
tmp/org.txm.groovy.core/src/groovy/org/txm/macro/xml/IndentMacro.groovy (revision 1384) | ||
---|---|---|
1 |
package org.txm.macro.xml |
|
2 |
// STANDARD DECLARATIONS |
|
3 |
|
|
4 |
import org.kohsuke.args4j.* |
|
5 |
import groovy.transform.Field |
|
6 |
import org.txm.rcpapplication.swt.widget.parameters.* |
|
7 |
import org.txm.importer.ApplyXsl2 |
|
8 |
|
|
9 |
// BEGINNING OF PARAMETERS |
|
10 |
|
|
11 |
@Field @Option(name="inputDirectory", usage="an example folder", widget="Folder", required=true, def="in") |
|
12 |
def inputDirectory = new File(System.getProperty("user.home"),"/tmp/xsltest") |
|
13 |
|
|
14 |
@Field @Option(name="outputDirectory", usage="an example folder", widget="Folder", required=true, def="out") |
|
15 |
def outputDirectory = new File("/tmp/xsltest/out") |
|
16 |
|
|
17 |
@Field @Option(name="omitXmlDeclaration", usage="omit xml declaration", widget="Boolean", required=false, def="false") |
|
18 |
def omitXmlDeclaration |
|
19 |
|
|
20 |
@Field @Option(name="suppressIndentation", usage="space delimited list of elements not to indent", widget="Text", required=false, def="") |
|
21 |
def suppressIndentation |
|
22 |
|
|
23 |
@Field @Option(name="doubleSpace", usage="space delimited list of elements with forced line break before", widget="Text", required=false, def="") |
|
24 |
def doubleSpace |
|
25 |
|
|
26 |
@Field @Option(name="encoding", usage="output character encoding", widget="String", required=false, def="utf-8") |
|
27 |
def encoding |
|
28 |
|
|
29 |
@Field @Option(name="namespacesDeclaration", usage="space delimited list of namespace declarations (eg \"xmlns:dc='http://purl.org/dc/elements/1.1/'\")", widget="Text", required=false, def="") |
|
30 |
def namespacesDeclaration |
|
31 |
|
|
32 |
@Field @Option(name="debug", usage="Show debug messages", widget="Boolean", required=true, def="false") |
|
33 |
def debug |
|
34 |
|
|
35 |
if (!ParametersDialog.open(this)) return |
|
36 |
|
|
37 |
// END OF PARAMETERS |
|
38 |
|
|
39 |
doubleSpace = doubleSpace.trim() |
|
40 |
|
|
41 |
if (doubleSpace.length() > 0) doubleSpace = " saxon:double-space=\"$doubleSpace\"" |
|
42 |
|
|
43 |
suppressIndentation = suppressIndentation.trim() |
|
44 |
|
|
45 |
if (suppressIndentation.length() > 0) suppressIndentation = " saxon:suppress-indentation=\"$suppressIndentation\"" |
|
46 |
|
|
47 |
encoding = encoding.trim() |
|
48 |
|
|
49 |
if (encoding.length() > 0) encoding = " encoding=\"$encoding\"" |
|
50 |
|
|
51 |
if (omitXmlDeclaration) omitXmlDeclarationP = " omit-xml-declaration=\"yes\"" else omitXmlDeclarationP = " omit-xml-declaration=\"no\"" |
|
52 |
|
|
53 |
namespacesDeclaration = namespacesDeclaration.trim() |
|
54 |
|
|
55 |
if (namespacesDeclaration.length() > 0) namespacesDeclaration = " $namespacesDeclaration" |
|
56 |
|
|
57 |
def xslParameters = "" |
|
58 |
|
|
59 |
IndentStyleSheet = """ |
|
60 |
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:saxon="http://saxon.sf.net/"${namespacesDeclaration}> |
|
61 |
<xsl:output method="xml" indent="yes"${omitXmlDeclarationP}${encoding}${doubleSpace}${suppressIndentation}/> |
|
62 |
<!-- saxon:indent-spaces="6" for Saxon-PE only --> |
|
63 |
<xsl:template match="node()|@*"> |
|
64 |
<xsl:copy> |
|
65 |
<!-- Including any attributes it has and any child nodes --> |
|
66 |
<xsl:apply-templates select="@*|node()"/> |
|
67 |
</xsl:copy> |
|
68 |
</xsl:template> |
|
69 |
</xsl:stylesheet>""" |
|
70 |
|
|
71 |
def XSLFile = File.createTempFile("IndentStyleSheet",".xsl") |
|
72 |
XSLFile.deleteOnExit() |
|
73 |
|
|
74 |
XSLFile << IndentStyleSheet |
|
75 |
|
|
76 |
outputDirectory.mkdir() |
|
77 |
|
|
78 |
xslParameters = xslParameters.trim() |
|
79 |
if (xslParameters.length() == 0) { |
|
80 |
xslParameters = null |
|
81 |
} else { |
|
82 |
def split = xslParameters.split("\n") |
|
83 |
xslParameters = [] |
|
84 |
for (def str : split) { |
|
85 |
def split2 = str.split("=", 2) |
|
86 |
if (split2.size() == 2) { |
|
87 |
xslParameters << split2 |
|
88 |
} |
|
89 |
} |
|
90 |
} |
|
91 |
|
|
92 |
println "Processed directory: $inputDirectory." |
|
93 |
|
|
94 |
def files = [] |
|
95 |
ApplyXsl2 a = new ApplyXsl2(XSLFile.getAbsolutePath()) |
|
96 |
inputDirectory.eachFileMatch(~/.+\.(xml|XML)/) { XMLFile -> |
|
97 |
String name = XMLFile.getName() |
|
98 |
try { |
|
99 |
|
|
100 |
def outFile = new File(outputDirectory, name) |
|
101 |
if (xslParameters != null) { |
|
102 |
for(def param : xslParameters) { |
|
103 |
a.setParam(param[0], param[1]) |
|
104 |
} |
|
105 |
} |
|
106 |
a.process(XMLFile, outFile) |
|
107 |
a.resetParams() |
|
108 |
files << XMLFile |
|
109 |
} catch (Exception e) { |
|
110 |
|
|
111 |
msgParse = (e.getMessageAndLocation() =~ /^(.*) lineNumber: ([0-9]+); columnNumber: ([0-9]+); (.*).$/) |
|
112 |
if (msgParse.size() == 1) { |
|
113 |
|
|
114 |
def lineNumber = msgParse[0][2] |
|
115 |
def colNumber = msgParse[0][3] |
|
116 |
def errMsg = msgParse[0][4] |
|
117 |
|
|
118 |
println "** $name processing aborted, [line $lineNumber, character $colNumber]: $errMsg." |
|
119 |
|
|
120 |
|
|
121 |
} else { |
|
122 |
println e.getMessageAndLocation() |
|
123 |
} |
|
124 |
|
|
125 |
XSLFile.delete() |
|
126 |
return 0 |
|
127 |
} |
|
128 |
} |
|
129 |
|
|
130 |
XSLFile.delete() |
|
131 |
|
|
132 |
return 1 |
|
133 |
|
tmp/org.txm.groovy.core/src/groovy/org/txm/macro/xml/ValidateMacro.groovy (revision 1384) | ||
---|---|---|
1 |
// Copyright © 2018 ENS de Lyon, CNRS, University of Franche-Comté |
|
2 |
// Licensed under the terms of the GNU General Public License (http://www.gnu.org/licenses) |
|
3 |
// @author sheiden |
|
4 |
|
|
5 |
package org.txm.macro.xml |
|
6 |
|
|
7 |
// STANDARD DECLARATIONS |
|
8 |
|
|
9 |
import java.nio.file.Files |
|
10 |
|
|
11 |
import org.kohsuke.args4j.* |
|
12 |
import groovy.transform.Field |
|
13 |
import org.txm.rcpapplication.commands.* |
|
14 |
import org.txm.rcpapplication.swt.widget.parameters.* |
|
15 |
import org.txm.importer.ApplyXsl2 |
|
16 |
|
|
17 |
import net.sf.saxon.TransformerFactoryImpl |
|
18 |
import org.txm.utils.saxon.SaxonNodeSet |
|
19 |
import javax.xml.transform.stream.StreamSource |
|
20 |
import javax.xml.transform.stream.StreamResult |
|
21 |
|
|
22 |
import org.eclipse.core.filesystem.EFS |
|
23 |
import org.eclipse.ui.PlatformUI |
|
24 |
import org.eclipse.ui.ide.IDE |
|
25 |
import org.eclipse.jface.text.ITextOperationTarget |
|
26 |
|
|
27 |
// BEGINNING OF PARAMETERS |
|
28 |
|
|
29 |
@Field @Option(name="inputDirectory", usage="an example folder", widget="Folder", required=true, def="in") |
|
30 |
def inputDirectory = new File(System.getProperty("user.home"),"/tmp/xsltest") |
|
31 |
|
|
32 |
@Field @Option(name="edit", usage="edit XML files with errors", widget="Boolean", required=true, def="true") |
|
33 |
def edit |
|
34 |
|
|
35 |
@Field @Option(name="maxEditors", usage="maximum number of files opened", widget="Integer", required=true, def="4") |
|
36 |
def maxEditors |
|
37 |
|
|
38 |
@Field @Option(name="debug", usage="Show debug messages", widget="Boolean", required=true, def="false") |
|
39 |
def debug |
|
40 |
|
|
41 |
if (!ParametersDialog.open(this)) return |
|
42 |
|
|
43 |
// END OF PARAMETERS |
|
44 |
|
|
45 |
def xslParameters = "" |
|
46 |
def nEditors = 0 |
|
47 |
|
|
48 |
IdentityStyleSheet = """ |
|
49 |
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:saxon="http://saxon.sf.net/"> |
|
50 |
<xsl:output method="xml"/> |
|
51 |
<xsl:template match="node()|@*"> |
|
52 |
<xsl:copy> |
|
53 |
<xsl:apply-templates select="@*|node()"/> |
|
54 |
</xsl:copy> |
|
55 |
</xsl:template> |
|
56 |
</xsl:stylesheet>""" |
|
57 |
|
|
58 |
def XSLFile = File.createTempFile("IdentityStyleSheet",".xsl") |
|
59 |
XSLFile.deleteOnExit() |
|
60 |
addShutdownHook { |
|
61 |
XSLFile.delete() |
|
62 |
println XSLFile+" deleted." |
|
63 |
} |
|
64 |
|
|
65 |
XSLFile << IdentityStyleSheet |
|
66 |
|
|
67 |
def outputDirectory = Files.createTempDirectory("Validate") |
|
68 |
outputDirectory = outputDirectory.toFile() |
|
69 |
outputDirectory.deleteOnExit() |
|
70 |
|
|
71 |
xslParameters = xslParameters.trim() |
|
72 |
if (xslParameters.length() == 0) { |
|
73 |
xslParameters = null |
|
74 |
} else { |
|
75 |
def split = xslParameters.split("\n") |
|
76 |
xslParameters = [] |
|
77 |
for (def str : split) { |
|
78 |
def split2 = str.split("=", 2) |
|
79 |
if (split2.size() == 2) { |
|
80 |
xslParameters << split2 |
|
81 |
} |
|
82 |
} |
|
83 |
} |
|
84 |
|
|
85 |
println "Processed directory: $inputDirectory." |
|
86 |
|
|
87 |
// let's build a Saxon XSLT processor |
|
88 |
|
|
89 |
System.setProperty("javax.xml.transform.TransformerFactory", "net.sf.saxon.TransformerFactoryImpl") |
|
90 |
tFactory = new net.sf.saxon.TransformerFactoryImpl() |
|
91 |
tConfiguration = tFactory.getConfiguration() |
|
92 |
tConfiguration.registerExtensionFunction(new SaxonNodeSet()) // ? |
|
93 |
// the following features don't seem to work, yet |
|
94 |
tConfiguration.setConfigurationProperty(net.sf.saxon.lib.FeatureKeys.LINE_NUMBERING, true) |
|
95 |
tConfiguration.setConfigurationProperty(net.sf.saxon.lib.FeatureKeys.RECOVERY_POLICY, net.sf.saxon.Configuration.RECOVER_WITH_WARNINGS) |
|
96 |
|
|
97 |
// === TODO: other configuration tuning options === |
|
98 |
// Basically: |
|
99 |
// - schema validation |
|
100 |
// - dtd validation |
|
101 |
// - etc. |
|
102 |
// |
|
103 |
// DTD_VALIDATION |
|
104 |
// DTD_VALIDATION_RECOVERABLE |
|
105 |
// LINE_NUMBERING |
|
106 |
// RECOVERY_POLICY: Configuration.RECOVER_SILENTLY, Configuration.RECOVER_WITH_WARNINGS, or Configuration.DO_NOT_RECOVER. |
|
107 |
// RECOVERY_POLICY_NAME (get?) |
|
108 |
// SCHEMA_VALIDATION |
|
109 |
// SCHEMA_VALIDATION_MODE: None, Strict, Lax, Preserve |
|
110 |
// STANDARD_ERROR_OUTPUT_FILE |
|
111 |
// STRIP_WHITESPACE |
|
112 |
// SUPPRESS_XSLT_NAMESPACE_CHECK |
|
113 |
// TRACE_LISTENER |
|
114 |
// VALIDATION_COMMENTS |
|
115 |
// VALIDATION_WARNINGS |
|
116 |
// XSD_VERSION |
|
117 |
// XSLT_SCHEMA_AWARE |
|
118 |
|
|
119 |
def transformer = tFactory.newTransformer(new StreamSource(XSLFile)) |
|
120 |
|
|
121 |
inputDirectory.eachFileMatch(~/.+\.(xml|XML)/) { xmlInputFile -> |
|
122 |
name = xmlInputFile.getName() |
|
123 |
def editor = "" |
|
124 |
try { |
|
125 |
|
|
126 |
def xmlOutputFile = new File(outputDirectory, name) |
|
127 |
xmlOutputFile.deleteOnExit() |
|
128 |
|
|
129 |
try { |
|
130 |
|
|
131 |
// redirect XSLT processor error output |
|
132 |
tmperr = new ByteArrayOutputStream() |
|
133 |
tFactory.getErrorListener().setErrorOutput(new PrintStream(tmperr)) |
|
134 |
|
|
135 |
strWriter = new StringWriter() |
|
136 |
out = new StreamResult(strWriter) |
|
137 |
|
|
138 |
transformer.transform(new StreamSource(xmlInputFile), out) |
|
139 |
|
|
140 |
if (debug) println "stderr = "+tmperr.toString(java.nio.charset.StandardCharsets.UTF_8) |
|
141 |
//System.setErr(stderr) |
|
142 |
|
|
143 |
w = new BufferedWriter(new FileWriter(xmlOutputFile)) |
|
144 |
w.write(strWriter.toString()) |
|
145 |
w.close() |
|
146 |
|
|
147 |
// reset transformer to free memory |
|
148 |
transformer = tFactory.newTransformer(new StreamSource(XSLFile)) |
|
149 |
|
|
150 |
} catch (Exception e) { |
|
151 |
|
|
152 |
// org.xml.sax.SAXParseException; systemId: file:/home/sheiden/Documents/txm/xml/sample.xml; lineNumber: 3; columnNumber: 1; Le type d'élément "a" doit être suivi des spécifications d'attribut, ">" ou "/>". |
|
153 |
|
|
154 |
msgParse = (e.getMessageAndLocation() =~ /^(.*) lineNumber: ([0-9]+); columnNumber: ([0-9]+); (.*).$/) |
|
155 |
if (msgParse.size() == 1) { |
|
156 |
|
|
157 |
def lineNumber = msgParse[0][2] |
|
158 |
def colNumber = msgParse[0][3] |
|
159 |
def errMsg = msgParse[0][4] |
|
160 |
|
|
161 |
println "** $name [line $lineNumber, character $colNumber]: $errMsg." |
|
162 |
|
|
163 |
if (edit && (nEditors < maxEditors++)) { |
|
164 |
def fileStore = EFS.getLocalFileSystem().getStore(xmlInputFile.toURI()) |
|
165 |
monitor.syncExec(new Runnable() { |
|
166 |
public void run() { |
|
167 |
def page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() |
|
168 |
editor = IDE.openEditorOnFileStore(page, fileStore) |
|
169 |
if (editor.getClass() == org.eclipse.wst.xml.ui.internal.tabletree.XMLMultiPageEditorPart) { |
|
170 |
editor = editor.fTextEditor |
|
171 |
} |
|
172 |
def dprov = editor.getDocumentProvider() |
|
173 |
def doc = dprov.getDocument(editor.getEditorInput()) |
|
174 |
def nlines = doc.getNumberOfLines() |
|
175 |
def line = Integer.parseInt(lineNumber)-1 |
|
176 |
if (nlines < line) line = nlines-1 |
|
177 |
def ncols = doc.getLineLength(line) |
|
178 |
def col = Integer.parseInt(colNumber)-1 |
|
179 |
if (ncols <= col) col = ncols-1 |
|
180 |
def offset = doc.getLineOffset(line)+col |
|
181 |
def textv = editor.getAdapter(ITextOperationTarget.class) |
|
182 |
textv.getTextWidget().setSelection(offset) |
|
183 |
textv.revealRange(offset, 10) |
|
184 |
} // run |
|
185 |
} // Runnable |
|
186 |
) // syncExec |
|
187 |
} |
|
188 |
} else { |
|
189 |
println e.getMessageAndLocation() |
|
190 |
} |
|
191 |
|
|
192 |
} |
|
193 |
} catch (Exception ee) { |
|
194 |
//println "Warning: XSL transformation of '$name' failed with error=$e" |
|
195 |
//if (debug) " with: "+e.printStackTrace() |
|
196 |
XSLFile.delete() |
|
197 |
outputDirectory.deleteDir() |
|
198 |
return 0 |
|
199 |
} |
|
200 |
} |
|
201 |
|
|
202 |
XSLFile.delete() |
|
203 |
outputDirectory.deleteDir() |
|
204 |
|
|
205 |
return 1 |
|
206 |
|
Formats disponibles : Unified diff