backend/app/services/previewing/HtmlPreviewGenerator.scala (34 lines of code) (raw):

package services.previewing import java.io.InputStream import java.nio.file.Path import com.amazonaws.util.StringInputStream import org.jsoup.Jsoup import org.jsoup.nodes.Document class HtmlPreviewGenerator(binary: String, workspace: Path) extends PreviewGenerator(workspace, temporaryFileExtension = "tmp.html") { override def transform(data: InputStream): InputStream = { // JSoup will attempt to detect charset or fallback to UTF-8 val cleansed = HtmlPreviewGenerator.clean(Jsoup.parse(data, null, ".")) new StringInputStream(cleansed) } override def buildCommand(workspace: String, input: String, output: String): Seq[String] = { Seq(binary, "--enable-local-file-access", input, output) } } object HtmlPreviewGenerator { val REPLACEMENT_IMAGE = """<svg fill="currentColor" width="50" height="50" viewBox="0 0 40 40" style="vertical-align:middle;display:inline-block;fill:#666;" size="50" preserveAspectRatio="xMidYMid meet"><g><path d="m30 19.063333333333336l5 5v7.578333333333333q0 1.3283333333333367-1.0166666666666657 2.34333333333333t-2.3416666666666686 1.0166666666666657h-23.28333333333333q-1.3266666666666689 0-2.3416666666666686-1.0166666666666657t-1.0166666666666657-2.341666666666665v-10.938333333333333l5 5 6.641666666666666-6.716666666666669 6.716666666666669 6.716666666666669z m5-10.703333333333333v10.938333333333333l-5-5-6.640000000000001 6.716666666666669-6.716666666666669-6.716666666666669-6.643333333333331 6.71833333333333-5-5.078333333333331v-7.578333333333333q0-1.3283333333333331 1.0166666666666666-2.3433333333333337t2.3433333333333346-1.0166666666666675h23.28333333333334q1.326666666666668 0 2.3416666666666686 1.0166666666666666t1.0149999999999935 2.3433333333333346z"></path></g></svg>""" def clean(input: Document): String = { input.select("a[href]").attr("href", "#") input.select("""img:not(img[src^="data:"])""").tagName("div").html(REPLACEMENT_IMAGE) input.select("script").remove() val headerHide = """ |<style> |@media print { | @page { margin: 0; } | body { margin: 1.6cm; } |} |</style> """.stripMargin input.select("head").append(headerHide) input.html() } }