Skip to content

Commit

Permalink
Fixes for asciidoc:
Browse files Browse the repository at this point in the history
- Escaping & symbol in ri:url attribute. Fixes #183
- Support for attributes in curly braces. Fixes #176

Extra: updated dependencies
  • Loading branch information
zeldigas committed Jun 24, 2024
1 parent 0a2c3cc commit 81e016c
Show file tree
Hide file tree
Showing 11 changed files with 55 additions and 23 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased

## 0.17.0 - 2024-06-24

### Added

- Check for conflict of published page with pages parent (#142)
Expand All @@ -15,12 +17,14 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
### Changed

- dependency updates:
- plantuml to 1.2024.3
- plantuml to 1.2024.5
- other deps (kotlin, ktor, logback, asciidoctor)

### Fixed

- Handling of quotes in image titles and alt text (#166)
- Escaping url for block images (#183)
- Using attributes enclosed in quotes, but not jsons (#176)

## 0.16.0 - 2024-01-07

Expand Down
2 changes: 1 addition & 1 deletion convert/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

<properties>
<flexmark.version>0.64.4</flexmark.version>
<asciidoctorj.version>2.5.12</asciidoctorj.version>
<asciidoctorj.version>2.5.13</asciidoctorj.version>
<asciidoctorj-diagram.version>2.3.0</asciidoctorj-diagram.version>
</properties>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ interface Converter {

}

open class ConversionException(message: String) : RuntimeException(message)
open class ConversionException(message: String, e: Throwable? = null) : RuntimeException(message, e)

class FileDoesNotExistException(val file: Path) : ConversionException("File does not exist: $file")
class DuplicateTitlesException(val duplicates: List<String>, message: String) : ConversionException(message)
Expand Down Expand Up @@ -64,13 +64,12 @@ internal class UniversalConverter(
) : Converter {

override fun convertFile(file: Path): Page {
val converter = converterFor(file)
if (!file.exists()) {
throw FileDoesNotExistException(file)
}

return Page(
converter.convert(file, ConvertingContext(ReferenceProvider.singleFile(), conversionParameters, space)),
performConversion(file, ConvertingContext(ReferenceProvider.singleFile(), conversionParameters, space)),
file,
emptyList()
)
Expand Down Expand Up @@ -121,14 +120,23 @@ internal class UniversalConverter(
private fun convertFilesInDirectory(dir: Path, context: ConvertingContext): List<Page> =
pagesDetector.scanDirectoryRecursively(dir,
filter = { it.supported() },
converter = { file -> converterFor(file).convert(file, context) },
converter = { file -> performConversion(file, context) },
assembler = { file, content, children -> Page(content, file, children) }
)

private fun converterFor(file: Path) =
converters[file.extension.lowercase()]
?: throw IllegalArgumentException("Unsupported extension: ${file.extension}")

private fun performConversion(file: Path, context: ConvertingContext): PageContent {
val convert = converterFor(file)
return try {
convert.convert(file, context)
} catch(e: Exception) {
throw ConversionException("Failed to convert $file: ${e.message}", e)
}
}

private fun File.supported() = isFile && !name.startsWith("_") && extension.lowercase() in converters
private fun Path.supported() = toFile().supported()
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
package com.github.zeldigas.text2confl.convert

import com.fasterxml.jackson.core.JsonParseException
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import io.github.oshai.kotlinlogging.KotlinLogging

private val logger = KotlinLogging.logger {}
private val JSON_PARSER = ObjectMapper()

fun parseAttribute(value: Any): Any {
return if (value is String) {
if (value.enclosedIn('{', '}')) {
JSON_PARSER.readValue<Map<String, *>>(value)
} else if (value.enclosedIn('[', ']')) {
JSON_PARSER.readValue<List<String>>(value)
} else {
try {
if (value.enclosedIn('{', '}')) {
JSON_PARSER.readValue<Map<String, *>>(value)
} else if (value.enclosedIn('[', ']')) {
JSON_PARSER.readValue<List<String>>(value)
} else {
value
}
} catch (e: JsonParseException) {
logger.debug(e) { "Failed to parse value $value, looks like not a valid json" }
value
}
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,9 @@ data class AsciidocRenderingParameters(

object Converter {
fun convert(string: String): String = unescapeHtml(string)

fun escapeXml(string: String) = string.replace("&", "&amp;")
.replace("<", "&lt;")
.replace(">", "&gt;")
.replace("\"", "&quot;")
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
p
= html_a_tag_if (attr? :link)
ac:image ac:height=(attr :height) ac:width=(attr :width) ac:title=(escape_quotes(title) if title?) ac:alt=(escape_quotes(attr :alt) if attr :alt) ac:thumbnail=(attr :thumbnail) ac:align=(attr :align) ac:border=(attr :border) ac:class=(attr :class) ac:style=(attr :imgstyle) ac:vspace=(attr :vspace) ac:hspace=(attr :hspace) ac:queryparams=(escape_quotes(attr :queryparams) if attr :queryparams)
- target = attr :target
- if uriish? attr :target
ri:url ri:value=(attr :target) /
ri:url ri:value=(escape_xml_attr target) /
- else
- attachment = page_attachment(attr :target)
- attachment = page_attachment(target)
- if attachment.nil?
ri:url ri:value=(attr :target) /
ri:url ri:value=(escape_xml_attr target) /
- else
ri:attachment ri:filename=(attachment) /
- if title?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,5 +291,10 @@ def escape_quotes val
val.gsub(/"/, '&quot;'.freeze)
end

def escape_xml_attr val
decoder = document.attr 't2c-decoder'
decoder.escapeXml(val)
end


end
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ internal class UniversalConverterTest(
@Test
internal fun `No file conversion for unsupported format`(@TempDir dir: Path) {
val src = dir.resolve("test.unsupported")
Files.createFile(src)

assertFailure { converter.convertFile(src) }
.isInstanceOf(IllegalArgumentException::class).hasMessage("Unsupported extension: unsupported")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ internal class RenderingOfImagesTest : RenderingTestBase() {
.A Title
image::https://example.org/test.jpg[Alt text]
image::https://example.org/test.jpg[]
image::https://example.org/test.jpg?id=12&param=b[]
image::assets/image.jpg[]
Expand All @@ -34,7 +34,7 @@ internal class RenderingOfImagesTest : RenderingTestBase() {
assertThat(result).isEqualToConfluenceFormat(
"""
<p><ac:image ac:title="A Title" ac:alt="Alt text"><ri:url ri:value="https://example.org/test.jpg" /></ac:image><div class="t2c-image-title"><em>Figure 1. A Title</em></div></p>
<p><ac:image ac:alt="test"><ri:url ri:value="https://example.org/test.jpg" /></ac:image></p>
<p><ac:image ac:alt="test"><ri:url ri:value="https://example.org/test.jpg?id=12&amp;param=b" /></ac:image></p>
<p><ac:image ac:alt="image"><ri:attachment ri:filename="an_attachment" /></ac:image></p>
<p><ac:image ac:title="&quot;Quoted text&quot; regular text &lt;special text&gt;" ac:alt="Alt"><ri:attachment ri:filename="an_attachment" /></ac:image><div class="t2c-image-title"><em>Figure 2. "Quoted text" regular text &lt;special text&gt;</em></div></p>
""".trimIndent(),
Expand All @@ -45,7 +45,7 @@ internal class RenderingOfImagesTest : RenderingTestBase() {
internal fun `Existing images inline rendering`() {
val result = toHtml(
"""
External image inside paragraph - image:https://example.org/test.jpg[Alt text,title="A Title"]
External image inside paragraph - image:https://example.org/test.jpg?id=12&param=b[Alt text,title="A Title"]
Attachment image inside paragraph - image:assets/image.jpg[Alt,title="Asset"]
""".trimIndent(),
Expand All @@ -60,7 +60,7 @@ internal class RenderingOfImagesTest : RenderingTestBase() {

assertThat(result).isEqualToConfluenceFormat(
"""
<p>External image inside paragraph - <ac:image ac:title="A Title" ac:alt="Alt text"><ri:url ri:value="https://example.org/test.jpg" /></ac:image></p>
<p>External image inside paragraph - <ac:image ac:title="A Title" ac:alt="Alt text"><ri:url ri:value="https://example.org/test.jpg?id=12&amp;param=b" /></ac:image></p>
<p>Attachment image inside paragraph - <ac:image ac:title="Asset" ac:alt="Alt"><ri:attachment ri:filename="an_attachment" /></ac:image></p>
""".trimIndent(),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ internal class RenderingOfLinksTest : RenderingTestBase() {

assertThat(result).isEqualToConfluenceFormat(
"""
<p><a href="mailto:[email protected]?subject=Subscribe+me&amp;body=I+want+to+participate.">Subscribe</a></p>
<p><a href="mailto:[email protected]?subject=Subscribe%20me&amp;body=I%20want%20to%20participate.">Subscribe</a></p>
<p>Send email to <a href="mailto:[email protected]">[email protected]</a></p>
<p><a href="mailto:[email protected]">Send email</a></p>
""".trimIndent(),
Expand Down
8 changes: 4 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<kotlin.version>1.9.24</kotlin.version>
<kotlin.version>2.0.0</kotlin.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
Expand Down Expand Up @@ -72,7 +72,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
<version>3.3.0</version>
</plugin>
</plugins>
</build>
Expand All @@ -89,7 +89,7 @@
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-bom</artifactId>
<version>1.8.0</version>
<version>1.8.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Expand Down Expand Up @@ -120,7 +120,7 @@
<dependency>
<groupId>io.github.oshai</groupId>
<artifactId>kotlin-logging-jvm</artifactId>
<version>6.0.9</version>
<version>7.0.0</version>
</dependency>
<dependency>
<groupId>io.mockk</groupId>
Expand Down

0 comments on commit 81e016c

Please sign in to comment.