Skip to content

Asciidoctor: BWC for // CONSOLE then callouts #721

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Mar 26, 2019

Conversation

nik9000
Copy link
Member

@nik9000 nik9000 commented Mar 15, 2019

Our backwards compatibility support for "OPEN IN CONSOLE"-style links did
not work with snippets followed by a callout list. That looks like this:

[source,js]
----
GET / <1>
----
// CONSOLE
<1> words go here

These is actually super common and I'm surprised I didn't catch it
before! This adds tests for it so it won't sneak through again.

The reason this didn't work is that our backwards compatibility worked by
transforming the // CONSOLE comment in pass:[// CONSOLE] and then
catching that when walking the tree. We do this in two passes because our
preprocessor works line by line and reading ahead can cause issues. So we
do the "action at a distance" in a tree processor where it is quite
simple.

The trouble is that the pass:[// CONSOLE] construct is inline so when
it is immediately followed by the <1> words go here line it gets sucked
into the same block which Asciidoctor thinks of as a paragraph. This
causes the parsing for the callout list not to happen, causing all kinds
of trouble.

The fix for this is to introduce a block macro that functions like
pass:[// CONSOLE] and to use that instead. This causes the callout list
to be parsed properly.

Our backwards compatibility support for "OPEN IN CONSOLE"-style links did
not work with snippets followed by a callout list. That looks like this:

```
[source,js]
----
GET / <1>
----
// CONSOLE
<1> words go here
```

These is actually *super* common and I'm surprised I didn't catch it
before! This adds tests for it so it won't sneak through again.

The reason this didn't work is that our backwards compatibility worked by
transforming the `// CONSOLE` comment in `pass:[// CONSOLE]` and then
catching that when walking the tree. We do this in two passes because our
preprocessor works line by line and reading ahead can cause issues. So we
do the "action at a distance" in a tree processor where it is quite
simple.

The trouble is that the `pass:[// CONSOLE]` construct is *inline* so when
it is immediately followed by the `<1> words go here` line it gets sucked
into the same block which Asciidoctor thinks of as a paragraph. This
causes the parsing for the callout list not to happen, causing all kinds
of trouble.

The fix for this is to introduce a block macro that functions like
`pass:[// CONSOLE]` and to use that instead. This causes the callout list
to be parsed properly.
@nik9000 nik9000 requested a review from estolfo March 15, 2019 14:26
Copy link
Contributor

@estolfo estolfo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, looks good. I personally like to put newlines in between rspec blocks so I can visualize the contexts. But that's up to you!


lang = LANG_MAPPING[$1]
snippet = $2
m = %r{^//\s*([^:\]]+)(?::\s*([^\]]+))?$}.match(next_block.source)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a longer variable name would make this clearer.


##
# Block macro that exists entirely to mark language overrides in a clean way
# without additing additional lines to the input file which would throw off
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

without adding additional

----
ASCIIDOC
snippet += "lang_override::[#{override}]" if override
snippet
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you seen the #tap method in Ruby? It's a style thing, but you could use it here. I like using it so I never accidentally forget to return the object (in this case, snippet) from the let block.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#tap seems pretty complex to use here because the string is frozen. Though I bet there are other places i can use it....

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, then it wouldn't work if the String is frozen..

#{snippet}
ASCIIDOC
end
include_examples 'has the expected language'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very nuanced, but you could also use it_behaves_like here. include_examples is best suited for what you're doing from the topic level - creating specs using different values but when you have a nested context and want to emphasize a behavior, people tend to use it_behaves_like. They're effectively interchangeable and I think the difference really comes down to how you want the specs to print out. Sometimes it's also awkward to find a phrase that describes the behavior. For example, in this case, it might be strange to say it_behaves_like 'a string converter' - or whatever. So anyway, maybe include_examples is best here and you can ignore this whole comment = )

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this! I looked at it_behaves_like for a bunch of things. I'll play with it some more and see what I can find. I found that it doesn't work well when you want to apply the same set of shared examples multiple times with different parameters. Or, rather, it doesn't seem to properly list the parameters when you run rspec. I'll try it some more though.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see what you're saying. Ultimately, they can accomplish very similar things in the specs, so it's up to you and how you want the the specs to run and print out.

@@ -113,7 +113,7 @@ class ElasticCompatPreprocessor < Asciidoctor::Extensions::Preprocessor
INCLUDE_TAGGED_DIRECTIVE_RX = /^include-tagged::([^\[][^\[]*)\[(#{Asciidoctor::CC_ANY}+)?\]$/
SOURCE_WITH_SUBS_RX = /^\["source", ?"[^"]+", ?subs="(#{Asciidoctor::CC_ANY}+)"\]$/
CODE_BLOCK_RX = /^-----*$/
SNIPPET_RX = %r{//\s*(?:AUTOSENSE|KIBANA|CONSOLE|SENSE:[^\n<]+)}
SNIPPET_RX = %r{^//\s*(AUTOSENSE|KIBANA|CONSOLE|SENSE:[^\n<]+)$} # NOCOMMIT handle trailing spaces
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll get this before merging!

#{snippet}
ASCIIDOC
end
include_examples 'has the expected language'
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this! I looked at it_behaves_like for a bunch of things. I'll play with it some more and see what I can find. I found that it doesn't work well when you want to apply the same set of shared examples multiple times with different parameters. Or, rather, it doesn't seem to properly list the parameters when you run rspec. I'll try it some more though.

@nik9000 nik9000 marked this pull request as ready for review March 15, 2019 20:04
@nik9000
Copy link
Member Author

nik9000 commented Mar 15, 2019

OK! I've pushed some more tests for the regex on the way in. I think this is ready for review again!

Copy link
Contributor

@estolfo estolfo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

----
ASCIIDOC
snippet += "lang_override::[#{override}]" if override
snippet
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, then it wouldn't work if the String is frozen..

#{snippet}
ASCIIDOC
end
include_examples 'has the expected language'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see what you're saying. Ultimately, they can accomplish very similar things in the specs, so it's up to you and how you want the the specs to run and print out.

@nik9000
Copy link
Member Author

nik9000 commented Mar 26, 2019

Thanks for reviewing @lcawl!

@nik9000 nik9000 merged commit 29e8fcd into elastic:master Mar 26, 2019
@nik9000
Copy link
Member Author

nik9000 commented Mar 26, 2019

Thanks for reviewing @lcawl!

Wow, that is embarrassing. "I meant thanks for reviewing @estolfo!" I mean, both of you review my code but for different reasons and I was just sending something to @lcawl.... But I'm not sure about why I mixed you two up there. Sorry!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants