Comments (25)
Sure there are many ways you can do that, it just depends on how much you want to recreate what marked.parse does for you.
One way you can do it is to use Lexer.blockTokens to create block tokens then update links before creating inline tokens.
As you can see that isn't quite as simple as just appending reflinks to the markdown.
from marked.
That doesn't work because it is not supposed to work like that. The url is resolved when creating the link tokens. It would be redundant, and a waste of time, to resolve it again on parsing. I'm going to close this since there is a way to do this even if it isn't the way that you want.
from marked.
Defined where externally? Just on a different page?
from marked.
I tried to modify tokens.links
property returned by the lexer before rendering the page, but couldn't get it to work. Just trying to find any means to provide the links before rendering. Could be on a different page or given as a configuration option.
from marked.
You can add the reflinks to the markdown in a preprocess
hook.
Something like:
marked.use({
hooks: {
preprocess(markdown) {
return markdown + '\n\n[mylink]: https://example.com/mylink';
}
}
});
from marked.
The hook is not called with marked.parser(tokens)
where the tokens are generated with marked.lexer()
from marked.
No. It is called by marked.parse(). If you are using marked.lexer you can just append the reflinks to the markdown that you pass in
from marked.
Gotcha. So there is no way to parse Markdown into an abstract syntax tree, then modify the tree (links specifically), and finally render the tree to HTML. Like parsing & rendering usually works.
from marked.
Lexer.blockTokens
sounds good! How exactly I can use that for updating the links? Some sample code would be helpful. Doesn't have to work. I can work my way out from there. Thanks!
from marked.
You will have to essentially copy the code from Lexer.lex and add in whatever changes you want.
Lines 86 to 98 in 0d3e9e7
from marked.
Sorry. I have no idea how to use the blockTokens()
function. Is it available as an API method at all?
from marked.
You can access the Lexer API by creating a new Lexer
import { Lexer, marked } from 'marked';
const lexer = new Lexer();
const tokens = lexer.blockTokens(markdown);
// update tokens.links
...
from marked.
Thanks. But the issue is that updating tokens.links
has no effect. For example by setting:
tokens.links.foo = { href: 'bar.com }
And [test][foo]
is still rendered as [test][foo]
from marked.
Can you share your whole code? It should work since that is exactly what marked does.
from marked.
Here's the code:
import { marked } from 'marked'
const md = `
[This works][works]
[This doesn't][test]
[works]: works.com
`
const tokens = marked.lexer(md)
tokens.links.test = { href: 'doesnt.com'}
console.info(marked.parser(tokens))
And the output is
<p><a href="works.com">This works</a></p>
<p>[This doesn’t][test]</p>
from marked.
You aren't calling blockTokens at all?
Marked.lexer creates block tokens and inline tokens. You have to add the link before getting the inline tokens.
from marked.
I have no idea how to use the undocumented blockTokens method. I tried this now:
import { marked, Lexer } from 'marked'
const md = `
[This works][works]
[This doesn't][test]
[works]: works.com
`
const lexer = new Lexer()
const tokens = lexer.blockTokens(md)
tokens.links.test = { href: 'doesnt.com'}
But the last sentence threw an error:
TypeError: undefined is not an object (evaluating 'tokens.links.test = { href: "doesnt.com" }')
Can you share a code that correctly updates the links before rendering? Thanks.
from marked.
It seems like just appending reflinks to the markdown would be the best way to do it. If you get it working with blockTokens it could be hard to update it if we ever change the Lexer methods.
from marked.
it seems appending reflinks to the markdown is the only way to do this, because there is no way to modify the abstract syntax tree before rendering as I originally stated.
from marked.
Adding a hook between block tokens and inline tokens is something we were thinking about doing. If you wanted to create a PR for that it would be very helpful.
from marked.
This is one way you can currently do it with Lexer and Parser
import { Marked, Lexer, Parser } from 'marked';
const marked = new Marked();
marked.use(
// extensions
);
const markdown = `
[This works][works]
[This does too][test]
[works]: works.com
`;
const lexer = new Lexer(marked.defaults);
lexer.tokens.links.test = { href: 'doesToo.com' };
const tokens = lexer.lex(markdown);
const parser = new Parser(marked.defaults);
console.log(parser.parse(tokens));
But this also works and is a lot simpler:
console.log(marked.parse(markdown + '\n\n[test]: doesAlso.com'));
from marked.
Cool. I got that working.
I agree, the JavaScript API for providing links in the AST phase is quite messy and not too user-friendly. Thre is no clear parse & render phases in Marked, which is unfortunate. I would like to do something like this (pseudocode):
import { parse, render } from 'marked'
// build AST
const ast = marked.parse(markdown)
// modify it
ast.doSomething()
ast.doSomethingElse()
// render with rendering options
const html = render(ast, { renderers, hooks, ... })
from marked.
Actually the issue on the title still remains. There is no way to update the links after parsing the AST, but before rendering. ie. the following does not work
// parse tokens (AST)
const tokens = lexer.lex(markdown);
// update tokens
tokens.links.test = { href: 'doesToo.com' };
// this doesn't work
console.log(parser.parse(tokens));
from marked.
Also this does work
import { marked } from 'marked'
// build AST
const ast = marked.lex(markdown)
// modify it
doSomething(ast)
doSomethingElse(ast)
// render with rendering options
const html = marked.parser(ast)
we just don't provide the doSomething
and doSomethingElse
functions.
If you would want to create a package that provides convenient methods for stuff to do with the ast you can.
from marked.
I was about to make such convenient methods but then realized that it's impossible with the current design of Marked, which does not have a clear and modifiable syntax tree. The parsed tree is somehow "resolved" and cannot be altered.
from marked.
Related Issues (20)
- v11.0.0. yields "Uncaught Error: renderer 'options' does not exist" in code that worked in versions up to v10.0.0 HOT 3
- Task List, Unordered List and Blockquote Bugs, along with Suggestions for Improvement HOT 2
- Proposal: mark-down html element HOT 1
- Marked treats tabs and spaces differently in lists
- Error: renderer 'options' does not exist HOT 1
- MiniProgramError SyntaxError: Invalid regular expression: /[\p{L}\p{N}]/: Invalid property name in character class HOT 1
- Rendering not as expected when using custom elements HOT 1
- Invalid regular expression in lower chrome HOT 1
- Multiple list with sublist - <p> tag inserts seems not quite right HOT 1
- marked parse mathematical formula error HOT 14
- Images? ![]() HOT 3
- Escape sequences in links are not unescaped HOT 1
- Lexer handling newlines incorrectly in some cases HOT 1
- Incompatibility with esNext Syntax in marked.js Bundle HOT 6
- Register Walktokens Behavior for extensions with different token structure HOT 4
- Clarify ambiguity around "extensions" HOT 1
- Marked Extensions Versioning HOT 7
- Issues with Parsing Nested Emphasis and Handling Chinese Parentheses HOT 1
- Token with "strong" type was not found HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from marked.