Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/keenwrite.git

Find SVG files using base element set in HTML

AuthorDaveJarvis <email>
Date2020-11-11 00:31:56 GMT-0800
Commit2bfe23c3aeaddef87870f85b4d4f61c60ac59e28
Parent6602414
Delta56 lines added, 22 lines removed, 34-line increase
src/main/resources/com/keenwrite/preview/webview.css
img {
max-width: 100%;
+
+ /**
+ * Required for FlyingSaucer to treat images
+ * as block elements. See SvhReplacedElementFactory
+ * for details.
+ */
+ display: inline-block;
}
/* Required for FlyingSaucer to detect the node.
- * See SVGReplacedElementFactory for details.
+ * See SvhReplacedElementFactory for details.
*/
tex {
src/main/java/com/keenwrite/processors/text/TextReplacementFactory.java
*/
public static TextReplacer getTextReplacer( final int length ) {
- // After about 1,500 characters, the StringUtils implementation is less
- // performant than the Aho-Corsick implementation.
- //
- // See http://stackoverflow.com/a/40836618/59087
+ // After about 1,500 characters, the StringUtils implementation is slower
+ // than the Aho-Corsick algorithm implementation.
return length < 1500 ? APACHE : AHO_CORASICK;
}
src/main/java/com/keenwrite/preview/SvgReplacedElementFactory.java
import com.keenwrite.util.BoundedCache;
-import org.apache.commons.io.FilenameUtils;
import org.w3c.dom.Element;
import org.xhtmlrenderer.extend.ReplacedElement;
import java.awt.image.BufferedImage;
+import java.net.URI;
+import java.nio.file.Paths;
import java.util.Map;
import java.util.function.Function;
import static com.keenwrite.StatusBarNotifier.clue;
+import static com.keenwrite.io.File.getMediaType;
+import static com.keenwrite.io.MediaType.IMAGE_SVG_XML;
+import static com.keenwrite.preview.SvgRasterizer.BROKEN_IMAGE_PLACEHOLDER;
import static com.keenwrite.preview.SvgRasterizer.rasterize;
import static com.keenwrite.processors.markdown.tex.TexNode.HTML_TEX;
return MathRendererContainer.INSTANCE;
}
-
- /**
- * SVG filename extension maps to an SVG image element.
- */
- private static final String SVG_FILE = "svg";
private static final String HTML_IMAGE = "img";
if( e != null ) {
- try {
- final var nodeName = e.getNodeName();
-
- if( HTML_IMAGE.equals( nodeName ) ) {
+ switch( e.getNodeName() ) {
+ case HTML_IMAGE -> {
final var src = e.getAttribute( HTML_IMAGE_SRC );
- final var ext = FilenameUtils.getExtension( src );
- if( SVG_FILE.equalsIgnoreCase( ext ) ) {
- image = getCachedImage(
- src, svg -> rasterize( svg, box.getContentWidth() ) );
+ if( getMediaType( src ) == IMAGE_SVG_XML ) {
+ try {
+ final var baseUri = getBaseUri( e );
+ final var uri = new URI( baseUri ).getPath();
+ final var path = Paths.get( uri, src );
+ System.out.println( "SVG PATH: " + path );
+
+ image = getCachedImage(
+ src, svg -> rasterize( path, box.getContentWidth() ) );
+ } catch( final Exception ex ) {
+ image = BROKEN_IMAGE_PLACEHOLDER;
+ clue( ex );
+ }
}
}
- else if( HTML_TEX.equals( nodeName ) ) {
+ case HTML_TEX -> {
// Convert the TeX element to a raster graphic if not yet cached.
final var src = e.getTextContent();
image = getCachedImage(
src, __ -> rasterize( getInstance().render( src ) )
);
}
- } catch( final Exception ex ) {
- clue( ex );
}
}
return null;
+ }
+
+ private String getBaseUri( final Element e ) {
+ try {
+ final var doc = e.getOwnerDocument();
+ final var html = doc.getDocumentElement();
+ final var head = html.getFirstChild();
+ final var children = head.getChildNodes();
+
+ for( int i = children.getLength() - 1; i >= 0; i-- ) {
+ final var child = children.item( i );
+ final var name = child.getLocalName();
+
+ if( "base".equalsIgnoreCase( name ) ) {
+ final var attrs = child.getAttributes();
+ final var item = attrs.getNamedItem( "href" );
+
+ return item.getNodeValue();
+ }
+ }
+ } catch( final Exception ex ) {
+ clue( ex );
+ }
+
+ return "";
}