straker/livingcss

Support for multiple @code, @example tags

Closed this issue · 7 comments

Hello again,

I'm interested in having multiple @code and @example blocks per section. Right now I'm trying to put both an HTML @code and a SCSS @code in one section. Support for multiple @example blocks would be useful to me as well.

It looks to me as if the comment parser has support for this.

Does this sound like a feature you'd be interested in having in this project? Happy to take a look and submit a PR, if so 😃

I don't see why not. Custom tags follow that approach already, so having it for @code and @example makes sense.

If you'd like to submit a PR for it, please feel free. Please make sure the default handlebars template is changed to understand it as well.

@straker While implementing this, I ran across some issues worth discussing...

The problem is that the current implementation expects at most 1 @example and @code comment per block. It also expects that if @code is not defined in a block, the @example should be used for the code (unless, of course, you provide the @hideCode comment).

Thus, if we want to interpret something like...

/**
 * @example
 * <div>first</div>
 *
 * @code
 * <div>override first</div>
 *
 * @example
 * <div>second</div>
 *
 * @example
 * <div>third</div>
 */

We need to make some new assumptions. My thought is:

  • In case there is one @example and one or zero @code, behave normally (i.e. the way it currently behaves)
  • Otherwise, treat @example and @code as pairs; so if an @example is followed by an @code, use that as the override; if it is not followed by an @code, the @example should be used for the code.
  • Any 'extra' @code comments get added, un-related to any @example.

As is, the template would display all the examples, followed by all the code.

This is an option if you want to maintain backwards compatibility.

If you don't want to maintain backwards compatibility, one way to simplify the code (but provide less flexiblity) would be just to mandate that all @example must be followed by @code. This would have the added benefit that in the template, we could interleave the examples and code.

Thoughts?

Those are some interesting points. This got hard fast.

I wonder if it would work to "name" your code and examples. Right now the template is @example|code {lang-type} <code>, the parser could handle the name portion of the comment and we could do @example|code {lang-type} name <code>. Then you could map examples to code by naming them the same, and they you can put them in any order in the comment.

/**
 * @example first
 * <div>first</div>
 *
 * @example
 * <div>second</div>
 *
 * @example
 * <div>third</div>
 *
 * @code first
 * <div>override first</div>
 */

Otherwise if there is no name, it could be first come first serve. That is, examples are put into an array, and code is put into a different array. As each example is parsed, it adds it's appropriate code block to the code array (so they remain 1:1 so long as there is no @code). Each @code will replace the last index in the code array (i.e. the last example's code). You couldn't do 2 @codes in a row, but I think that's a fair compromise if you don't name them.

/**
 * @example
 * <div>first</div>
 *
 * @code
 * <div>override first</div>
 *
 * @example
 * <div>second</div>
 *
 * @example
 * <div>third</div>
 *
 * @code
 * <div>override third</div>
 */

One further point of discussion: should the @hideCode work on the entire comment (so no code no mater how many examples you have), or should we change it so you can hide the code for specific examples within the comment?

Wait, scratch what I just said. Your use case needs 2 @codes next to one another. What you need is a 1:many relationship (one example, one HTML code, one SCSS code). Since the example can only be HTML to display it, maybe we only support 1 example (HTML), but multiple codes for that example. That would simplify things quite a bit and I think makes more sense then multiple examples (since the only reason to have multiple example blocks would be to change it's type, which can't work to display them).

@straker if @sidraval follows the markdown support (that we got in), he could just use the markdown files for that. It's a workaround, and you will get more blocks in the style files, but the blocks would at least be smaller and easier to maintain

This is somewhat tangential, but for my own project, there were a bunch of places where I wanted short bits of HTML and the resulting rendered output in a table. This allows me to show small modifications to elements based on class, but I still wanted things broken up. I added two tags, @exampleRow and @tableDescription. For each @exampleRow a new row is added to a table with the HTML for that @exampleRow being shown next to it. (My examples were always small when done like this, so no need for a @code to overwrite the HTML.) I added @tableDescription to allow for a text description that would appear above the table, but below any full @example blocks. You're still limited to only one @example block, but you can have as many @exampleRow blocks as you need. I put up a gist with how I did it at https://gist.github.com/MikeTheReader/e0d6c167ff534979ba20c1d3004e4295. Not sure if that's helpful or not, but thought I'd at least put it out there.

I'm going to close this issue as inactive. Feel free to still create a PR if you find the feature helpful.