@@ -51,7 +51,9 @@ use crate::core::theme;
5151use crate :: core:: {
5252 self , Color , Element , Length , Padding , Pixels , Theme , color,
5353} ;
54- use crate :: { column, container, rich_text, row, rule, scrollable, span, text} ;
54+ use crate :: {
55+ checkbox, column, container, rich_text, row, rule, scrollable, span, text,
56+ } ;
5557
5658use std:: borrow:: BorrowMut ;
5759use std:: cell:: { Cell , RefCell } ;
@@ -204,7 +206,7 @@ pub enum Item {
204206 /// The first number of the list, if it is ordered.
205207 start : Option < u64 > ,
206208 /// The items of the list.
207- items : Vec < Vec < Item > > ,
209+ items : Vec < ListItem > ,
208210 } ,
209211 /// An image.
210212 Image {
@@ -346,6 +348,19 @@ impl Span {
346348 }
347349}
348350
351+ /// The item of a list.
352+ #[ derive( Debug , Clone ) ]
353+ pub struct ListItem {
354+ checked : Option < bool > ,
355+ items : Vec < Item > ,
356+ }
357+
358+ impl ListItem {
359+ fn push ( & mut self , item : Item ) {
360+ self . items . push ( item) ;
361+ }
362+ }
363+
349364/// Parse the given Markdown content.
350365///
351366/// # Example
@@ -499,7 +514,7 @@ fn parse_with<'a>(
499514
500515 struct List {
501516 start : Option < u64 > ,
502- items : Vec < Vec < Item > > ,
517+ items : Vec < ListItem > ,
503518 }
504519
505520 let broken_links = Rc :: new ( RefCell :: new ( HashSet :: new ( ) ) ) ;
@@ -525,7 +540,8 @@ fn parse_with<'a>(
525540 pulldown_cmark:: Options :: ENABLE_YAML_STYLE_METADATA_BLOCKS
526541 | pulldown_cmark:: Options :: ENABLE_PLUSES_DELIMITED_METADATA_BLOCKS
527542 | pulldown_cmark:: Options :: ENABLE_TABLES
528- | pulldown_cmark:: Options :: ENABLE_STRIKETHROUGH ,
543+ | pulldown_cmark:: Options :: ENABLE_STRIKETHROUGH
544+ | pulldown_cmark:: Options :: ENABLE_TASKLISTS ,
529545 {
530546 let references = state. borrow ( ) . references . clone ( ) ;
531547 let broken_links = broken_links. clone ( ) ;
@@ -644,7 +660,10 @@ fn parse_with<'a>(
644660 }
645661 pulldown_cmark:: Tag :: Item => {
646662 if let Some ( Scope :: List ( list) ) = stack. last_mut ( ) {
647- list. items . push ( Vec :: new ( ) ) ;
663+ list. items . push ( ListItem {
664+ checked : None ,
665+ items : Vec :: new ( ) ,
666+ } ) ;
648667 }
649668
650669 None
@@ -977,6 +996,15 @@ fn parse_with<'a>(
977996 pulldown_cmark:: Event :: Rule => {
978997 produce ( state. borrow_mut ( ) , & mut stack, Item :: Rule , source)
979998 }
999+ pulldown_cmark:: Event :: TaskListMarker ( checked) => {
1000+ if let Some ( Scope :: List ( list) ) = stack. last_mut ( ) {
1001+ if let Some ( item) = list. items . last_mut ( ) {
1002+ item. checked = Some ( checked) ;
1003+ }
1004+ }
1005+
1006+ None
1007+ }
9801008 _ => None ,
9811009 } )
9821010}
@@ -1278,18 +1306,32 @@ where
12781306pub fn unordered_list < ' a , Message , Theme , Renderer > (
12791307 viewer : & impl Viewer < ' a , Message , Theme , Renderer > ,
12801308 settings : Settings ,
1281- items : & ' a [ Vec < Item > ] ,
1309+ items : & ' a [ ListItem ] ,
12821310) -> Element < ' a , Message , Theme , Renderer >
12831311where
12841312 Message : ' a ,
12851313 Theme : Catalog + ' a ,
12861314 Renderer : core:: text:: Renderer < Font = Font > + ' a ,
12871315{
1288- column ( items. iter ( ) . map ( |items | {
1316+ column ( items. iter ( ) . map ( |list_item | {
12891317 row ! [
1290- text( "•" ) . size( settings. text_size) ,
1318+ list_item
1319+ . checked
1320+ . map( |is_checked| {
1321+ Element :: from(
1322+ checkbox( "" , is_checked)
1323+ . spacing( 0 )
1324+ . text_size( settings. text_size) ,
1325+ )
1326+ } )
1327+ . unwrap_or( Element :: from(
1328+ text( "•" )
1329+ . width( settings. text_size)
1330+ . center( )
1331+ . size( settings. text_size)
1332+ ) ) ,
12911333 view_with(
1292- items,
1334+ & list_item . items,
12931335 Settings {
12941336 spacing: settings. spacing * 0.6 ,
12951337 ..settings
@@ -1311,7 +1353,7 @@ pub fn ordered_list<'a, Message, Theme, Renderer>(
13111353 viewer : & impl Viewer < ' a , Message , Theme , Renderer > ,
13121354 settings : Settings ,
13131355 start : u64 ,
1314- items : & ' a [ Vec < Item > ] ,
1356+ items : & ' a [ ListItem ] ,
13151357) -> Element < ' a , Message , Theme , Renderer >
13161358where
13171359 Message : ' a ,
@@ -1320,14 +1362,32 @@ where
13201362{
13211363 let digits = ( ( start + items. len ( ) as u64 ) . max ( 1 ) as f32 ) . log10 ( ) . ceil ( ) ;
13221364
1323- column ( items. iter ( ) . enumerate ( ) . map ( |( i, items ) | {
1365+ column ( items. iter ( ) . enumerate ( ) . map ( |( i, list_item ) | {
13241366 row ! [
1325- text!( "{}." , i as u64 + start)
1326- . size( settings. text_size)
1327- . align_x( alignment:: Horizontal :: Right )
1328- . width( settings. text_size * ( ( digits / 2.0 ) . ceil( ) + 1.0 ) ) ,
1367+ list_item
1368+ . checked
1369+ . map( |is_checked| {
1370+ Element :: from(
1371+ container(
1372+ checkbox( "" , is_checked)
1373+ . spacing( 0 )
1374+ . text_size( settings. text_size) ,
1375+ )
1376+ . align_right(
1377+ settings. text_size * ( ( digits / 2.0 ) . ceil( ) + 1.0 ) ,
1378+ ) ,
1379+ )
1380+ } )
1381+ . unwrap_or( Element :: from(
1382+ text!( "{}." , i as u64 + start)
1383+ . size( settings. text_size)
1384+ . align_x( alignment:: Horizontal :: Right )
1385+ . width(
1386+ settings. text_size * ( ( digits / 2.0 ) . ceil( ) + 1.0 )
1387+ ) ,
1388+ ) ) ,
13291389 view_with(
1330- items,
1390+ & list_item . items,
13311391 Settings {
13321392 spacing: settings. spacing * 0.6 ,
13331393 ..settings
@@ -1566,7 +1626,7 @@ where
15661626 fn unordered_list (
15671627 & self ,
15681628 settings : Settings ,
1569- items : & ' a [ Vec < Item > ] ,
1629+ items : & ' a [ ListItem ] ,
15701630 ) -> Element < ' a , Message , Theme , Renderer > {
15711631 unordered_list ( self , settings, items)
15721632 }
@@ -1578,7 +1638,7 @@ where
15781638 & self ,
15791639 settings : Settings ,
15801640 start : u64 ,
1581- items : & ' a [ Vec < Item > ] ,
1641+ items : & ' a [ ListItem ] ,
15821642 ) -> Element < ' a , Message , Theme , Renderer > {
15831643 ordered_list ( self , settings, start, items)
15841644 }
@@ -1636,6 +1696,7 @@ pub trait Catalog:
16361696 + scrollable:: Catalog
16371697 + text:: Catalog
16381698 + crate :: rule:: Catalog
1699+ + checkbox:: Catalog
16391700 + crate :: table:: Catalog
16401701{
16411702 /// The styling class of a Markdown code block.
0 commit comments