@@ -324,7 +324,290 @@ module JsonOutput = struct
324
324
]
325
325
end
326
326
327
- module MdOutput = struct end
327
+ module MdOutput = struct
328
+ let stringifyDocstrings docstrings =
329
+ match docstrings with
330
+ | [] -> " "
331
+ | docstrings ->
332
+ docstrings |> List. map String. trim
333
+ |> List. filter (fun s -> s <> " " )
334
+ |> String. concat " \n\n "
335
+
336
+ let stringifyFieldDoc (fieldDoc : fieldDoc ) =
337
+ let buffer = Buffer. create 256 in
338
+ Buffer. add_string buffer
339
+ (Printf. sprintf " - **FIELD:** `%s`\n " fieldDoc.fieldName);
340
+ Buffer. add_string buffer
341
+ (Printf. sprintf " - **TYPE:** `%s`\n " fieldDoc.signature);
342
+ Buffer. add_string buffer
343
+ (Printf. sprintf " - **OPTIONAL:** %s\n "
344
+ (string_of_bool fieldDoc.optional));
345
+ (match fieldDoc.deprecated with
346
+ | Some d ->
347
+ Buffer. add_string buffer (Printf. sprintf " - **DEPRECATED:** %s\n " d)
348
+ | None -> () );
349
+ (match stringifyDocstrings fieldDoc.docstrings with
350
+ | "" -> ()
351
+ | docs ->
352
+ Buffer. add_string buffer (Printf. sprintf " - **DESCRIPTION:** %s\n " docs));
353
+ Buffer. contents buffer
354
+
355
+ let stringifyConstructorDoc (constructorDoc : constructorDoc ) =
356
+ let buffer = Buffer. create 256 in
357
+ Buffer. add_string buffer
358
+ (Printf. sprintf " - **CONSTRUCTOR:** `%s`\n " constructorDoc.constructorName);
359
+ Buffer. add_string buffer
360
+ (Printf. sprintf " - **SIGNATURE:** `%s`\n " constructorDoc.signature);
361
+ (match constructorDoc.deprecated with
362
+ | Some d ->
363
+ Buffer. add_string buffer (Printf. sprintf " - **DEPRECATED:** %s\n " d)
364
+ | None -> () );
365
+ (match stringifyDocstrings constructorDoc.docstrings with
366
+ | "" -> ()
367
+ | docs ->
368
+ Buffer. add_string buffer (Printf. sprintf " - **DESCRIPTION:** %s\n " docs));
369
+ (match constructorDoc.items with
370
+ | None -> ()
371
+ | Some (InlineRecord {fieldDocs} ) ->
372
+ Buffer. add_string buffer " - **INLINE_RECORD_FIELDS:**\n " ;
373
+ fieldDocs
374
+ |> List. iter (fun field ->
375
+ let field_lines =
376
+ stringifyFieldDoc field |> String. split_on_char '\n'
377
+ in
378
+ field_lines
379
+ |> List. iter (fun line ->
380
+ if String. trim line <> " " then
381
+ Buffer. add_string buffer (" " ^ line ^ " \n " ))));
382
+ Buffer. contents buffer
383
+
384
+ let stringifyDetail (detail : docItemDetail ) =
385
+ match detail with
386
+ | Record {fieldDocs} ->
387
+ let buffer = Buffer. create 512 in
388
+ Buffer. add_string buffer " \n **RECORD_FIELDS:**\n " ;
389
+ fieldDocs
390
+ |> List. iter (fun field ->
391
+ Buffer. add_string buffer (stringifyFieldDoc field ^ " \n " ));
392
+ Buffer. contents buffer
393
+ | Variant {constructorDocs} ->
394
+ let buffer = Buffer. create 512 in
395
+ Buffer. add_string buffer " \n **VARIANT_CONSTRUCTORS:**\n " ;
396
+ constructorDocs
397
+ |> List. iter (fun constructor ->
398
+ Buffer. add_string buffer
399
+ (stringifyConstructorDoc constructor ^ " \n " ));
400
+ Buffer. contents buffer
401
+ | Signature {parameters = _ ; returnType = _ } ->
402
+ (* For function signatures, we could add parameter details, but for now keep it simple *)
403
+ " "
404
+
405
+ let stringifySource (source : source ) =
406
+ Printf. sprintf " **SOURCE:** %s:%d:%d" source.filepath source.line source.col
407
+
408
+ let rec stringifyDocItem ?(depth = 2 ) (item : docItem ) =
409
+ let heading = String. make depth '#' ^ " " in
410
+
411
+ match item with
412
+ | Value {name; docstring; signature; deprecated; detail; source} ->
413
+ let buffer = Buffer. create 1024 in
414
+ Buffer. add_string buffer (Printf. sprintf " %s%s\n\n " heading name);
415
+ Buffer. add_string buffer " **KIND:** VALUE\n\n " ;
416
+ Buffer. add_string buffer
417
+ (Printf. sprintf " **SIGNATURE:** `%s`\n\n " signature);
418
+ Buffer. add_string buffer
419
+ (Printf. sprintf " %s\n\n " (stringifySource source));
420
+ (match deprecated with
421
+ | Some d ->
422
+ Buffer. add_string buffer (Printf. sprintf " **DEPRECATED:** %s\n\n " d)
423
+ | None -> () );
424
+ (match stringifyDocstrings docstring with
425
+ | "" -> ()
426
+ | docs ->
427
+ Buffer. add_string buffer
428
+ (Printf. sprintf " **DESCRIPTION:**\n %s\n\n " docs));
429
+ (match detail with
430
+ | None -> ()
431
+ | Some d -> Buffer. add_string buffer (stringifyDetail d ^ " \n " ));
432
+ Buffer. contents buffer
433
+ | Type {name; docstring; signature; deprecated; detail; source} ->
434
+ let buffer = Buffer. create 1024 in
435
+ Buffer. add_string buffer (Printf. sprintf " %s%s\n\n " heading name);
436
+ Buffer. add_string buffer " **KIND:** TYPE\n\n " ;
437
+ Buffer. add_string buffer
438
+ (Printf. sprintf " **SIGNATURE:** `%s`\n\n " signature);
439
+ Buffer. add_string buffer
440
+ (Printf. sprintf " %s\n\n " (stringifySource source));
441
+ (match deprecated with
442
+ | Some d ->
443
+ Buffer. add_string buffer (Printf. sprintf " **DEPRECATED:** %s\n\n " d)
444
+ | None -> () );
445
+ (match stringifyDocstrings docstring with
446
+ | "" -> ()
447
+ | docs ->
448
+ Buffer. add_string buffer
449
+ (Printf. sprintf " **DESCRIPTION:**\n %s\n\n " docs));
450
+ (match detail with
451
+ | None -> ()
452
+ | Some d -> Buffer. add_string buffer (stringifyDetail d ^ " \n " ));
453
+ Buffer. contents buffer
454
+ | Module m ->
455
+ let buffer = Buffer. create 1024 in
456
+ Buffer. add_string buffer (Printf. sprintf " %s%s\n\n " heading m.name);
457
+ Buffer. add_string buffer " **KIND:** MODULE\n\n " ;
458
+ Buffer. add_string buffer
459
+ (Printf. sprintf " %s\n\n " (stringifySource m.source));
460
+ (match m.moduletypeid with
461
+ | Some id ->
462
+ Buffer. add_string buffer
463
+ (Printf. sprintf " **MODULE_TYPE_ID:** %s\n\n " id)
464
+ | None -> () );
465
+ (match m.deprecated with
466
+ | Some d ->
467
+ Buffer. add_string buffer (Printf. sprintf " **DEPRECATED:** %s\n\n " d)
468
+ | None -> () );
469
+ (match stringifyDocstrings m.docstring with
470
+ | "" -> ()
471
+ | docs ->
472
+ Buffer. add_string buffer
473
+ (Printf. sprintf " **DESCRIPTION:**\n %s\n\n " docs));
474
+ (match m.items with
475
+ | [] -> ()
476
+ | items ->
477
+ Buffer. add_string buffer " **MODULE_CONTENTS:**\n\n " ;
478
+ items
479
+ |> List. iter (fun item ->
480
+ Buffer. add_string buffer
481
+ (stringifyDocItem ~depth: (depth + 1 ) item ^ " \n " )));
482
+ Buffer. contents buffer
483
+ | ModuleType m ->
484
+ let buffer = Buffer. create 1024 in
485
+ Buffer. add_string buffer (Printf. sprintf " %s%s\n\n " heading m.name);
486
+ Buffer. add_string buffer " **KIND:** MODULE_TYPE\n\n " ;
487
+ Buffer. add_string buffer
488
+ (Printf. sprintf " %s\n\n " (stringifySource m.source));
489
+ (match m.deprecated with
490
+ | Some d ->
491
+ Buffer. add_string buffer (Printf. sprintf " **DEPRECATED:** %s\n\n " d)
492
+ | None -> () );
493
+ (match stringifyDocstrings m.docstring with
494
+ | "" -> ()
495
+ | docs ->
496
+ Buffer. add_string buffer
497
+ (Printf. sprintf " **DESCRIPTION:**\n %s\n\n " docs));
498
+ (match m.items with
499
+ | [] -> ()
500
+ | items ->
501
+ Buffer. add_string buffer " **MODULE_TYPE_CONTENTS:**\n\n " ;
502
+ items
503
+ |> List. iter (fun item ->
504
+ Buffer. add_string buffer
505
+ (stringifyDocItem ~depth: (depth + 1 ) item ^ " \n " )));
506
+ Buffer. contents buffer
507
+ | ModuleAlias m ->
508
+ let buffer = Buffer. create 1024 in
509
+ Buffer. add_string buffer (Printf. sprintf " %s%s\n\n " heading m.name);
510
+ Buffer. add_string buffer " **KIND:** MODULE_ALIAS\n\n " ;
511
+ Buffer. add_string buffer
512
+ (Printf. sprintf " %s\n\n " (stringifySource m.source));
513
+ (match stringifyDocstrings m.docstring with
514
+ | "" -> ()
515
+ | docs ->
516
+ Buffer. add_string buffer
517
+ (Printf. sprintf " **DESCRIPTION:**\n %s\n\n " docs));
518
+ (match m.items with
519
+ | [] -> ()
520
+ | items ->
521
+ Buffer. add_string buffer " **ALIASED_MODULE_CONTENTS:**\n\n " ;
522
+ items
523
+ |> List. iter (fun item ->
524
+ Buffer. add_string buffer
525
+ (stringifyDocItem ~depth: (depth + 1 ) item ^ " \n " )));
526
+ Buffer. contents buffer
527
+
528
+ let stringifyDocsForModule (docs : docsForModule ) =
529
+ let buffer = Buffer. create 4096 in
530
+
531
+ (* Header with metadata *)
532
+ Buffer. add_string buffer (Printf. sprintf " # %s\n\n " docs.name);
533
+ Buffer. add_string buffer " **KIND:** MODULE\n\n " ;
534
+ Buffer. add_string buffer
535
+ (Printf. sprintf " %s\n\n " (stringifySource docs.source));
536
+
537
+ (match docs.deprecated with
538
+ | Some d ->
539
+ Buffer. add_string buffer (Printf. sprintf " **DEPRECATED:** %s\n\n " d)
540
+ | None -> () );
541
+
542
+ (match stringifyDocstrings docs.docstring with
543
+ | "" -> ()
544
+ | docs_str ->
545
+ Buffer. add_string buffer
546
+ (Printf. sprintf " **DESCRIPTION:**\n %s\n\n " docs_str));
547
+
548
+ (* Group items by type for better organization *)
549
+ let values, types, modules, module_types, module_aliases =
550
+ docs.items
551
+ |> List. fold_left
552
+ (fun (vals , typs , mods , mod_typs , mod_aliases ) item ->
553
+ match item with
554
+ | Value _ -> (item :: vals, typs, mods, mod_typs, mod_aliases)
555
+ | Type _ -> (vals, item :: typs, mods, mod_typs, mod_aliases)
556
+ | Module _ -> (vals, typs, item :: mods, mod_typs, mod_aliases)
557
+ | ModuleType _ -> (vals, typs, mods, item :: mod_typs, mod_aliases)
558
+ | ModuleAlias _ -> (vals, typs, mods, mod_typs, item :: mod_aliases))
559
+ ([] , [] , [] , [] , [] )
560
+ in
561
+
562
+ let values = List. rev values in
563
+ let types = List. rev types in
564
+ let modules = List. rev modules in
565
+ let module_types = List. rev module_types in
566
+ let module_aliases = List. rev module_aliases in
567
+
568
+ (* Content sections with clear headers *)
569
+ (match values with
570
+ | [] -> ()
571
+ | _ ->
572
+ Buffer. add_string buffer " ## VALUES\n\n " ;
573
+ values
574
+ |> List. iter (fun item ->
575
+ Buffer. add_string buffer (stringifyDocItem ~depth: 3 item ^ " \n " )));
576
+
577
+ (match types with
578
+ | [] -> ()
579
+ | _ ->
580
+ Buffer. add_string buffer " ## TYPES\n\n " ;
581
+ types
582
+ |> List. iter (fun item ->
583
+ Buffer. add_string buffer (stringifyDocItem ~depth: 3 item ^ " \n " )));
584
+
585
+ (match modules with
586
+ | [] -> ()
587
+ | _ ->
588
+ Buffer. add_string buffer " ## MODULES\n\n " ;
589
+ modules
590
+ |> List. iter (fun item ->
591
+ Buffer. add_string buffer (stringifyDocItem ~depth: 3 item ^ " \n " )));
592
+
593
+ (match module_types with
594
+ | [] -> ()
595
+ | _ ->
596
+ Buffer. add_string buffer " ## MODULE_TYPES\n\n " ;
597
+ module_types
598
+ |> List. iter (fun item ->
599
+ Buffer. add_string buffer (stringifyDocItem ~depth: 3 item ^ " \n " )));
600
+
601
+ (match module_aliases with
602
+ | [] -> ()
603
+ | _ ->
604
+ Buffer. add_string buffer " ## MODULE_ALIASES\n\n " ;
605
+ module_aliases
606
+ |> List. iter (fun item ->
607
+ Buffer. add_string buffer (stringifyDocItem ~depth: 3 item ^ " \n " )));
608
+
609
+ Buffer. contents buffer
610
+ end
328
611
329
612
let fieldToFieldDoc (field : SharedTypes.field ) : fieldDoc =
330
613
{
@@ -655,5 +938,5 @@ let extractDocsToJson ~entryPointFile ~debug =
655
938
656
939
let extractDocsToMd ~entryPointFile ~debug =
657
940
match extractDocs ~entry PointFile ~debug with
658
- | Ok (_docs , _env ) -> Ok " wip "
941
+ | Ok (docs , _env ) -> Ok ( MdOutput. stringifyDocsForModule docs)
659
942
| Error e -> Error e
0 commit comments