revolunet / sublimetext-markdown-preview

markdown preview and build plugin for sublime text 2/3
MIT License
2.31k stars 362 forks source link

Missing task lists from GitHub flavoured Markdown #207

Closed ghost closed 10 years ago

ghost commented 10 years ago

GitHub flavoured markdown was updated not too long ago to allow for lists of checkable items. The plugin currently renders them as a regular unordered list.

Example

Taken from github's markdown guide

- [x] @mentions, #refs, [links](), **formatting**, and <del>tags</del> supported
- [x] list syntax required (any unordered or ordered list supported)
- [x] this is a complete item
- [ ] this is an incomplete item

Result

facelessuser commented 10 years ago

You can use the new task list extension mentioned in the readme to get this functionality; I added it myself. You just have to do some setting up.

So here is a real example, Markdown Preview turned this:

- [x] @mentions, #refs, [links](), **formatting**, and ~~tags~~ supported
- [x] list syntax required (any unordered or ordered list supported)
- [x] this is a complete item
- [ ] this is an incomplete item :smile:

Into this: screenshot 2014-07-03 01 14 07

Git hub renders it like this

Not bad eh? So we have a number of extensions you can use. Above you see tasklist, githubemoji, and delete in action. My currently enabled extensions are below.

    "enabled_extensions": [
        "extra",
        "toc",
        "codehilite",
        "delete",
        "magiclink",
        "tasklist",
        "githubemoji",
        "b64",
        "nl2br"
    ],
ghost commented 10 years ago

Thanks for the quick response. Sorry, I should have read the README more carefully.

Unfortunately I'm still having issues. I opened up my user settings for Markdown Preview and entered the following:

{
  "enabled_extensions": [
    "extra",
    "toc",
    "codehilite",
    "delete",
    "magiclink",
    "tasklist",
    "githubemoji",
    "b64",
    "nl2br"
  ]
}

After restarting sublime I tried both of these commands:

The first command completes successfully, but the rendered page still renders the tasklist as a regular unordered list. I don't know if I'm misunderstanding how this command works or something.

The second command fails. Checking the console log I get:

Traceback (most recent call last):
  File ".\sublime_plugin.py", line 356, in run_
  File ".\MarkdownPreview.py", line 429, in run
  File ".\MarkdownPreview.py", line 384, in run
  File ".\MarkdownPreview.py", line 365, in convert_markdown
  File ".\markdown\__init__.py", line 426, in markdown
  File ".\markdown\__init__.py", line 146, in __init__
  File ".\markdown\__init__.py", line 171, in registerExtensions
  File ".\markdown\__init__.py", line 217, in build_extension
ImportError: Failed loading extension 'delete' from 'markdown.extensions.delete' or 'mdx_delete'

I realized that the necessary python files were not in Packages\Markdown Preview\markdown\extensions, so I tried copying them over from the zip download referenced in the README. The same error was produced even with delete.py and the other extensions added to the file.

My initial installation was via Package Control. My python version is 3.4.1.

revolunet commented 10 years ago

@facelessuser : you need to issue a new release here https://github.com/revolunet/sublimetext-markdown-preview/releases for it to appear on the package manager and it takes a few minutes to appear in ST.

Also we should try to prevent exceptions when loading extensions if possible

facelessuser commented 10 years ago

@facelessuser : you need to issue a new release here https://github.com/revolunet/sublimetext-markdown-preview/releases for it to appear on the package manager and it takes a few minutes to appear in ST.

Cool, then it is coming when we tag the new relasee :smile:.

Also we should try to prevent exceptions when loading extensions if possible

I agree that it should gracefully ignore missing extensions. It wasn't already gracefully catching these since all I did was push the abstraction up alevel, not alter it. But I agree, moving forward, catching these is better.

facelessuser commented 10 years ago

Once I finish the few tasks I have lined up, I will tag a release.

facelessuser commented 10 years ago

Actually, I'll leave tag creation up to @revolunet. I believe it is more appropriate.

revolunet commented 10 years ago

Ok as you like, but feel free to do it you're at home here :)

facelessuser commented 10 years ago

Cool. I just didn't want to take liberties that weren't given :smile:.

facelessuser commented 10 years ago

@curiousinternals I am getting close to making a branch with the mentioned changes, but I thought I would clarify some things:

So basically, if you are using GFM parser, make sure your mode is set to gfm and you are good to go as of today.

But if you were hoping for this functionality in the offline markdown parser, you need to wait a least a couple more days as I am wrapping up changes for the next big release.

ghost commented 10 years ago

@facelessuser Thanks for the clarification. It wasn't originally clear to me that the built in parser would not parse GFM. In the README's list of features I read the section on third-party extensions for the built-in parser and got the impression these were already in there.

I followed your advice and I've got things parsing now, thanks. I look forward to seeing that next update :smile:

facelessuser commented 10 years ago

New changes are in. Gitub emulation extensions (along with other extensions) are enabled by default. If you want to turn off language guessing like github does, see the readme for more info. Hopefully that clears this issue up for your.

ghost commented 10 years ago

@facelessuser Unfortunately more trouble. After a fresh install using package control the commands do not show up (e.g. Typing ctrl+shift+p "Markdown" only yeilds two results, both for setting the file's syntax). Trying to build with ctrl+b gives the console error:

Unable to find target command: markdown_build

Here's a dump of my console on starting up sublime if it's any help:

startup, version: 2221 windows x64 channel: stable
executable: /P/prog/Sublime Text 2/sublime_text.exe
working dir: /C/Windows/system32
packages path: /C/Users/MB/AppData/Roaming/Sublime Text 2/Packages
settings path: /C/Users/MB/AppData/Roaming/Sublime Text 2/Settings
PackageSetup not required
Py_GetProgramName(): sublime_text.exe
Py_GetExecPrefix(): P:\prog\Sublime Text 2
Py_GetProgramFullPath(): P:\prog\Sublime Text 2\sublime_text.exe
Py_GetPath(): P:\prog\Sublime Text 2\python26.zip;P:\prog\Sublime Text 2\DLLs;P:\prog\Sublime Text 2\lib;P:\prog\Sublime Text 2\lib\plat-win;P:\prog\Sublime Text 2\lib\lib-tk;P:\prog\Sublime Text 2
Py_GetPythonHome(): P:\prog\Sublime Text 2
catalogue loaded
found 4 files for base name Default.sublime-keymap
found 1 files for base name Default.sublime-mousemap
found 3 files for base name Main.sublime-menu
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\CSS\css_completions.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Default\comment.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Default\copy_path.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Default\delete_word.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Default\detect_indentation.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Default\duplicate_line.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Default\echo.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Default\exec.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Default\fold.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Default\font.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Default\goto_line.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Default\indentation.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Default\kill_ring.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Default\mark.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Default\new_templates.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Default\open_file_settings.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Default\open_in_browser.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Default\paragraph.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Default\save_on_focus_lost.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Default\scroll.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Default\set_unsaved_view_name.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Default\side_bar.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Default\sort.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Default\swap_line.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Default\switch_file.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Default\transform.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Default\transpose.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Default\trim_trailing_white_space.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Diff\diff.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\HTML\encode_html_entities.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\HTML\html_completions.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\MarkdownPreview.py
Reloading plugin extension C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\markdown\extensions.py
Reloading plugin extension C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\markdown\extensions\abbr.py
Reloading plugin extension C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\markdown\extensions\admonition.py
Reloading plugin extension C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\markdown\extensions\attr_list.py
Reloading plugin extension C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\markdown\extensions\b64.py
Reloading plugin extension C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\markdown\extensions\codehilite.py
Reloading plugin extension C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\markdown\extensions\def_list.py
Reloading plugin extension C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\markdown\extensions\delete.py
Reloading plugin extension C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\markdown\extensions\extra.py
Reloading plugin extension C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\markdown\extensions\fenced_code.py
Reloading plugin extension C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\markdown\extensions\footnotes.py
Reloading plugin extension C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\markdown\extensions\github.py
Reloading plugin extension C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\markdown\extensions\githubemoji.py
Reloading plugin extension C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\markdown\extensions\headeranchor.py
Traceback (most recent call last):
  File ".\sublime_plugin.py", line 62, in reload_plugin
  File ".\MarkdownPreview.py", line 38, in <module>
    from helper import INSTALLED_DIRECTORY
  File ".\helper.py", line 59, in <module>
    __import__(package)
  File ".\markdown\extensions\headeranchor.py", line 20, in <module>
    from .headerid import slugify, stashedHTML2text, itertext, unique
  File ".\markdown\extensions\headerid.py", line 84, in <module>
    import unicodedata
ImportError: No module named unicodedata
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\helper.py
Reloading plugin extension C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\markdown\extensions.py
Reloading plugin extension C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\markdown\extensions\abbr.py
Reloading plugin extension C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\markdown\extensions\admonition.py
Reloading plugin extension C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\markdown\extensions\attr_list.py
Reloading plugin extension C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\markdown\extensions\b64.py
Reloading plugin extension C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\markdown\extensions\codehilite.py
Reloading plugin extension C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\markdown\extensions\def_list.py
Reloading plugin extension C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\markdown\extensions\delete.py
Reloading plugin extension C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\markdown\extensions\extra.py
Reloading plugin extension C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\markdown\extensions\fenced_code.py
Reloading plugin extension C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\markdown\extensions\footnotes.py
Reloading plugin extension C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\markdown\extensions\github.py
Reloading plugin extension C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\markdown\extensions\githubemoji.py
Reloading plugin extension C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\markdown\extensions\headeranchor.py
Traceback (most recent call last):
  File ".\sublime_plugin.py", line 62, in reload_plugin
  File ".\helper.py", line 59, in <module>
    __import__(package)
  File ".\markdown\extensions\headeranchor.py", line 20, in <module>
    from .headerid import slugify, stashedHTML2text, itertext, unique
  File ".\markdown\extensions\headerid.py", line 84, in <module>
    import unicodedata
ImportError: No module named unicodedata
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Markdown Preview\markdown_wrapper.py
Reloading plugin C:\Users\MB\AppData\Roaming\Sublime Text 2\Packages\Package Control\Package Control.py
plugin init time: 0.564581
loading bindings
loading pointer bindings
found 1 files for base name Default.sublime-theme
theme loaded
app ready
pre session restore time: 0.731966
startup cache, total files: 98 cache hits: 98
startup time: 0.7941 (package setup was not run)
loaded 837 snippets
Package Control: Skipping automatic upgrade, last run at 2014-07-07 05:52:41, next run at 2014-07-07 06:52:41 or after
facelessuser commented 10 years ago

Man, I didn't enable everything on windows...

I probably need to patch with:

try:
    import unicodedata
except:
    from os.path import dirname
    sys.path.append(dirname(sys.executable))
    import unicodedata

in the sublime environment. Let me boot this up in windows.

facelessuser commented 10 years ago

Yep that was it. I patched it and now ST2 windows is looking good. I will tag it. Sorry, I put in a ton of work recently into this, but it looks like I got a little sloppy with testing. I tested nearly everything, but didn't test the headerid tag in windows ST2 :blush:.

facelessuser commented 10 years ago

It has been tagged. As soon as Package Control sees it, you should be good. Sorry I let that one slip.

ghost commented 10 years ago

Haha, don't worry about it. It happens to everyone at some point. I'll grab it when I next wake up and confirm there are no more code gremlins waiting for me. Thanks for the fast responses ^_^

facelessuser commented 10 years ago

FYI. I would recommend turning sane_lists extension off...that is if you are going for github emulation. They work together, but sane_lists will change the logic of when a list is recognized and not.

ghost commented 10 years ago

Okay, I gave it a try and it's working well. Thanks for all the help ^_^

The only thing I noticed was that running Markdown Preview: Preview in Browser and selecting the github option, with all the settings at their defaults, will not render github flavour syntax correctly. I think that behaviour might confuse some people.

Otherwise, using the markdown option or just building with ctrl+b does the job perfectly.

Issue solved. Thanks for all the help. ^_^

I'll turn sane_lists off when I get a chance.

facelessuser commented 10 years ago

That is the weird thing about the Github API. It doesn't appear to be as complete as the one that actually gets used on the github site. Markdown Preview has no control over the API.

Markdown Preview can run some post processing to fix some of that. For instance, anchor tags appear with github_mode="markdown" and not with github_mode="gfm", but they don't quite work right because the API doesn't add the ids to the headers. I am currently having to patch that with a post processor that should be available soonish. I am only adding it because they include the anchor with an actual reference. Ids aren't included in "gfm" either, but I have no reference there. I would have to reverse engineer the algorithm for id creation to ensure a reliable workaround.

Technically, I could patch the Github API output to get tasklists working as well. I will have to see how much motivation I have, I am kind of winding down with the things I am adding. I should have one more release fixing some things. I might get the tasklist patch in there. We shall see.

I will go ahead and close this.

ghost commented 10 years ago

@facelessuser Unfortunately I don't understand as well as I'd like. My knowledge is still pretty patchy, got a year left of a compsci degree and I haven't covered parsers in detail yet. At some point I'll probably have a read through the source. I could do to learn python better, and have a look at a parser while I'm at it. I'm sure I'll understand better afterwards.

Don't break your back on my account, I'm perfectly happy with how well it runs so far.

One final noob question: Do people generally like to manage their own issue tracker or would it be best if I just close my own issues the moment I consider the issue I raised fixed? It makes sense that I'd know whether the issue is fixed best, but I'd also like to avoid developing habits that might irritate others.

facelessuser commented 10 years ago

I generally close an issue I create when I feel it is resolved. But sometimes the owner closes before I ever do.

I have found that some issue creators don't actually close their issues; so, I usually take a more forward approach and close them when I feel I fixed the issue. If I am not certain, I may give the creator a chance to do it themselves, but if they don't comment or close it after too long, I just close it. I figure if it is really still an issue, they will re-open :).

ghost commented 10 years ago

Alright, thanks a lot for the info. ^_^