erusev / parsedown-extra

Markdown Extra Extension for Parsedown
MIT License
819 stars 123 forks source link

Todo/Checkbox list #136

Open chapterjason opened 5 years ago

chapterjason commented 5 years ago

Hey, I miss the checkbox/todo feature. I already searched and found the issue #113 but it was closed and it looks like its not followed anymore.

I really like and use these feature, would be awesome to have that in here. Not sure if the extra package would be a place or the main, cause it is also in the GitHub Flavored - Section 5.3.

Something like this

- [x] Do work
- [] Do some work
- [ ] Do some extra work

will result in image

Currently I use this workaround:

class AppParsedown extends ParsedownExtra
{
    protected function blockListComplete(array $Block)
    {
        $list = parent::blockListComplete($Block);

        if (!isset($list)) {
            return null;
        }

        foreach ($list['element']['elements'] as $key => $listItem) {
            $args = $listItem['handler']['argument'];
            if (isset($args[0])) {
                $firstThree = substr($args[0], 0, 3);
                $rest = trim(substr($args[0], 3));
                if ($firstThree === '[x]' || $firstThree === '[ ]') {
                    $checked = $firstThree === '[x]' ? ' checked' : '';
                    $items = $this->lineElements('<input type="checkbox" disabled' . $checked . '/> ' . $rest);
                    $list['element']['elements'][$key]['attributes']['class'] = 'task-list-item';
                    $list['element']['elements'][$key]['elements'] = $items;
                    unset($list['element']['elements'][$key]['handler']);
                }
            }
        }

        return $list;
    }

}

.task-list-item {
    margin-left: -20px;
    list-style-type: none;
}
Clicketyclick commented 4 years ago

Could you please provide an example? Where do you add this code?

chapterjason commented 4 years ago

@Clicketyclick I use the class directly to parse the markdown.

LexShadow commented 3 years ago

This a year later is still missing, I not sure if Extra is really been worked on that much.

My Fix: Create a new file called ParsedownExtraFix.php include it after ParsedownExtra 'include(/'YOURFILEPATH/ParsedownExtraFix.php');'

/*
            ParsedownExtraFix
               LexShadow
*/

class ParsedownExtraFix extends ParsedownExtra{
    const version = '0.0.0.1';

    function __construct(){
        if (version_compare(parent::version, '0.8.1') < 0){
            throw new Exception('ParsedownExtraFix(0.0.0.1) requires 0.8.1 of ParsedownExtra to work.');
        }
    }
    protected function blockListComplete(array $Block){
        $list = parent::blockListComplete($Block);
        if (!isset($list)) {
            return null;
        }
        foreach ($list['element'] as $key => $listItem) {
            if(is_array($listItem)){
                foreach($listItem as $inList => $items){
                    $CheckFind = substr($items['text'][0], 0, 3);
                    $SourceContent = trim(substr($items['text'][0], 3));
                    if ($CheckFind === '[x]' || $CheckFind === '[ ]') {
                        $isChecked = $CheckFind === '[x]' ? ' checked' : '';
                        $list['element'][$key][$inList]['attributes']['class'] = 'task-list-item';
                        $list['element'][$key][$inList]['text'][0] = '<input type="checkbox" disabled' . $isChecked . '/> ' . $SourceContent;
                    }
                }
            }
        }
        return $list;
    }
}
LexShadow commented 3 years ago

I have changed this above in my own version this works but I replaced this with Fontawesome for better theming if you have FA installed you can try my version if you like

/*
            ParsedownExtraFix
                 LexShadow
            For this version to work you need
       to make sure Font Awesom 5.15.1 CSS 
       is included in your main site, this was 
        tested with the CSS version not the 
                           JS versions.

*/

class ParsedownExtraFix extends ParsedownExtra {
    const version = '0.0.0.2';

    function __construct(){
        if (version_compare(parent::version, '0.8.1') < 0){
            throw new Exception('ParsedownExtra requires a later version of Parsedown');
        }
    }
    protected function blockListComplete(array $Block){
        $list = parent::blockListComplete($Block);
        if (!isset($list)) {
            return null;
        }
        foreach ($list['element'] as $key => $listItem) {
            if(is_array($listItem)){
                foreach($listItem as $inList => $items){
                    $firstThree = substr($items['text'][0], 0, 3);
                    $rest = trim(substr($items['text'][0], 3));
                    if ($firstThree === '[x]' || $firstThree === '[ ]') {
                        $hex = substr($items['text'][0], strpos($items['text'][0], '{hex}')+5);
                        $hex = substr($hex, 0, strpos($hex, '{/hex}'));
                        if($hex != ""){
                                $rest = str_replace("{hex}" . $hex . "{/hex}", "", $rest);
                                $hex = ' style="color:' . $hex .';" ';
                        }
                        $checked = $firstThree === '[x]' ? ' <i class="fas fa-check-square"' . $hex . '></i> ' : '<i class="far fa-square"' . $hex . '></i> ';
                        $list['element'][$key][$inList]['attributes']['class'] = 'task-list-item';
                        $list['element'][$key][$inList]['text'][0] = $checked . $rest;
                    }
                }
            }
        }
        return $list;
    }
}
WebDesignWorx commented 1 year ago

This is great, thanks. Works even with Parsdown itself (not the ParsdownExtra.php) I had to tweak the code a little bit though.

protected function blockListComplete(array $Block) {
        $list = parent::blockListComplete($Block);
        if (!isset($list)) {
            return null;
        }
        if(is_array($list['element'])){
            foreach ($list['element'] as $key => $listItem) {
                if (is_array($listItem)) {
                    foreach ($listItem as $inList => $items) {
                        if(isset($items['text']) && is_array($items['text'])){
                            $CheckFind = substr($items['text'][0], 0, 3);
                            $SourceContent = trim(substr($items['text'][0], 3));
                            if ($CheckFind === '[x]' || $CheckFind === '[ ]') {
                                $isChecked = $CheckFind === '[x]' ? ' checked' : '';
                                $list['element'][$key][$inList]['attributes']['class'] = 'task-list-item';
                                $list['element'][$key][$inList]['text'][0] = '<input type="checkbox" disabled' . $isChecked . '/> ' . $SourceContent;
                            }
                        }
                    }
                }
            }
        }
        return $list;
    }

I am going to implement the work in our CMS. Anything special you want me to write to credit your contribution? Thanks.