diff --git a/blog/annoucement-showdown-2.0.md b/blog/annoucement-showdown-2.0.md index 1ace834..8f062d7 100644 --- a/blog/annoucement-showdown-2.0.md +++ b/blog/annoucement-showdown-2.0.md @@ -60,6 +60,5 @@ development efforts will be put into it. This means **Showdown 1.x will now enter maintenance mode, that is, no new features will be added** and only important bugfixes will be committed. -We expect to release a stable version of Showdown 2.0 somewhere around June 2018, -but an alpha-version might be released a lot sooner. ***So, if you are as excited as -we are, stay tuned for more information***. +We expect to release an alpha version of Showdown 2.0 somewhere around ~~August 2018,~~ +the fall of 2018. ***So, if you are as excited as we are, stay tuned for more information***. diff --git a/blog/img/2018.09.25.jpg b/blog/img/2018.09.25.jpg new file mode 100644 index 0000000..0d93a82 Binary files /dev/null and b/blog/img/2018.09.25.jpg differ diff --git a/blog/img/2018.10.16.jpg b/blog/img/2018.10.16.jpg new file mode 100644 index 0000000..ed21bd7 Binary files /dev/null and b/blog/img/2018.10.16.jpg differ diff --git a/blog/posts.json b/blog/posts.json index fa58f76..1c7c21b 100644 --- a/blog/posts.json +++ b/blog/posts.json @@ -12,5 +12,33 @@ "image": "blog/img/2017.12.12.jpg", "summary": "Showdown version 1.0.0 was released almost 3 years ago, back in May 2015. Since then, it has seen a lot of improvements, with a boost to performance and a significant number of features now included in the core of the library. However, do to backwards compatibility constrains, we are still supporting a lot of legacy features, that prevent us from moving the software forward.\n\nWith that in mind, **it is time to start thinking about Showdown version 2.0.** For the next major release of Showdown we have planned a range of **significant changes and additions**." } + }, + { + "id": 2, + "canonical": "rewriting-the-parser-challenges-and-opportunities", + "url": "blog/rewriting-the-parser-challenges-and-opportunities.md", + "metadata": { + "title": "Rewriting the parser: Challenges and opportunities", + "author": "Estevão Soares dos Santos", + "author_avatar": "img/avatars/tivie.jpg", + "date": "2018-09-25", + "language": "en", + "image": "blog/img/2018.09.25.jpg", + "summary": "There comes a time when tough (and exciting) choices need to be made. With a version 2.0 in the oven (and the exciting reverse parser already completed), it seemed an excellent opportunity for doing something that I wished for a long time: rewriting showdown's parser from scratch. But maybe that challenge was a lot more tough than I first anticipated!" + } + }, + { + "id": 3, + "canonical": "showdown-1.8.7-released", + "url": "blog/showdown-1.8.7-released.md", + "metadata": { + "title": "Showdown 1.8.7 released", + "author": "Estevão Soares dos Santos", + "author_avatar": "img/avatars/tivie.jpg", + "date": "2018-10-16", + "language": "en", + "image": "blog/img/2018.10.06.jpg", + "summary": "While everyone's waiting for the new Showdown 2.0, we released version 1.8.7 with some improvements and several bugfixes" + } } ] diff --git a/blog/rewriting-the-parser-challenges-and-opportunities.md b/blog/rewriting-the-parser-challenges-and-opportunities.md new file mode 100644 index 0000000..9d6314a --- /dev/null +++ b/blog/rewriting-the-parser-challenges-and-opportunities.md @@ -0,0 +1,103 @@ +««« +title: Rewriting the parser: Challenges and opportunities, +author: Estevão Soares dos Santos, +author_avatar: img/avatars/tivie.jpg, +date: 2018-09-25, +language: en, +image: img/blog/2018.09.25.jpg, +summary: There comes a time when tough (and exciting) choices need to be made. With a version 2.0 in the oven + (and the exciting reverse parser already completed), it seemed an excellent opportunity for doing something + that I wished for a long time: rewriting showdown's parser from scratch. But maybe that challenge was a lot + more tough than I first anticipated! +»»» + +There comes a time when tough (and exciting) choices need to be made. With a version 2.0 in the oven +(and the exciting reverse parser already completed), it seemed an excellent opportunity for doing something that +I wished for a long time: rewriting showdown's parser from scratch. + +But maybe that challenge was a lot more tough than I first anticipated! + +## The old parser + +The old parser was based on replacing markdown text with HTML, through a series of Regular Expression in loco replaces. +While this was true to showdown's origins in Markdown.pl from John Gruber, during the last 3 years it became clear that +Regex (at least alone) was not suitable for the job. + +Don't get me wrong, Regex is a great tool: *not only it works for 99% of use cases* but also makes it extremely easy, +to develop extensions that complement showdown's features, even for beginner programmers. + +The problem, however, are those pesky edge cases... that 1% of of weird scenarios that made the Regular Expressions +increasingly complex over the time and forced me to make more and more exceptions to the rule. + +In fact, when you compare v 1.0 to v. 1.8.6, it's plain to see that almost all bug fixes (with notable exceptions) +were, in fact, edge case fixes. + +## Regex Madness + +Some regexes grew so weirdly that I need to split them in chunks and do some convoluted stuff to keep sanity. + +```javascript + if (options.literalMidWordUnderscores) { + text = text.replace(/\b___(\S[\s\S]*)___\b/g, function (wm, txt) { + return parseInside (txt, '', ''); + }); + text = text.replace(/\b__(\S[\s\S]*)__\b/g, function (wm, txt) { + return parseInside (txt, '', ''); + }); + text = text.replace(/\b_(\S[\s\S]*?)_\b/g, function (wm, txt) { + return parseInside (txt, '', ''); + }); + } else { + text = text.replace(/___(\S[\s\S]*?)___/g, function (wm, m) { + return (/\S$/.test(m)) ? parseInside (m, '', '') : wm; + }); + text = text.replace(/__(\S[\s\S]*?)__/g, function (wm, m) { + return (/\S$/.test(m)) ? parseInside (m, '', '') : wm; + }); + text = text.replace(/_([^\s_][\s\S]*?)_/g, function (wm, m) { + // !/^_[^_]/.test(m) - test if it doesn't start with __ (since it seems redundant, we removed it) + return (/\S$/.test(m)) ? parseInside (m, '', '') : wm; + }); + } +``` + +Others, which were inherited from when I took over the project, were just plainly poorly coded and +[hid some nasty bugs within](https://codereview.stackexchange.com/questions/150277/regex-to-parse-horizontal-rules-in-markdown). + +Javascript's regex limitations (such as no support for Lookbehind or atomic and possessive grouping) meant that I needed to rely +on the language's quirks and look for hacks to overcome those limitations. +At some point I even had to adapt a [recursive RegExp extension](https://github.com/showdownjs/showdown/blob/version_1.x/src/helpers.js#L210) +so HTML parsing was not as painful and slow as it was. + + +## Enter the new parser + +For all those reasons, and some more, I felt that version 2.0 should have a shinny and **proper new parser** that relied +on sequentiality and code logic rather than in place substitutions. But to move successfully away from RexExp, 3 things were needed: + +1. Keep the extension logic simple (while making it more powerful) +2. Time +3. Accurately estimate number 2 (time needed vs free time) + + +While I feel that the first one is being accomplished quite nicely (if I may say so myself), I might have over estimated +my free time and I definitely failed at number 3. Which meant I had to keep pushing the alpha release since August. + +Between work and family, the little free time I get, I dedicate it to this library. I do feel that things +are still going on the right track, albeit a lot more slowly than expected (and than I wished for). + +Regardless, **I'm really excited about the new features for version 2.0, specially the reverse converter and how it will tie in +toegether with the new parser and event system** + + +## I would really, really, really appreciate if you could donate, you know? + +As you know, ShowdownJS is a free library and it will remain free forever. +However, maintaining and improving the library costs time and money. + +So... if you like my work and find our library useful, +please donate ~~[through Patreon (coming soon)](https://www.patreon.com/showdownjs) or~~ +directly [through paypal](https://www.paypal.me/tiviesantos)!! + +Your contribution will mean a lot to me and really help me dedicate less time to my dayjob (and those annoying extra hours) +and more time developing this (awesome) library. Thank you!!! diff --git a/blog/showdown-1.8.7-released.md b/blog/showdown-1.8.7-released.md new file mode 100644 index 0000000..b14cc1c --- /dev/null +++ b/blog/showdown-1.8.7-released.md @@ -0,0 +1,45 @@ +««« +title: Showdown 1.8.7 released, +author: Estevão Soares dos Santos, +author_avatar: img/avatars/tivie.jpg, +date: 2018-10-16, +language: en, +image: img/blog/2018.10.06.jpg, +summary: While everyone's waiting for the new Showdown 2.0, I released version 1.8.7 with some improvements and several bugfixes. +»»» + +Showdown's version 2.0 is coming together although not as fast as I wanted, maybe +[due to the extensive refactor done to the parser][rewriting-the-parser]. But while the community is patiently waiting, +I felt that some important bugfixes could (and should) be backported to v 1.x. + + +## What's new in 1.8.7? + +Some long awaited bugfixes were backported, namely: + + +* **emojis:** fix emoji excessive size + +* **gfm-codeblocks:** + + * add support for spaces before language declaration + + * leading space no longer breaks gfm codeblocks + +* **images:** fix js error when using image references + +* **literalMidWordAsterisks:** now parses single characters enclosed by * correctly + +* **mentions:** allow for usernames with dot, underscore and dash + +* **nbsp:** fix replacing of nbsp with regular spaces + + + +You can download/use the new version from [github], [npm] and [CDNJS]. + + +[rewriting-the-parser]: http://shwodownjs.com/#!/blog/rewriting-the-parser-challenge-or-opportunity +[npm]: https://www.npmjs.com/package/showdown +[github]: https://github.com/showdownjs/showdown +[CDNJS]: https://cdnjs.com/libraries/showdown diff --git a/sitemap.xml b/sitemap.xml index 5417af6..9363a64 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -25,4 +25,12 @@ http://showdownjs.com/#!/blog/annoucement-showdown-2.0 2017-12-14T12:46:23+00:00 - \ No newline at end of file + + http://showdownjs.com/#!/blog/rewriting-the-parser-challenges-and-apportunities + 2018-09-25T00:00:00+00:00 + + + http://showdownjs.com/#!/blog/showdown-1.8.7-released + 2018-10-17T00:18:00+00:00 + +