diff --git a/Examples/issue12.txt b/Examples/issue12.txt new file mode 100644 index 0000000000000000000000000000000000000000..a5f3743c58e31e316c4587eb4f152c09fb1f55aa --- /dev/null +++ b/Examples/issue12.txt @@ -0,0 +1,57 @@ +[S:00] +{org:en} +This document defines the functional requirements for ERTMS/ETCS (EUROPEAN RAIL TRAFFIC MANAGEMENT SYSTEM / EUROPEAN TRAIN CONTROL SYSTEM). +{/org} +{unl} +mod(document(icl>writing>thing),this(icl>determiner>adj,mod<concrete_thing)) +aoj(define(icl>characterize>be,obj>uw,aoj>thing).@entry.@present,document(icl>writing>thing)) +mod(requirement(icl>duty>thing).@def.@pl,functional(icl>adj,ant>nonfunctional)) +obj(define(icl>characterize>be,obj>uw,aoj>thing).@entry.@present,requirement(icl>duty>thing).@def.@pl) +or(etcs,ertms) +pur(requirement(icl>duty>thing).@def.@pl,etcs) +mod:01(management(icl>action,agt>volitional_thing,obj>thing),traffic(icl>collection>thing)) +mod(:03.@_hn-scope,management(icl>action,agt>volitional_thing,obj>thing)) +or:03(european(icl>inhabitant>person).@entry,system(icl>group>thing):01.@entry) +mod:01(control(icl>power>thing),train(icl>public_transport>thing)) +mod:01(system(icl>group>thing):02,control(icl>power>thing)) +agt:02(rail(icl>complain>do,rsn>thing,agt>volitional_thing).@entry.@present,:01.@entry.@parenthesis) +rsn:02(rail(icl>complain>do,rsn>thing,agt>volitional_thing).@entry.@present,:01.@entry.@parenthesis) +shd(etcs,:02) +mod(train(icl>public_transport>thing),:03.@_hn-scope) +{/unl} +[/S] +[S:00] +{org:en} +The document primarily defines the operational requirements and therefore contains only a few technical terms. +{/org} +{unl} +aoj(define(icl>characterize>be,obj>uw,aoj>thing).@entry.@present,document(icl>writing>thing).@def) +man(define(icl>characterize>be,obj>uw,aoj>thing).@entry.@present,primarily(icl>how,equ>mainly)) +and(:01,define(icl>characterize>be,obj>uw,aoj>thing).@entry.@present) +mod(requirement(icl>duty>thing).@def.@pl,operational(icl>adj,com>operation)) +obj(define(icl>characterize>be,obj>uw,aoj>thing).@entry.@present,requirement(icl>duty>thing).@def.@pl) +man:01(contain(icl>be,equ>comprise,obj>abstract_thing,aoj>information,pur>abstract_thing).@entry.@present,therefore(icl>how)) +man:01(term(icl>word>thing,mod>thing).@pl,only(icl>how,equ>recently)) +qua:01(term(icl>word>thing,mod>thing).@pl,a_few(icl>adj,equ>some,qua<thing)) +mod:01(term(icl>word>thing,mod>thing).@pl,technical(icl>adj,ant>nontechnical)) +obj:01(contain(icl>be,equ>comprise,obj>abstract_thing,aoj>information,pur>abstract_thing).@entry.@present,term(icl>word>thing,mod>thing).@pl) +{/unl} +[/S] +[S:00] +{org:en} +For consistency reasons, all functional requirements not implemented in the SRS 2.3.0 have been removed from this version.. +{/org} +{unl} +agt:01(reason(icl>persuade>do,agt>thing,gol>uw,rec>person).@entry.@present,consistency(icl>uniformity>thing,ant>inconsistency)) +qua:02(requirement(icl>duty>thing).@pl,all(icl>quantity,ant>some,per>thing)) +mod:02(requirement(icl>duty>thing).@pl,functional(icl>adj,ant>nonfunctional)) +agt:02(implement(icl>employ>do,agt>thing,obj>thing).@past.@not,requirement(icl>duty>thing).@pl) +plc(remove(icl>dismiss>do,plf>thing,agt>volitional_thing,obj>person).@entry.@present.@complete,srs.@def) +obj(remove(icl>dismiss>do,plf>thing,agt>volitional_thing,obj>person).@entry.@present.@complete,"2.3".@topic) +mod("2.3".@topic,".0") +mod(version(icl>interpretation>abstract_thing,agt>thing,obj>uw),this(icl>determiner>adj,mod<concrete_thing)) +plf(remove(icl>dismiss>do,plf>thing,agt>volitional_thing,obj>person).@entry.@present.@complete,version(icl>interpretation>abstract_thing,agt>thing,obj>uw)) +and(implement(icl>employ>do,agt>thing,obj>thing).@past.@not,:01) +rsn(remove(icl>dismiss>do,plf>thing,agt>volitional_thing,obj>person).@entry.@present.@complete,:02) +{/unl} +[/S] diff --git a/unl-tools-infrastructure/src/main/java/fr/tetras_libre/unltools/unl/exporters/dot/DotFileGraphExporter.java b/unl-tools-infrastructure/src/main/java/fr/tetras_libre/unltools/unl/exporters/dot/DotFileGraphExporter.java index 9f06cc75d1ee70d43a808298f42759b720f28b87..6ef5d9e4a724c5bb974a7462b55f441a71a43e96 100644 --- a/unl-tools-infrastructure/src/main/java/fr/tetras_libre/unltools/unl/exporters/dot/DotFileGraphExporter.java +++ b/unl-tools-infrastructure/src/main/java/fr/tetras_libre/unltools/unl/exporters/dot/DotFileGraphExporter.java @@ -75,7 +75,7 @@ public class DotFileGraphExporter implements GraphExporter { private void WriteCluster(String scope, Graph g) throws IOException { writer.append(String.format("subgraph cluster_%s{\n", scope.substring(1))) .append(" color = black;\n") - .append(String.format(" label = \"%s\"", scope)); + .append(String.format(" label = \"%s\"", escapeDoubleQuote(scope))); for (GraphRelation graphRelation : g.getRelations()) { if (graphRelation.getSubGraphReferenceLabel().equals(scope)) { @@ -112,7 +112,7 @@ public class DotFileGraphExporter implements GraphExporter { */ private void write(UniversalWordNode universalWordNode) throws IOException { writer.append(String.valueOf(universalWordNode.getNodeNumber())) - .append(String.format(" [\nlabel=\"%s\\n", universalWordNode.getNodeId())); + .append(String.format(" [\nlabel=\"%s\\n", escapeDoubleQuote(universalWordNode.getNodeId()))); for (Object elem : universalWordNode.getAttributes()) { writer.append(elem.toString()); @@ -144,7 +144,7 @@ public class DotFileGraphExporter implements GraphExporter { .append(" -> ") .append(getTextForSubGraphRelationOrGetNodeNumber(n2, g)); - writer.append(String.format(" [label=\"%s\" ", graphRelation.getRelationLabel())) + writer.append(String.format(" [label=\"%s\" ", escapeDoubleQuote(graphRelation.getRelationLabel()))) // move the arrow tail to subgraph if nécessary (case of SubGraphReferenceNode) .append(getFormattedTextIfIsSubGraphReferenceNodeOrEmpty(" ltail=\"cluster_%s\"", n1)) // move the arrow head to subgraph if nécessary (case of SubGraphReferenceNode) @@ -153,6 +153,12 @@ public class DotFileGraphExporter implements GraphExporter { } } + private String escapeDoubleQuote(String label){ + if (null == label) return label; + + return label.replaceAll("\"", "\\\\\""); + } + /** * Get the corresponding node number for the GraphNode graphNode. * diff --git a/unl-tools-infrastructure/src/test/java/fr/tetras_libre/unltools/unl/UnlSentences.java b/unl-tools-infrastructure/src/test/java/fr/tetras_libre/unltools/unl/UnlSentences.java index 2eaec52afd1cfc4637483b818f6c2ee4c078a766..bcd2f597c527894fc5ac8891c663c3946294bb1f 100644 --- a/unl-tools-infrastructure/src/test/java/fr/tetras_libre/unltools/unl/UnlSentences.java +++ b/unl-tools-infrastructure/src/test/java/fr/tetras_libre/unltools/unl/UnlSentences.java @@ -94,6 +94,64 @@ public class UnlSentences { "[/S]\n" + "[/D]"; + public static final String Issue12 = "[S:00]\n" + + "{org:en}\n" + + "This document defines the functional requirements for ERTMS/ETCS (EUROPEAN RAIL TRAFFIC MANAGEMENT SYSTEM / EUROPEAN TRAIN CONTROL SYSTEM). \n" + + "{/org}\n" + + "{unl}\n" + + "mod(document(icl>writing>thing),this(icl>determiner>adj,mod<concrete_thing))\n" + + "aoj(define(icl>characterize>be,obj>uw,aoj>thing).@entry.@present,document(icl>writing>thing))\n" + + "mod(requirement(icl>duty>thing).@def.@pl,functional(icl>adj,ant>nonfunctional))\n" + + "obj(define(icl>characterize>be,obj>uw,aoj>thing).@entry.@present,requirement(icl>duty>thing).@def.@pl)\n" + + "or(etcs,ertms)\n" + + "pur(requirement(icl>duty>thing).@def.@pl,etcs)\n" + + "mod:01(management(icl>action,agt>volitional_thing,obj>thing),traffic(icl>collection>thing))\n" + + "mod(:03.@_hn-scope,management(icl>action,agt>volitional_thing,obj>thing))\n" + + "or:03(european(icl>inhabitant>person).@entry,system(icl>group>thing):01.@entry)\n" + + "mod:01(control(icl>power>thing),train(icl>public_transport>thing))\n" + + "mod:01(system(icl>group>thing):02,control(icl>power>thing))\n" + + "agt:02(rail(icl>complain>do,rsn>thing,agt>volitional_thing).@entry.@present,:01.@entry.@parenthesis)\n" + + "rsn:02(rail(icl>complain>do,rsn>thing,agt>volitional_thing).@entry.@present,:01.@entry.@parenthesis)\n" + + "shd(etcs,:02)\n" + + "mod(train(icl>public_transport>thing),:03.@_hn-scope)\n" + + "{/unl}\n" + + "[/S]\n" + + "[S:00]\n" + + "{org:en}\n" + + "The document primarily defines the operational requirements and therefore contains only a few technical terms. \n" + + "{/org}\n" + + "{unl}\n" + + "aoj(define(icl>characterize>be,obj>uw,aoj>thing).@entry.@present,document(icl>writing>thing).@def)\n" + + "man(define(icl>characterize>be,obj>uw,aoj>thing).@entry.@present,primarily(icl>how,equ>mainly))\n" + + "and(:01,define(icl>characterize>be,obj>uw,aoj>thing).@entry.@present)\n" + + "mod(requirement(icl>duty>thing).@def.@pl,operational(icl>adj,com>operation))\n" + + "obj(define(icl>characterize>be,obj>uw,aoj>thing).@entry.@present,requirement(icl>duty>thing).@def.@pl)\n" + + "man:01(contain(icl>be,equ>comprise,obj>abstract_thing,aoj>information,pur>abstract_thing).@entry.@present,therefore(icl>how))\n" + + "man:01(term(icl>word>thing,mod>thing).@pl,only(icl>how,equ>recently))\n" + + "qua:01(term(icl>word>thing,mod>thing).@pl,a_few(icl>adj,equ>some,qua<thing))\n" + + "mod:01(term(icl>word>thing,mod>thing).@pl,technical(icl>adj,ant>nontechnical))\n" + + "obj:01(contain(icl>be,equ>comprise,obj>abstract_thing,aoj>information,pur>abstract_thing).@entry.@present,term(icl>word>thing,mod>thing).@pl)\n" + + "{/unl}\n" + + "[/S]\n" + + "[S:00]\n" + + "{org:en}\n" + + "For consistency reasons, all functional requirements not implemented in the SRS 2.3.0 have been removed from this version.. \n" + + "{/org}\n" + + "{unl}\n" + + "agt:01(reason(icl>persuade>do,agt>thing,gol>uw,rec>person).@entry.@present,consistency(icl>uniformity>thing,ant>inconsistency))\n" + + "qua:02(requirement(icl>duty>thing).@pl,all(icl>quantity,ant>some,per>thing))\n" + + "mod:02(requirement(icl>duty>thing).@pl,functional(icl>adj,ant>nonfunctional))\n" + + "agt:02(implement(icl>employ>do,agt>thing,obj>thing).@past.@not,requirement(icl>duty>thing).@pl)\n" + + "plc(remove(icl>dismiss>do,plf>thing,agt>volitional_thing,obj>person).@entry.@present.@complete,srs.@def)\n" + + "obj(remove(icl>dismiss>do,plf>thing,agt>volitional_thing,obj>person).@entry.@present.@complete,\"2.3\".@topic)\n" + + "mod(\"2.3\".@topic,\".0\")\n" + + "mod(version(icl>interpretation>abstract_thing,agt>thing,obj>uw),this(icl>determiner>adj,mod<concrete_thing))\n" + + "plf(remove(icl>dismiss>do,plf>thing,agt>volitional_thing,obj>person).@entry.@present.@complete,version(icl>interpretation>abstract_thing,agt>thing,obj>uw))\n" + + "and(implement(icl>employ>do,agt>thing,obj>thing).@past.@not,:01)\n" + + "rsn(remove(icl>dismiss>do,plf>thing,agt>volitional_thing,obj>person).@entry.@present.@complete,:02)\n" + + "{/unl}\n" + + "[/S]\n"; + public static final String Issue13 = "[S:00]\n" + "{org:en}\n" + "(M) = Mandatory:The requirement shall be respected in every ETCS application. \n" + diff --git a/unl-tools-main/src/test/java/unl2rdf/Unl2RdfTest.java b/unl-tools-main/src/test/java/unl2rdf/Unl2RdfTest.java index 4a9dfb91cf582313bae6e2e722270098042db815..9f5c58d362eabda45334cc5641405f7a42b3a15b 100644 --- a/unl-tools-main/src/test/java/unl2rdf/Unl2RdfTest.java +++ b/unl-tools-main/src/test/java/unl2rdf/Unl2RdfTest.java @@ -49,9 +49,9 @@ class Unl2RdfTest { @Override public Stream<? extends Arguments> provideArguments(ExtensionContext extensionContext) { return Stream.of( - Arguments.of((Object) new String[]{"--input-file", "../Examples/exemples_unl.txt", "--output-file", "dotOnly", "--output-type", "dot"}), - Arguments.of((Object) new String[]{"--input-file", "../Examples/exemples_unl.txt", "--output-file", "rdfOnly", "--output-type", "rdf"}), - Arguments.of((Object) new String[]{"--input-file", "../Examples/exemples_unl.txt", "--output-file", "dotWithRdf", "--output-type", "dot,rdf"}) + Arguments.of((Object) new String[]{"--input-file", "../Examples/issue12.txt", "--output-file", "dotOnly", "--output-type", "dot"}), + Arguments.of((Object) new String[]{"--input-file", "../Examples/issue12.txt", "--output-file", "rdfOnly", "--output-type", "rdf"}), + Arguments.of((Object) new String[]{"--input-file", "../Examples/issue12.txt", "--output-file", "dotWithRdf", "--output-type", "dot,rdf"}) ); } }