Open cheezopath opened 1 year ago
Does this functionality make sense to include in the default suite of scripts?
Eventually, yes, probably. Filtering/excluding parts of notes seems in-scope for default steps.
Is it easy to implement?
Right now, sort of, but not trivially. The correct way to make this achievable would be to figure out how to expose the structural meaning of the markdown (what programmers would call the AST) to steps; that doesn't happen right now, but it would make writing this sort of step far easier.
In the short term you could probably get away with a custom step that uses a regex to match the content you want, then return that content from the step. It's less learning javascript than figuring out the regex. If you use templates to get the same format for every note then figuring out the regex to match a part of that note shouldn't be too bad; once you have the regex, the step would look something like:
// See docs for `input` and `context` types and expected return type.
async function compile(input, context) {
const regex = ... // your regex here
return input.map((sceneInput) => {
// see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match
// for more on getting the results of a regex (e.g. if you use named groups)
const contents = sceneInput.contents.match(regex)[0];
return {
...sceneInput,
contents
};
});
}
module.exports = {
description: {
name: "Select Block by Header",
description: "Selects a block of text from a hardcoded regex",
availableKinds: ["Scene"],
options: []
},
compile: compile
};
Note a few things about the above example:
Hope this helps. If you get something flexible feel free to PR it!
Thanks for the tips! I managed to put together this:
module.exports = {
description: {
name: "Select Block by Header",
description: "Selects a matching heading 1 block per scene",
availableKinds: ["Scene"],
options: [
{
id: "heading",
name: "Heading to include",
description: "Uses this string to look for a matching level 1 heading block to include in compile",
type: "Text",
default: "draft",
},
],
},
compile (input, context) {
const heading = context.optionValues["heading"];
const re = new RegExp("(?<=^# "+heading+"\n)(.*?\n)*?(?=^# )\n*","gm")
input = input.map(i => {
i.contents = i.contents.match(re);
return i;
});
return input;
}
};
It will include, per scene only the h1 block that matches the given string, and only if using the "#" heading style. It seems to work well just before a "Prepend Title" step.
It would not at all surprise me if there is a much more elegant way to do this, and the AST approach you mentioned would be great in future, but I'm happy to work out how to do a PR with this if you think it's worth it. In any case, that's the proof of concept :)
first of all thanks for a great plugin!
I like to write my scenes in levels of detail depending what stage I'm at;
All my scenes are built from the same template, with a heading for each stage. I'd love to be able to select which stage to compile. How difficult would it be to have the option to include only a specified heading name per scene in the compile?
I managed to get an example user script working, but I'm totally new to .js at the moment as far as customising the script goes. Does this functionality make sense to include in the default suite of scripts? Is it easy to implement?