Dave Jarvis' Repositories

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

Pass attributes to R svg export function

AuthorDaveJarvis <email>
Date2022-09-18 18:59:14 GMT-0700
Commitdf4428c4ffc9fea1f11bbfc48c8fa49747cfe289
Parentaddd6d9
Delta47 lines added, 2 lines removed, 45-line increase
src/main/java/com/keenwrite/processors/markdown/extensions/fences/FencedBlockExtension.java
*/
private final static String R_SVG_EXPORT =
- "tryCatch({svg('%s')%n%s%n},finally={dev.off()})%n";
+ "tryCatch({svg('%s'%s)%n%s%n},finally={dev.off()})%n";
private final static String STYLE_DIAGRAM = "diagram-";
}
+ /**
+ * Evaluates an R expression. This will take into consideration any
+ * key/value pairs passed in from the document, such as width and height
+ * attributes of the form: <code>{r width=5 height=5}</code>.
+ *
+ * @param node The {@link FencedCodeBlock} to evaluate using R.
+ * @param context Used to resolve the link that refers to any resulting
+ * image produced by the R chunk (such as a plot).
+ * @return The SVG text string associated with the content produced by
+ * the chunk (such as a graphical data plot).
+ */
+ @SuppressWarnings( "unused" )
private Tuple<String, ResolvedLink> evaluateRChunk(
final FencedCodeBlock node,
final NodeRendererContext context ) {
final var content = node.getContentChars().normalizeEOL().trim();
final var text = mRVariableProcessor.apply( content );
final var hash = Integer.toHexString( text.hashCode() );
final var filename = format( "%s-%s.svg", APP_TITLE_LOWERCASE, hash );
final var svg = Paths.get( TEMP_DIR, filename ).toString();
final var link = context.resolveLink( LINK, svg, false );
- final var r = format( R_SVG_EXPORT, svg, text );
+ final var dimensions = getAttributes( node.getInfo() );
+ final var r = format( R_SVG_EXPORT, svg, dimensions, text );
final var result = mRChunkEvaluator.apply( r );
return new Tuple<>( svg, link );
+ }
+
+ /**
+ * Splits attributes of the form <code>{r key1=value2 key2=value2}</code>
+ * into a comma-separated string containing only the key/value pairs,
+ * such as <code>key1=value1,key2=value2</code>.
+ *
+ * @param bs The complete line after the fenced block demarcation.
+ * @return A comma-separated string of name/value pairs.
+ */
+ private String getAttributes( final BasedSequence bs ) {
+ final var result = new StringBuilder();
+ final var split = bs.splitList( " " );
+ final var splits = split.size();
+
+ for( var i = 1; i < splits; i++ ) {
+ final var based = split.get( i ).toString();
+ final var attribute = based.replace( '}', ' ' );
+
+ // The order of attribute evaluations is in order of performance.
+ if( !attribute.isBlank() &&
+ attribute.indexOf( '=' ) > 1 &&
+ attribute.matches( ".*\\d.*" ) ) {
+
+ // The comma will do double-duty for separating individual attributes
+ // as well as being the comma that separates all attributes from the
+ // SVG image file name.
+ result.append( ',' ).append( attribute );
+ }
+ }
+
+ return result.toString();
}