Skip to content
Snippets Groups Projects
Commit b41a63e6 authored by dgelessus's avatar dgelessus
Browse files

Add support for parsing first line of cell separately from body

parent 5a378b0f
No related branches found
No related tags found
No related merge requests found
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` prob ``` prob
:help ::render :help ::render
``` ```
%% Output %% Output
``` ```
::render MIMETYPE ::render MIMETYPE
CONTENT CONTENT
``` ```
Render some content with the specified MIME type. Render some content with the specified MIME type.
This command is intended for debugging the rendering behavior of Jupyter and the kernel, it should not be used in regular notebooks. To include text or images in a notebook, Markdown cells should be used instead. This command is intended for debugging the rendering behavior of Jupyter and the kernel, it should not be used in regular notebooks. To include text or images in a notebook, Markdown cells should be used instead.
The command does not place any restrictions on the MIME type or content. A plain text fallback with the raw content is always included, and will be displayed if the frontend does not support the given MIME type. The command does not place any restrictions on the MIME type or content. A plain text fallback with the raw content is always included, and will be displayed if the frontend does not support the given MIME type.
::render MIMETYPE ::render MIMETYPE
CONTENT CONTENT
Render some content with the specified MIME type. Render some content with the specified MIME type.
This command is intended for debugging the rendering behavior of Jupyter and the kernel, it should not be used in regular notebooks. To include text or images in a notebook, Markdown cells should be used instead. This command is intended for debugging the rendering behavior of Jupyter and the kernel, it should not be used in regular notebooks. To include text or images in a notebook, Markdown cells should be used instead.
The command does not place any restrictions on the MIME type or content. A plain text fallback with the raw content is always included, and will be displayed if the frontend does not support the given MIME type. The command does not place any restrictions on the MIME type or content. A plain text fallback with the raw content is always included, and will be displayed if the frontend does not support the given MIME type.
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` prob ``` prob
::render text/plain ::render text/plain
This is plain text. This is plain text.
``` ```
%% Output %% Output
This is plain text. This is plain text.
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` prob ``` prob
::render text/markdown ::render text/markdown
This *is* **Markdown!** Also supports embedded $\LaTeX$ math. This *is* **Markdown!** Also supports embedded $\LaTeX$ math.
``` ```
%% Output %% Output
This *is* **Markdown!** Also supports embedded $\LaTeX$ math. This *is* **Markdown!** Also supports embedded $\LaTeX$ math.
text/markdown: text/markdown:
This *is* **Markdown!** Also supports embedded $\LaTeX$ math. This *is* **Markdown!** Also supports embedded $\LaTeX$ math.
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` prob ``` prob
::render text/latex ::render text/latex
This is text with embedded $\LaTeX$ math, but *no* Markdown. This is text with embedded $\LaTeX$ math, but *no* Markdown.
``` ```
%% Output %% Output
This is text with embedded $\LaTeX$ math, but *no* Markdown. This is text with embedded $\LaTeX$ math, but *no* Markdown.
text/latex: text/latex:
This is text with embedded $\LaTeX$ math, but *no* Markdown. This is text with embedded $\LaTeX$ math, but *no* Markdown.
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` prob ``` prob
::render text/html ::render text/html
This <em>is</em> <a href="https://html.spec.whatwg.org/multipage/">HTML</a>. This <em>is</em> <a href="https://html.spec.whatwg.org/multipage/">HTML</a>.
``` ```
%% Output %% Output
text/html: text/html:
This <em>is</em> <a href="https://html.spec.whatwg.org/multipage/">HTML</a>. This <em>is</em> <a href="https://html.spec.whatwg.org/multipage/">HTML</a>.
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` prob ``` prob
::render image/svg+xml ::render image/svg+xml
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<!-- <!--
Based on: Based on:
https://en.wikipedia.org/w/index.php?title=Scalable_Vector_Graphics&oldid=843316249#Example https://en.wikipedia.org/w/index.php?title=Scalable_Vector_Graphics&oldid=843316249#Example
--> -->
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="250" height="250"> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="250" height="250">
<rect x="25" y="25" width="200" height="200" fill="lime" stroke-width="4" stroke="pink" /> <rect x="25" y="25" width="200" height="200" fill="lime" stroke-width="4" stroke="pink" />
<circle cx="125" cy="125" r="75" fill="orange" /> <circle cx="125" cy="125" r="75" fill="orange" />
<polyline points="50,150 50,200 200,200 200,100" stroke="red" stroke-width="4" fill="none" /> <polyline points="50,150 50,200 200,200 200,100" stroke="red" stroke-width="4" fill="none" />
<line x1="50" y1="50" x2="200" y2="200" stroke="blue" stroke-width="4" /> <line x1="50" y1="50" x2="200" y2="200" stroke="blue" stroke-width="4" />
</svg> </svg>
``` ```
%% Output %% Output
image/svg+xml: image/svg+xml:
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<!-- <!--
Based on: Based on:
https://en.wikipedia.org/w/index.php?title=Scalable_Vector_Graphics&oldid=843316249#Example https://en.wikipedia.org/w/index.php?title=Scalable_Vector_Graphics&oldid=843316249#Example
--> -->
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="250" height="250"> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="250" height="250">
<rect x="25" y="25" width="200" height="200" fill="lime" stroke-width="4" stroke="pink" /> <rect x="25" y="25" width="200" height="200" fill="lime" stroke-width="4" stroke="pink" />
<circle cx="125" cy="125" r="75" fill="orange" /> <circle cx="125" cy="125" r="75" fill="orange" />
<polyline points="50,150 50,200 200,200 200,100" stroke="red" stroke-width="4" fill="none" /> <polyline points="50,150 50,200 200,200 200,100" stroke="red" stroke-width="4" fill="none" />
<line x1="50" y1="50" x2="200" y2="200" stroke="blue" stroke-width="4" /> <line x1="50" y1="50" x2="200" y2="200" stroke="blue" stroke-width="4" />
</svg> </svg>
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
The content must be on a separate line. The content must be on a separate line.
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` prob ``` prob
::render text/markdown This *is* **Markdown!** ::render text/markdown This *is* **Markdown!**
``` ```
%% Output %% Output
::render: Missing content (the content cannot be placed on the same line as the command) ::render: Missing required body content
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
The MIME type is required. The MIME type is required.
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` prob ``` prob
::render ::render
This is... something. This is... something.
``` ```
%% Output %% Output
::render: Missing MIME type ::render: Missing required parameter mimeType
......
...@@ -120,7 +120,19 @@ public final class CommandUtils { ...@@ -120,7 +120,19 @@ public final class CommandUtils {
public static @NotNull ParsedArguments parseArgs(final @NotNull Parameters parameters, final @NotNull String argString) { public static @NotNull ParsedArguments parseArgs(final @NotNull Parameters parameters, final @NotNull String argString) {
final ParsedArguments parsed = new ParsedArguments(Collections.emptyMap()); final ParsedArguments parsed = new ParsedArguments(Collections.emptyMap());
String remainingArgs = argString; String remainingArgs;
if (parameters.getBodyParam().isPresent()) {
final String[] split = argString.split("\n", 2);
final PositionalParameter.RequiredRemainder bodyParam = parameters.getBodyParam().get();
if (split.length < 2) {
throw new UserErrorException("Missing required body " + bodyParam.getIdentifier());
}
remainingArgs = split[0];
parsed.put(bodyParam, split[1]);
} else {
remainingArgs = argString;
}
for (final PositionalParameter<?> param : parameters.getPositionalParameters()) { for (final PositionalParameter<?> param : parameters.getPositionalParameters()) {
if (remainingArgs.isEmpty()) { if (remainingArgs.isEmpty()) {
break; break;
......
...@@ -2,15 +2,18 @@ package de.prob2.jupyter; ...@@ -2,15 +2,18 @@ package de.prob2.jupyter;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Optional;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public final class Parameters { public final class Parameters {
public static final @NotNull Parameters NONE = new Parameters(Collections.emptyList()); public static final @NotNull Parameters NONE = new Parameters(Collections.emptyList());
private final @NotNull List<PositionalParameter<?>> positionalParameters; private final @NotNull List<PositionalParameter<?>> positionalParameters;
private final @Nullable PositionalParameter.RequiredRemainder bodyParam;
public Parameters(final @NotNull List<PositionalParameter<?>> positionalParameters) { public Parameters(final @NotNull List<PositionalParameter<?>> positionalParameters, final @Nullable PositionalParameter.RequiredRemainder bodyParam) {
super(); super();
this.positionalParameters = positionalParameters; this.positionalParameters = positionalParameters;
...@@ -29,9 +32,19 @@ public final class Parameters { ...@@ -29,9 +32,19 @@ public final class Parameters {
seenOptional |= isOptional; seenOptional |= isOptional;
seenOnlyLast |= isOnlyLast; seenOnlyLast |= isOnlyLast;
} }
this.bodyParam = bodyParam;
}
public Parameters(final @NotNull List<PositionalParameter<?>> positionalParameters) {
this(positionalParameters, null);
} }
public @NotNull List<PositionalParameter<?>> getPositionalParameters() { public @NotNull List<PositionalParameter<?>> getPositionalParameters() {
return this.positionalParameters; return this.positionalParameters;
} }
public @NotNull Optional<PositionalParameter.RequiredRemainder> getBodyParam() {
return Optional.ofNullable(this.bodyParam);
}
} }
...@@ -17,7 +17,6 @@ import de.prob2.jupyter.Parameters; ...@@ -17,7 +17,6 @@ import de.prob2.jupyter.Parameters;
import de.prob2.jupyter.ParsedArguments; import de.prob2.jupyter.ParsedArguments;
import de.prob2.jupyter.PositionalParameter; import de.prob2.jupyter.PositionalParameter;
import de.prob2.jupyter.ProBKernel; import de.prob2.jupyter.ProBKernel;
import de.prob2.jupyter.UserErrorException;
import io.github.spencerpark.jupyter.kernel.ReplacementOptions; import io.github.spencerpark.jupyter.kernel.ReplacementOptions;
import io.github.spencerpark.jupyter.kernel.display.DisplayData; import io.github.spencerpark.jupyter.kernel.display.DisplayData;
...@@ -26,7 +25,8 @@ import org.jetbrains.annotations.NotNull; ...@@ -26,7 +25,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
public final class LoadCellCommand implements Command { public final class LoadCellCommand implements Command {
private static final @NotNull PositionalParameter.RequiredRemainder PREFS_AND_CODE_PARAM = new PositionalParameter.RequiredRemainder("prefsAndCode"); private static final @NotNull PositionalParameter.OptionalRemainder PREFS_PARAM = new PositionalParameter.OptionalRemainder("prefs");
private static final @NotNull PositionalParameter.RequiredRemainder CODE_PARAM = new PositionalParameter.RequiredRemainder("code");
private final @NotNull ClassicalBFactory classicalBFactory; private final @NotNull ClassicalBFactory classicalBFactory;
private final @NotNull AnimationSelector animationSelector; private final @NotNull AnimationSelector animationSelector;
...@@ -52,7 +52,7 @@ public final class LoadCellCommand implements Command { ...@@ -52,7 +52,7 @@ public final class LoadCellCommand implements Command {
@Override @Override
public @NotNull Parameters getParameters() { public @NotNull Parameters getParameters() {
return new Parameters(Collections.singletonList(PREFS_AND_CODE_PARAM)); return new Parameters(Collections.singletonList(PREFS_PARAM), CODE_PARAM);
} }
@Override @Override
...@@ -74,13 +74,8 @@ public final class LoadCellCommand implements Command { ...@@ -74,13 +74,8 @@ public final class LoadCellCommand implements Command {
@Override @Override
public @NotNull DisplayData run(final @NotNull ParsedArguments args) { public @NotNull DisplayData run(final @NotNull ParsedArguments args) {
final String[] split = args.get(PREFS_AND_CODE_PARAM).split("\n", 2); final String body = args.get(CODE_PARAM);
if (split.length != 2) { final List<String> prefsSplit = args.get(PREFS_PARAM).map(CommandUtils::splitArgs).orElse(Collections.emptyList());
throw new UserErrorException("Missing command body");
}
final String prefsString = split[0];
final String body = split[1];
final List<String> prefsSplit = CommandUtils.splitArgs(prefsString);
final Map<String, String> preferences = CommandUtils.parsePreferences(prefsSplit); final Map<String, String> preferences = CommandUtils.parsePreferences(prefsSplit);
this.animationSelector.changeCurrentAnimation(new Trace(CommandUtils.withSourceCode(body, () -> this.animationSelector.changeCurrentAnimation(new Trace(CommandUtils.withSourceCode(body, () ->
......
...@@ -8,7 +8,6 @@ import de.prob2.jupyter.Command; ...@@ -8,7 +8,6 @@ import de.prob2.jupyter.Command;
import de.prob2.jupyter.Parameters; import de.prob2.jupyter.Parameters;
import de.prob2.jupyter.ParsedArguments; import de.prob2.jupyter.ParsedArguments;
import de.prob2.jupyter.PositionalParameter; import de.prob2.jupyter.PositionalParameter;
import de.prob2.jupyter.UserErrorException;
import io.github.spencerpark.jupyter.kernel.ReplacementOptions; import io.github.spencerpark.jupyter.kernel.ReplacementOptions;
import io.github.spencerpark.jupyter.kernel.display.DisplayData; import io.github.spencerpark.jupyter.kernel.display.DisplayData;
...@@ -17,7 +16,8 @@ import org.jetbrains.annotations.NotNull; ...@@ -17,7 +16,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
public final class RenderCommand implements Command { public final class RenderCommand implements Command {
private static final @NotNull PositionalParameter.RequiredRemainder MIME_TYPE_AND_CONTENT_PARAM = new PositionalParameter.RequiredRemainder("mimeTypeAndContent"); private static final @NotNull PositionalParameter.RequiredSingle MIME_TYPE_PARAM = new PositionalParameter.RequiredSingle("mimeType");
private static final @NotNull PositionalParameter.RequiredRemainder CONTENT_PARAM = new PositionalParameter.RequiredRemainder("content");
@Inject @Inject
private RenderCommand() { private RenderCommand() {
...@@ -31,7 +31,7 @@ public final class RenderCommand implements Command { ...@@ -31,7 +31,7 @@ public final class RenderCommand implements Command {
@Override @Override
public @NotNull Parameters getParameters() { public @NotNull Parameters getParameters() {
return new Parameters(Collections.singletonList(MIME_TYPE_AND_CONTENT_PARAM)); return new Parameters(Collections.singletonList(MIME_TYPE_PARAM), CONTENT_PARAM);
} }
@Override @Override
...@@ -52,15 +52,8 @@ public final class RenderCommand implements Command { ...@@ -52,15 +52,8 @@ public final class RenderCommand implements Command {
@Override @Override
public @NotNull DisplayData run(final @NotNull ParsedArguments args) { public @NotNull DisplayData run(final @NotNull ParsedArguments args) {
final String[] split = args.get(MIME_TYPE_AND_CONTENT_PARAM).split("\n", 2); final String mimeType = args.get(MIME_TYPE_PARAM);
if (split.length != 2) { final String code = args.get(CONTENT_PARAM);
throw new UserErrorException("Missing content (the content cannot be placed on the same line as the command)");
}
final String mimeType = split[0];
final String code = split[1];
if (mimeType.isEmpty()) {
throw new UserErrorException("Missing MIME type");
}
final DisplayData data = new DisplayData(mimeType + ":\n" + code); final DisplayData data = new DisplayData(mimeType + ":\n" + code);
data.putData(mimeType, code); data.putData(mimeType, code);
return data; return data;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment