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