| Author | DaveJarvis <email> |
|---|---|
| Date | 2022-05-14 23:47:30 GMT-0700 |
| Commit | 034e0469b112eb68f91c8278c4676718f638a425 |
| Parent | 5f96d01 |
| Delta | 125 lines added, 57 lines removed, 68-line increase |
| Main.status.error.bootstrap.eval=Note: Bootstrap variable of ''{0}'' not found | ||
| -Main.status.error.parse={0} (near ${Main.status.text.offset} {1}) | ||
| +Main.status.error.parse=Evaluation error: {0} | ||
| Main.status.error.def.blank=Move the caret to a word before inserting a variable | ||
| Main.status.error.def.empty=Create a variable before inserting one |
| } | ||
| - public void file_export_markdown() { | ||
| - file_export( MARKDOWN_PLAIN ); | ||
| - } | ||
| - | ||
| private void fireExportFailedEvent() { | ||
| runLater( ExportFailedEvent::fire ); |
| +/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | ||
| +package com.keenwrite.processors.r; | ||
| + | ||
| +import com.keenwrite.processors.ProcessorContext; | ||
| + | ||
| +import java.util.function.Function; | ||
| + | ||
| +import static com.keenwrite.constants.Constants.STATUS_PARSE_ERROR; | ||
| +import static com.keenwrite.events.StatusEvent.clue; | ||
| + | ||
| +/** | ||
| + * Transforms a document containing R statements into Markdown. The statements | ||
| + * are part of an R chunk, <code>```{r}</code>. | ||
| + */ | ||
| +public final class RChunkEvaluator implements Function<String, String> { | ||
| + | ||
| + private final ProcessorContext mContext; | ||
| + | ||
| + /** | ||
| + * Constructs an evaluator capable of executing R statements. | ||
| + * | ||
| + * @param context Used to initialize the {@link RBootstrapController}. | ||
| + */ | ||
| + public RChunkEvaluator( final ProcessorContext context ) { | ||
| + mContext = context; | ||
| + } | ||
| + | ||
| + /** | ||
| + * Evaluates the given R statements and returns the result as a string. | ||
| + * If an image was produced, the calling code is responsible for persisting | ||
| + * and making the file embeddable into the document. | ||
| + * | ||
| + * @param r The R statements to evaluate. | ||
| + * @return The output from the final R statement. | ||
| + */ | ||
| + @Override | ||
| + public String apply( final String r ) { | ||
| + try { | ||
| + RBootstrapController.init( mContext ); | ||
| + return Engine.eval( r ); | ||
| + } catch( final Exception ex ) { | ||
| + clue( STATUS_PARSE_ERROR, ex.getMessage() ); | ||
| + | ||
| + return r; | ||
| + } | ||
| + } | ||
| +} | ||
| +/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | ||
| +package com.keenwrite.processors.r; | ||
| + | ||
| +import com.keenwrite.processors.Processor; | ||
| +import com.keenwrite.processors.ProcessorContext; | ||
| + | ||
| +import java.util.function.Function; | ||
| +import java.util.function.Predicate; | ||
| + | ||
| +import static com.keenwrite.constants.Constants.STATUS_PARSE_ERROR; | ||
| +import static com.keenwrite.events.StatusEvent.clue; | ||
| +import static com.keenwrite.processors.IdentityProcessor.IDENTITY; | ||
| + | ||
| +/** | ||
| + * Evaluates inline R statements. | ||
| + */ | ||
| +public final class RInlineEvaluator | ||
| + implements Function<String, String>, Predicate<String> { | ||
| + public static final String PREFIX = "`r#"; | ||
| + public static final String SUFFIX = "`"; | ||
| + | ||
| + private static final int PREFIX_LENGTH = PREFIX.length(); | ||
| + private static final int SUFFIX_LENGTH = SUFFIX.length(); | ||
| + | ||
| + private final Processor<String> mProcessor; | ||
| + | ||
| + /** | ||
| + * Constructs an evaluator capable of executing R statements. | ||
| + */ | ||
| + public RInlineEvaluator( final ProcessorContext context ) { | ||
| + mProcessor = new RVariableProcessor( IDENTITY, context ); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Evaluates all R statements in the source document and inserts the | ||
| + * calculated value into the generated document. | ||
| + * | ||
| + * @param text The document text that includes variables that should be | ||
| + * replaced with values when rendered as HTML. | ||
| + * @return The generated document with output from all R statements | ||
| + * substituted with value returned from their execution. | ||
| + */ | ||
| + @Override | ||
| + public String apply( final String text ) { | ||
| + try { | ||
| + final var len = text.length(); | ||
| + final var r = mProcessor.apply( | ||
| + text.substring( PREFIX_LENGTH, len - SUFFIX_LENGTH ) | ||
| + ); | ||
| + | ||
| + // Return the evaluated R expression for insertion back into the text. | ||
| + return Engine.eval( r ); | ||
| + } catch( final Exception ex ) { | ||
| + clue( STATUS_PARSE_ERROR, ex.getMessage() ); | ||
| + | ||
| + // If the string couldn't be parsed using R, append the statement | ||
| + // that failed to parse, instead of its evaluated value. | ||
| + return text; | ||
| + } | ||
| + } | ||
| + | ||
| + /** | ||
| + * Answers whether the engine associated with this evaluator may attempt to | ||
| + * evaluate the given source code statement. | ||
| + * | ||
| + * @param code The source code to verify. | ||
| + * @return {@code true} if the code may be evaluated. | ||
| + */ | ||
| + @Override | ||
| + public boolean test( final String code ) { | ||
| + return code.startsWith( PREFIX ); | ||
| + } | ||
| +} | ||
| -/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | ||
| -package com.keenwrite.processors.r; | ||
| - | ||
| -import com.keenwrite.processors.ExecutorProcessor; | ||
| -import com.keenwrite.processors.Processor; | ||
| -import com.keenwrite.processors.ProcessorContext; | ||
| - | ||
| -import java.util.function.Function; | ||
| - | ||
| -import static com.keenwrite.processors.IdentityProcessor.IDENTITY; | ||
| - | ||
| -/** | ||
| - * Responsible for processing R statements within a text block. | ||
| - */ | ||
| -public final class RProcessor | ||
| - extends ExecutorProcessor<String> implements Function<String, String> { | ||
| - private final Processor<String> mProcessor; | ||
| - private final InlineRProcessor mInlineRProcessor; | ||
| - | ||
| - public RProcessor( final ProcessorContext context ) { | ||
| - final var irp = new InlineRProcessor( IDENTITY, context ); | ||
| - final var rvp = new RVariableProcessor( irp, context ); | ||
| - | ||
| - mProcessor = new ExecutorProcessor<>( rvp ); | ||
| - mInlineRProcessor = irp; | ||
| - } | ||
| - | ||
| - public String apply( final String text ) { | ||
| - if( !mInlineRProcessor.isReady() ) { | ||
| - mInlineRProcessor.init(); | ||
| - } | ||
| - | ||
| - return mProcessor.apply( text ); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Called when the {@link InlineRProcessor} is instantiated, which triggers | ||
| - * a re-evaluation of all R expressions in the document. Without this, when | ||
| - * the document is first viewed, no R expressions are evaluated until the | ||
| - * user interacts with the document. | ||
| - */ | ||
| - public void init() { | ||
| - mInlineRProcessor.init(); | ||
| - } | ||
| - | ||
| - public boolean isReady() { | ||
| - return mInlineRProcessor.isReady(); | ||
| - } | ||
| -} | ||
| package com.keenwrite.processors.r; | ||
| +import com.keenwrite.processors.Processor; | ||
| import com.keenwrite.processors.ProcessorContext; | ||
| import com.keenwrite.processors.VariableProcessor; | ||
| * <pre>v$tree$leaf</pre>. | ||
| */ | ||
| -public final class RVariableProcessor extends VariableProcessor { | ||
| +public class RVariableProcessor extends VariableProcessor { | ||
| public RVariableProcessor( | ||
| - final InlineRProcessor irp, final ProcessorContext context ) { | ||
| - super( irp, context ); | ||
| + final Processor<String> successor, final ProcessorContext context ) { | ||
| + super( successor, context ); | ||
| } | ||