GithubHelp home page GithubHelp logo

remark@next (13) about remark-attr HOT 10 OPEN

wooorm avatar wooorm commented on May 29, 2024
remark@next (13)

from remark-attr.

Comments (10)

arobase-che avatar arobase-che commented on May 29, 2024 9

from remark-attr.

david-sharer avatar david-sharer commented on May 29, 2024 1

It looks like this may be a suitable replacement, as well https://github.com/remarkjs/remark-directive

from remark-attr.

wooorm avatar wooorm commented on May 29, 2024 1

I wonder if it's used anywhere. But in principle, it's nice, maybe a little complex but still nice.

It’s getting some traction: a growing number of questions about it and users of it!

from remark-attr.

cah4a avatar cah4a commented on May 29, 2024 1

Made a simple plugin from scratch that works well with remark@next:
https://gist.github.com/cah4a/9b75c531540e2891599453863dd24881

Don't know how well it is aligned with the plugins ecosystem. Patching hProperties seems not a very delicate solution, but it works.

If somebody has the power to make a package out of it, feel free to grab the source.

from remark-attr.

swamidass avatar swamidass commented on May 29, 2024 1

Don't know how well it is aligned with the plugins ecosystem. Patching hProperties seems not a very delicate solution, but it works.

If somebody has the power to make a package out of it, feel free to grab the source.

Is this code still working? Has anyone made a package out of it yet? That would be much appreciated!

from remark-attr.

arobase-che avatar arobase-che commented on May 29, 2024

Ok, so I took the night to study the problem.

If I understand well, this plugin is obsolete. The parsing is now done in micromark and than I can't rewrite the tokenizers of remark-parse.

I wonder what to do. How should I support such a syntax ? Basically everything is outdated and I must rewrite a plugin from scratch and first study micromark. It's a lot of hard work.

A hint on how to do it well will be very welcome. I guess that you don't remember what that plugin does and how it works. Here a little summary :

This plugin extends the tokenizers of remark-parse to support syntax like that : *Hello !*{ style="red"}. A new tokenizer is created, it call the old tokenizer and them parse the { style="red"} syntax; and modify the result of the old tokenizer consequently (adding attributes).

So now, they is no more tokernizer to extend. Should I extend the state machine of micromark (SyntaxExtension ?) or do it in the unified/remark ecosystem (maybe hard or near to impossible due to edge-cases as *Hello !*{ comment="I _like_ the work on remark"} where the AST will be complex ) ?

Ok, thinking about it made me realize that I only one main question. I think, i have no chose but to extend micromark. Do you think it's possible ? Is there any doc available about it or I will have to study the source code ?

Thank for improving the remark ecosystem and in advance to any help provided.

from remark-attr.

wooorm avatar wooorm commented on May 29, 2024

For generic directives, I wrote an attribute parser, that support #id.class boolean key=value or="quoted" attributes: https://github.com/micromark/micromark-extension-directive/blob/main/lib/factory-attributes.js. That’s a lot of what you’d need to write.

Architecturally, there is a) a tokenizing part, where you parse {attributes} in micromark, and b) a tree building part, where you turn those tokens into mdast—for directives, that’s mdast-util-directive/from-markdown.js. Last, the remark part bundles it all so that users don’t need to know about everything.

I like building things in separate projects. But you don’t have to: it can all live in this project. The reasons why I split things up, are a) just nice coding for me, b) not everyone needs a syntax tree, so I also have micromark html extensions, c) in the future there will be a CST, not sure how or when that would be, but mdast wouldn’t be the only tree format.

For the tokenizing part, I think you’d be looking for {, then try and parse attributes, then find a }, and you‘re done! With one exception, which I’ll describe later. The second thing is in the adapter, where you‘re taking tokens and building trees, to take your attribute tokens and add them to the preceding link or heading. mdast-util-directive has attributes which aren’t hast, but the remark-directive readme shows an example of making hProperties out of ’em.

The complex part for attrs is that they’re added to other constructs. You can access the events on micromark, so that you can check to parse attributes or not based on whether there’s a link or image right before it. Links and images are made up of a start (![, [), and an end (](asd), ][asd], ][], or ]), which is done here: https://github.com/micromark/micromark/blob/ed4d78e4e2a799858d2c2c4f87b09163f1eae9da/lib/tokenize/label-end.js#L164. Those and autolinks, code spans, footnote calls, inline footnotes, are pretty easy. But emphasis, strong, and strikethrough are harder because those sequences can open and close, which is figured out at the end.

For the flow part (blocks), I see that you have two different ways: setext headings attributes on their own line, ATX headings inline. I would suggest doing only the setext heading way: a “block” attribute starts at a line, cannot include line endings, and ends at a line ending.
Then, it’s attached to the preceding block, whether it’s a paragraph, a heading (ATX or setext), thematic breaks, code (fenced or indented). Containers (lists and block quotes) would be more complex, but as you’re not handling them yet, we can skip that for now.


Alright, already a wall of text, so I’ll quit now. That should give you some ideas on how to go about it.
An alternative is: The downside of attributes is that they don’t work in other markdown parsers. More markdown parsers are moving to generic directives. You could push folks to instead switch to a directive based approach? Such as the example in the remark-directive readme.

from remark-attr.

janosh avatar janosh commented on May 29, 2024

What's the current status? Is there a new remark plugin on the horizon that will provide the functionality of this one with the new micromark parser?

from remark-attr.

david-sharer avatar david-sharer commented on May 29, 2024

For anyone else who runs into this, I got this working with a custom component for my scenario (I needed call-to-action button-links). All buttons that have <strong> as the first-child [**text here**](... "custom:attribute title text") are rendered as buttons and their title text is parsed for custom attribute strings. Highly limited, but worked for me!
image

This pipeline relies on react-markdown.

// typescript component rendering
import React, { ReactElement } from "react";
import ReactMarkdown from "react-markdown";
import { Components, ReactBaseProps, ReactMarkdownProps } from "react-markdown/src/ast-to-react";
import remarkGfm from "remark-gfm";
import { first, fromPairs } from "lodash";
import { Button } from "@material-ui/core";

const components: Components = {
  a: ({
    node,
    children,
    href,
    title,
    ...props
  }: ReactBaseProps & ReactMarkdownProps & { href: string; title: string }) => {
    // if the first child of the button is a bold element, make this a CTA button
    if ((first(children) as ReactElement)?.type === "strong") {
      const splitTitle = title.split(' ');
      const titleAttrEntries = splitTitle.filter(t => t.includes(':'));
      const remainingTitleEntries = splitTitle.filter(t => !t.includes(':'));
      const finalTitle = remainingTitleEntries.join(' ');
      const titleAttrPairs = titleAttrEntries.map(te => te.split(':'))
      const titleAttrs = fromPairs(titleAttrPairs);
      return (
        <Button variant="contained" href={href} title={finalTitle} {...props} {...titleAttrs}>
          {children}
        </Button>
      );
    }

    return <a href={href} title={title} children={children} {...props}></a>;
  },
};

export function renderMarkdown(markdown: string) {
  return (
    <ReactMarkdown
      plugins={[remarkGfm]}
      children={markdown}
      components={components}/>
  );
}
<!-- markdown -->
[Regular Link](/where_to_go/)

[**CTA Button Link**](/where_to_go/ "color:primary any:attribute things without colons will be treated as the title")

output
image

from remark-attr.

arobase-che avatar arobase-che commented on May 29, 2024

Directive should have been the way to go since the CommonMark compatibility, but directive never really make it way to the CommonMark standard.

I wonder if it's used anywhere. But in principle, it's nice, maybe a little complex but still nice.

It's also difficult to implement to remark but that not a real argument because attributes-style (like remark-attr) become slightly more complicated to implement with µmark.

PS: If you plan to use remark-directive take a look at https://github.com/micromark/micromark-extension-directive.

from remark-attr.

Related Issues (18)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.