66use crate :: pandoc:: ast_context:: ASTContext ;
77use crate :: pandoc:: block:: MetaBlock ;
88use crate :: pandoc:: location:: { Location , Range , SourceInfo } ;
9+ use crate :: pandoc:: table:: {
10+ Alignment , Cell , ColSpec , ColWidth , Row , Table , TableBody , TableFoot , TableHead ,
11+ } ;
912use crate :: pandoc:: {
1013 Attr , Block , BlockQuote , BulletList , Caption , Citation , CitationMode , Cite , Code , CodeBlock ,
1114 DefinitionList , Div , Emph , Figure , Header , HorizontalRule , Image , Inline , Inlines , LineBlock ,
@@ -73,7 +76,8 @@ fn read_location(value: &Value) -> Option<(Option<usize>, Range)> {
7376 column : end_obj. get ( "column" ) ?. as_u64 ( ) ? as usize ,
7477 } ;
7578
76- let filename_index = obj. get ( "filenameIndex" )
79+ let filename_index = obj
80+ . get ( "filenameIndex" )
7781 . and_then ( |v| v. as_u64 ( ) )
7882 . map ( |i| i as usize ) ;
7983
@@ -182,23 +186,26 @@ fn read_inline(value: &Value) -> Result<Inline> {
182186 } ) )
183187 }
184188 "Space" => {
185- let ( filename_index, range) = obj. get ( "l" )
189+ let ( filename_index, range) = obj
190+ . get ( "l" )
186191 . and_then ( read_location)
187192 . unwrap_or_else ( || ( None , empty_range ( ) ) ) ;
188193 Ok ( Inline :: Space ( Space {
189194 source_info : SourceInfo :: new ( filename_index, range) ,
190195 } ) )
191196 }
192197 "LineBreak" => {
193- let ( filename_index, range) = obj. get ( "l" )
198+ let ( filename_index, range) = obj
199+ . get ( "l" )
194200 . and_then ( read_location)
195201 . unwrap_or_else ( || ( None , empty_range ( ) ) ) ;
196202 Ok ( Inline :: LineBreak ( crate :: pandoc:: inline:: LineBreak {
197203 source_info : SourceInfo :: new ( filename_index, range) ,
198204 } ) )
199205 }
200206 "SoftBreak" => {
201- let ( filename_index, range) = obj. get ( "l" )
207+ let ( filename_index, range) = obj
208+ . get ( "l" )
202209 . and_then ( read_location)
203210 . unwrap_or_else ( || ( None , empty_range ( ) ) ) ;
204211 Ok ( Inline :: SoftBreak ( SoftBreak {
@@ -616,7 +623,8 @@ fn read_ast_context(value: &Value) -> Result<ASTContext> {
616623 . as_object ( )
617624 . ok_or_else ( || JsonReadError :: InvalidType ( "Expected object for ASTContext" . to_string ( ) ) ) ?;
618625
619- let filenames_val = obj. get ( "filenames" )
626+ let filenames_val = obj
627+ . get ( "filenames" )
620628 . ok_or_else ( || JsonReadError :: MissingField ( "filenames" . to_string ( ) ) ) ?;
621629
622630 let filenames_arr = filenames_val
@@ -773,6 +781,197 @@ fn read_blocks(value: &Value) -> Result<Vec<Block>> {
773781 arr. iter ( ) . map ( read_block) . collect ( )
774782}
775783
784+ fn read_alignment ( value : & Value ) -> Result < Alignment > {
785+ let obj = value
786+ . as_object ( )
787+ . ok_or_else ( || JsonReadError :: InvalidType ( "Expected object for Alignment" . to_string ( ) ) ) ?;
788+ let t = obj
789+ . get ( "t" )
790+ . and_then ( |v| v. as_str ( ) )
791+ . ok_or_else ( || JsonReadError :: MissingField ( "t" . to_string ( ) ) ) ?;
792+
793+ match t {
794+ "AlignLeft" => Ok ( Alignment :: Left ) ,
795+ "AlignCenter" => Ok ( Alignment :: Center ) ,
796+ "AlignRight" => Ok ( Alignment :: Right ) ,
797+ "AlignDefault" => Ok ( Alignment :: Default ) ,
798+ _ => Err ( JsonReadError :: UnsupportedVariant ( format ! (
799+ "Alignment: {}" ,
800+ t
801+ ) ) ) ,
802+ }
803+ }
804+
805+ fn read_colwidth ( value : & Value ) -> Result < ColWidth > {
806+ let obj = value
807+ . as_object ( )
808+ . ok_or_else ( || JsonReadError :: InvalidType ( "Expected object for ColWidth" . to_string ( ) ) ) ?;
809+ let t = obj
810+ . get ( "t" )
811+ . and_then ( |v| v. as_str ( ) )
812+ . ok_or_else ( || JsonReadError :: MissingField ( "t" . to_string ( ) ) ) ?;
813+
814+ match t {
815+ "ColWidthDefault" => Ok ( ColWidth :: Default ) ,
816+ "ColWidth" => {
817+ let c = obj
818+ . get ( "c" )
819+ . ok_or_else ( || JsonReadError :: MissingField ( "c" . to_string ( ) ) ) ?;
820+ let percentage = c. as_f64 ( ) . ok_or_else ( || {
821+ JsonReadError :: InvalidType ( "ColWidth percentage must be number" . to_string ( ) )
822+ } ) ?;
823+ Ok ( ColWidth :: Percentage ( percentage) )
824+ }
825+ _ => Err ( JsonReadError :: UnsupportedVariant ( format ! (
826+ "ColWidth: {}" ,
827+ t
828+ ) ) ) ,
829+ }
830+ }
831+
832+ fn read_colspec ( value : & Value ) -> Result < ColSpec > {
833+ let arr = value
834+ . as_array ( )
835+ . ok_or_else ( || JsonReadError :: InvalidType ( "Expected array for ColSpec" . to_string ( ) ) ) ?;
836+
837+ if arr. len ( ) != 2 {
838+ return Err ( JsonReadError :: InvalidType (
839+ "ColSpec array must have 2 elements" . to_string ( ) ,
840+ ) ) ;
841+ }
842+
843+ let alignment = read_alignment ( & arr[ 0 ] ) ?;
844+ let colwidth = read_colwidth ( & arr[ 1 ] ) ?;
845+ Ok ( ( alignment, colwidth) )
846+ }
847+
848+ fn read_cell ( value : & Value ) -> Result < Cell > {
849+ let arr = value
850+ . as_array ( )
851+ . ok_or_else ( || JsonReadError :: InvalidType ( "Expected array for Cell" . to_string ( ) ) ) ?;
852+
853+ if arr. len ( ) != 5 {
854+ return Err ( JsonReadError :: InvalidType (
855+ "Cell array must have 5 elements" . to_string ( ) ,
856+ ) ) ;
857+ }
858+
859+ let attr = read_attr ( & arr[ 0 ] ) ?;
860+ let alignment = read_alignment ( & arr[ 1 ] ) ?;
861+ let row_span = arr[ 2 ]
862+ . as_u64 ( )
863+ . ok_or_else ( || JsonReadError :: InvalidType ( "Cell row_span must be number" . to_string ( ) ) ) ?
864+ as usize ;
865+ let col_span = arr[ 3 ]
866+ . as_u64 ( )
867+ . ok_or_else ( || JsonReadError :: InvalidType ( "Cell col_span must be number" . to_string ( ) ) ) ?
868+ as usize ;
869+ let content = read_blocks ( & arr[ 4 ] ) ?;
870+
871+ Ok ( Cell {
872+ attr,
873+ alignment,
874+ row_span,
875+ col_span,
876+ content,
877+ } )
878+ }
879+
880+ fn read_row ( value : & Value ) -> Result < Row > {
881+ let arr = value
882+ . as_array ( )
883+ . ok_or_else ( || JsonReadError :: InvalidType ( "Expected array for Row" . to_string ( ) ) ) ?;
884+
885+ if arr. len ( ) != 2 {
886+ return Err ( JsonReadError :: InvalidType (
887+ "Row array must have 2 elements" . to_string ( ) ,
888+ ) ) ;
889+ }
890+
891+ let attr = read_attr ( & arr[ 0 ] ) ?;
892+ let cells_arr = arr[ 1 ]
893+ . as_array ( )
894+ . ok_or_else ( || JsonReadError :: InvalidType ( "Row cells must be array" . to_string ( ) ) ) ?;
895+ let cells = cells_arr
896+ . iter ( )
897+ . map ( read_cell)
898+ . collect :: < Result < Vec < _ > > > ( ) ?;
899+
900+ Ok ( Row { attr, cells } )
901+ }
902+
903+ fn read_table_head ( value : & Value ) -> Result < TableHead > {
904+ let arr = value
905+ . as_array ( )
906+ . ok_or_else ( || JsonReadError :: InvalidType ( "Expected array for TableHead" . to_string ( ) ) ) ?;
907+
908+ if arr. len ( ) != 2 {
909+ return Err ( JsonReadError :: InvalidType (
910+ "TableHead array must have 2 elements" . to_string ( ) ,
911+ ) ) ;
912+ }
913+
914+ let attr = read_attr ( & arr[ 0 ] ) ?;
915+ let rows_arr = arr[ 1 ]
916+ . as_array ( )
917+ . ok_or_else ( || JsonReadError :: InvalidType ( "TableHead rows must be array" . to_string ( ) ) ) ?;
918+ let rows = rows_arr. iter ( ) . map ( read_row) . collect :: < Result < Vec < _ > > > ( ) ?;
919+
920+ Ok ( TableHead { attr, rows } )
921+ }
922+
923+ fn read_table_body ( value : & Value ) -> Result < TableBody > {
924+ let arr = value
925+ . as_array ( )
926+ . ok_or_else ( || JsonReadError :: InvalidType ( "Expected array for TableBody" . to_string ( ) ) ) ?;
927+
928+ if arr. len ( ) != 4 {
929+ return Err ( JsonReadError :: InvalidType (
930+ "TableBody array must have 4 elements" . to_string ( ) ,
931+ ) ) ;
932+ }
933+
934+ let attr = read_attr ( & arr[ 0 ] ) ?;
935+ let rowhead_columns = arr[ 1 ] . as_u64 ( ) . ok_or_else ( || {
936+ JsonReadError :: InvalidType ( "TableBody rowhead_columns must be number" . to_string ( ) )
937+ } ) ? as usize ;
938+ let head_arr = arr[ 2 ]
939+ . as_array ( )
940+ . ok_or_else ( || JsonReadError :: InvalidType ( "TableBody head must be array" . to_string ( ) ) ) ?;
941+ let head = head_arr. iter ( ) . map ( read_row) . collect :: < Result < Vec < _ > > > ( ) ?;
942+ let body_arr = arr[ 3 ]
943+ . as_array ( )
944+ . ok_or_else ( || JsonReadError :: InvalidType ( "TableBody body must be array" . to_string ( ) ) ) ?;
945+ let body = body_arr. iter ( ) . map ( read_row) . collect :: < Result < Vec < _ > > > ( ) ?;
946+
947+ Ok ( TableBody {
948+ attr,
949+ rowhead_columns,
950+ head,
951+ body,
952+ } )
953+ }
954+
955+ fn read_table_foot ( value : & Value ) -> Result < TableFoot > {
956+ let arr = value
957+ . as_array ( )
958+ . ok_or_else ( || JsonReadError :: InvalidType ( "Expected array for TableFoot" . to_string ( ) ) ) ?;
959+
960+ if arr. len ( ) != 2 {
961+ return Err ( JsonReadError :: InvalidType (
962+ "TableFoot array must have 2 elements" . to_string ( ) ,
963+ ) ) ;
964+ }
965+
966+ let attr = read_attr ( & arr[ 0 ] ) ?;
967+ let rows_arr = arr[ 1 ]
968+ . as_array ( )
969+ . ok_or_else ( || JsonReadError :: InvalidType ( "TableFoot rows must be array" . to_string ( ) ) ) ?;
970+ let rows = rows_arr. iter ( ) . map ( read_row) . collect :: < Result < Vec < _ > > > ( ) ?;
971+
972+ Ok ( TableFoot { attr, rows } )
973+ }
974+
776975fn read_block ( value : & Value ) -> Result < Block > {
777976 let obj = value
778977 . as_object ( )
@@ -783,7 +982,8 @@ fn read_block(value: &Value) -> Result<Block> {
783982 . ok_or_else ( || JsonReadError :: MissingField ( "t" . to_string ( ) ) ) ?;
784983
785984 // Extract location information if present
786- let ( filename_index, range) = obj. get ( "l" )
985+ let ( filename_index, range) = obj
986+ . get ( "l" )
787987 . and_then ( read_location)
788988 . unwrap_or_else ( || ( None , empty_range ( ) ) ) ;
789989
@@ -993,6 +1193,46 @@ fn read_block(value: &Value) -> Result<Block> {
9931193 source_info : SourceInfo :: new ( filename_index, range) ,
9941194 } ) )
9951195 }
1196+ "Table" => {
1197+ let c = obj
1198+ . get ( "c" )
1199+ . ok_or_else ( || JsonReadError :: MissingField ( "c" . to_string ( ) ) ) ?;
1200+ let arr = c. as_array ( ) . ok_or_else ( || {
1201+ JsonReadError :: InvalidType ( "Table content must be array" . to_string ( ) )
1202+ } ) ?;
1203+ if arr. len ( ) != 6 {
1204+ return Err ( JsonReadError :: InvalidType (
1205+ "Table array must have 6 elements" . to_string ( ) ,
1206+ ) ) ;
1207+ }
1208+ let attr = read_attr ( & arr[ 0 ] ) ?;
1209+ let caption = read_caption ( & arr[ 1 ] ) ?;
1210+ let colspec_arr = arr[ 2 ] . as_array ( ) . ok_or_else ( || {
1211+ JsonReadError :: InvalidType ( "Table colspec must be array" . to_string ( ) )
1212+ } ) ?;
1213+ let colspec = colspec_arr
1214+ . iter ( )
1215+ . map ( read_colspec)
1216+ . collect :: < Result < Vec < _ > > > ( ) ?;
1217+ let head = read_table_head ( & arr[ 3 ] ) ?;
1218+ let bodies_arr = arr[ 4 ] . as_array ( ) . ok_or_else ( || {
1219+ JsonReadError :: InvalidType ( "Table bodies must be array" . to_string ( ) )
1220+ } ) ?;
1221+ let bodies = bodies_arr
1222+ . iter ( )
1223+ . map ( read_table_body)
1224+ . collect :: < Result < Vec < _ > > > ( ) ?;
1225+ let foot = read_table_foot ( & arr[ 5 ] ) ?;
1226+ Ok ( Block :: Table ( Table {
1227+ attr,
1228+ caption,
1229+ colspec,
1230+ head,
1231+ bodies,
1232+ foot,
1233+ source_info : SourceInfo :: new ( filename_index, range) ,
1234+ } ) )
1235+ }
9961236 "Div" => {
9971237 let c = obj
9981238 . get ( "c" )
0 commit comments