Skip to content

Commit

Permalink
Merge pull request #40 from fkleedorfer/fix_numeric_literals
Browse files Browse the repository at this point in the history
Fix numeric literal formatting
  • Loading branch information
atextor authored Nov 2, 2024
2 parents 0739515 + aa55f2d commit 16fb9f0
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 2 deletions.
12 changes: 10 additions & 2 deletions src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ public class TurtleFormatter implements Function<Model, String>, BiConsumer<Mode

private static final Logger LOG = LoggerFactory.getLogger( TurtleFormatter.class );

private static final Pattern XSD_DECIMAL_UNQUOTED_REGEX = Pattern.compile("[+-]?\\d*\\.\\d+");

private static final Pattern XSD_DOUBLE_UNQUOTED_REGEX = Pattern.compile("(([+-]?\\d+\\.\\d+)|([+-]?\\.\\d+)|([+-]?\\d+))[eE][+-]?\\d+");

/**
* String escape sequences as described in <a href="https://www.w3.org/TR/turtle/#sec-escapes">Escape Sequences</a>.
* <p>
Expand Down Expand Up @@ -626,7 +630,8 @@ private State writeLiteral( final Literal literal, final State state ) {
if ( datatypeUri.equals( XSD.xdouble.getURI() ) ) {
if ( style.enableDoubleFormatting ) {
return state.write( style.doubleFormat.format( literal.getDouble() ) );
} else {
} else if (XSD_DOUBLE_UNQUOTED_REGEX.matcher(literal.getLexicalForm()).matches()) {
// only use unquoted form if it will be parsed as an xsd:double
return state.write( literal.getLexicalForm() );
}
}
Expand All @@ -637,7 +642,10 @@ private State writeLiteral( final Literal literal, final State state ) {
return state.write( quoteAndEscape( literal ) );
}
if ( datatypeUri.equals( XSD.decimal.getURI() ) ) {
return state.write( literal.getLexicalForm() );
if (XSD_DECIMAL_UNQUOTED_REGEX.matcher(literal.getLexicalForm()).matches()) {
// only use unquoted form if it will be parsed as an xsd:decimal
return state.write(literal.getLexicalForm());
}
}
if ( datatypeUri.equals( XSD.integer.getURI() ) ) {
return state.write( literal.getLexicalForm() );
Expand Down
73 changes: 73 additions & 0 deletions src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1084,6 +1084,79 @@ public void testIntegerLiteralWithLeadingZeros(){
assertThat(result.trim()).isEqualTo(expected);
}

@Test
public void testDoubleLiteralWithoutFractions(){
String content = """
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix : <http://example.com/ns#> .
:thing :value "40"^^xsd:double.
""";
String expected = """
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix : <http://example.com/ns#> .
:thing :value "40"^^xsd:double .""";
final FormattingStyle style = FormattingStyle.DEFAULT;
final TurtleFormatter formatter = new TurtleFormatter(style);
final String result = formatter.applyToContent(content);
assertThat(result.trim()).isEqualTo(expected);
}

@Test
public void testDoubleLiteralWithFractions(){
String content = """
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix : <http://example.com/ns#> .
:thing :value "4.001E2"^^xsd:double.
""";
String expected = """
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix : <http://example.com/ns#> .
:thing :value 4.001E2 .""";
final FormattingStyle style = FormattingStyle.DEFAULT;
final TurtleFormatter formatter = new TurtleFormatter(style);
final String result = formatter.applyToContent(content);
assertThat(result.trim()).isEqualTo(expected);
}

@Test
public void testDecimalLiteralWithoutFractions(){
String content = """
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix : <http://example.com/ns#> .
:thing :value "40"^^xsd:decimal.
""";
String expected = """
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix : <http://example.com/ns#> .
:thing :value "40"^^xsd:decimal .""";
final FormattingStyle style = FormattingStyle.DEFAULT;
final TurtleFormatter formatter = new TurtleFormatter(style);
final String result = formatter.applyToContent(content);
assertThat(result.trim()).isEqualTo(expected);
}

@Test
public void testDecimalLiteralWithFractions(){
String content = """
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix : <http://example.com/ns#> .
:thing :value "40.0001"^^xsd:decimal.
""";
String expected = """
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix : <http://example.com/ns#> .
:thing :value 40.0001 .""";
final FormattingStyle style = FormattingStyle.DEFAULT;
final TurtleFormatter formatter = new TurtleFormatter(style);
final String result = formatter.applyToContent(content);
assertThat(result.trim()).isEqualTo(expected);
}


private Model modelFromString( final String content ) {
final Model model = ModelFactory.createDefaultModel();
final InputStream stream = new ByteArrayInputStream( content.getBytes( StandardCharsets.UTF_8 ) );
Expand Down

0 comments on commit 16fb9f0

Please sign in to comment.