invicticide / fractive

Fractive is a free, open-source, Markdown-based hypertext authoring tool for writing interactive fiction.
http://fractive.io
Other
37 stars 5 forks source link

Escape sequence to show {alias} in text is FUBAR #77

Closed NQNStudios closed 6 years ago

NQNStudios commented 6 years ago

What happened

While making an example for #75, I couldn't find any way to make the invocation of an alias, i.e. {alias}, appear in a section without being expanded. I tried to escape it as \{alias} following the pattern of other macros, and also \{alias\} and \\{alias}. Nothing worked.

Steps to reproduce

For convenience, you can just pull #75 and run the example. Near the end, you'll see the ugly results of this bug.

Expected behavior

Aliases should be escapable in the same syntax as other macros, \{alias}.

NQNStudios commented 6 years ago

I did some snooping around in the SkipEscapedSubstring function and couldn't find anything that looked wrong about it. It's really weird.

invicticide commented 6 years ago

Is the same \{alias} you're escaping also in use elsewhere in the same .md file in a non-escaped fashion, e.g. {alias}? Because when that's the case, I can repro this as such:

Display this as-is: \{myAlias}
But replace this one: {myAlias}

You'd expect the result to be:

Display this as-is: {myAlias}
But replace this one: foo

But what actually happens is:

Display this as-is: \foo
But replace this one: foo

The reason for that is near the end of Compiler.ReplaceAliases when we identify a non-escaped alias for replacement, we then proceed to replace all instances of that alias in the entire .md file, without checking each subsequent one for an escape. The solution to that is to replace only the alias instance we're looking at right now, instead of doing a global replace. That applies to both the regular and regex forms of replacement.

If I escape an alias that's not expanded elsewhere, it works fine, e.g.

Display this as-is: \{unusedAlias}
But replace this one: {myAlias}

...correctly displays as:

Display this as-is: {unusedAlias}
But replace this one: foo

Let me know if you're seeing a different repro for this, or a different issue altogether.

NQNStudios commented 6 years ago

Off the top of my head, that is probably the use-case, yeah. Because I was trying to make an example that would show macro syntax and subsequently show the macro output, if I remember correctly.