@@ -674,7 +674,7 @@ module Make (S : SPEC_VALUE) = struct
674674 missing prose templates. *)
675675 let prose_or_empty_message ~name prose =
676676 if Utils. string_is_empty prose then
677- Format. asprintf " < empty prose for %s> "
677+ Format. asprintf " `` empty prose for %s'' "
678678 (Latex. spec_var_to_latex_var ~font_type: TextTT name)
679679 else prose
680680
@@ -689,6 +689,15 @@ module Make (S : SPEC_VALUE) = struct
689689 *)
690690 let var_to_prose id = spec_var_to_latex_var ~font_type: TextTT id
691691
692+ (* * Removes angle brackets from the template and substitutes the
693+ placeholders with the provided substitutions. *)
694+ let preprocess_template_and_substitute template substitutions =
695+ (* Replace text inside angle brackets with the text itself. *)
696+ let template =
697+ Str. global_replace (Str. regexp " <\\ ([^>]*\\ )>" ) " \\ 1" template
698+ in
699+ substitute template substitutions
700+
692701 (* * [expr_to_prose expr] converts an expression [expr] to its prose
693702 representation. *)
694703 let rec expr_to_prose expr =
@@ -749,7 +758,7 @@ module Make (S : SPEC_VALUE) = struct
749758 | Some name -> Some (name, prose))
750759 formal_opt_prose_pairs
751760 in
752- substitute expr_prose formal_prose_pairs
761+ preprocess_template_and_substitute expr_prose formal_prose_pairs
753762 | Record { label_opt; fields } ->
754763 let variant = Spec. record_variant_for_expr S. spec expr in
755764 let name =
@@ -764,12 +773,33 @@ module Make (S : SPEC_VALUE) = struct
764773 TypeVariant. prose_description variant
765774 |> prose_or_empty_message ~name
766775 in
776+ let declared_fields =
777+ match variant.term with
778+ | Record { fields } -> fields
779+ | _ -> assert false
780+ in
781+ (* A record expression is allowed to specify only a subset of the declared fields.
782+ We figure those out, associate them with _, and append them to the explicitly
783+ specified fields.
784+ *)
785+ let unspecified_defaults =
786+ let declared_field_names =
787+ List. map (fun field -> field.Term. name) declared_fields
788+ in
789+ let unspecified_fields =
790+ Utils. string_list_difference declared_field_names
791+ (List. map fst fields)
792+ in
793+ List. map
794+ (fun field -> (field, Expr. Var Spec. ignore_var))
795+ unspecified_fields
796+ in
767797 let field_to_prose =
768798 List. map
769799 (fun (field , field_expr ) -> (field, expr_to_prose field_expr))
770- fields
800+ ( fields @ unspecified_defaults)
771801 in
772- substitute expr_prose field_to_prose
802+ preprocess_template_and_substitute expr_prose field_to_prose
773803 | RecordUpdate { record_expr; updates } ->
774804 let record_prose = expr_to_prose record_expr in
775805 let updates_prose =
@@ -837,7 +867,7 @@ module Make (S : SPEC_VALUE) = struct
837867 relation.name
838868 in
839869 let formal_prose_pair = [ (formal_arg_name, args_prose) ] in
840- substitute expr_prose formal_prose_pair
870+ preprocess_template_and_substitute expr_prose formal_prose_pair
841871 else
842872 let formal_arg_pairs = List. combine formal_args args in
843873 let formal_prose_pairs =
@@ -846,7 +876,7 @@ module Make (S : SPEC_VALUE) = struct
846876 named_args_for_opt_named_term opt_named_term arg)
847877 formal_arg_pairs
848878 in
849- substitute expr_prose formal_prose_pairs
879+ preprocess_template_and_substitute expr_prose formal_prose_pairs
850880
851881 (* * [short_circuit_to_prose relation_name short_circuit] returns the prose
852882 for the short-circuit expressions added as superscripts. *)
@@ -956,6 +986,14 @@ module Make (S : SPEC_VALUE) = struct
956986 "one of the following applies". *)
957987 pp_prose_rule_elements fmt ~case_name: " " rule_elements
958988
989+ (* * [pp_render_rule_math_and_prose fmt def] renders both the mathematical
990+ inference rules and the prose description of the rules referenced by
991+ [def] with the formatter [fmt]. *)
992+ let pp_render_rule_math_and_prose fmt def =
993+ pp_render_rule fmt def;
994+ fprintf fmt " @.@." ;
995+ pp_render_rule_prose fmt def
996+
959997 (* * [pp_render_rule_macro fmt def] renders the LaTeX wrapper macro
960998 [\DefineRule{name}{...}] around the rendering of the mathematical
961999 inference rules referenced by [def] with the formatter [fmt]. *)
@@ -1010,7 +1048,7 @@ module Make (S : SPEC_VALUE) = struct
10101048 | Elem_Type def -> pp_type_definition fmt def
10111049 | Elem_Relation def -> pp_relation_definition fmt def
10121050 | Elem_RenderTypes def -> RenderTypeSubsets. pp_render_types fmt def
1013- | Elem_RenderRule def -> RenderRule. pp_render_rule fmt def
1051+ | Elem_RenderRule def -> RenderRule. pp_render_rule_math_and_prose fmt def
10141052
10151053 (* * [pp_elem_definition_macro fmt elem] renders a macro definition for an
10161054 element of the specification. *)
@@ -1042,28 +1080,9 @@ module Make (S : SPEC_VALUE) = struct
10421080 Latex. spec_var_to_latex_var ~font_type: Latex. Text name
10431081 in
10441082 match elem with
1045- | Elem_Constant _ ->
1046- fprintf fmt {|
1047- \section* {% s}
1048- % a
1049- | } latex_name pp_elem elem
1050- | Elem_Relation _ ->
1051- if is_operator elem then ()
1052- else fprintf fmt {|
1053- \section* {% s}
1054- % a
1055- | } latex_name pp_elem elem
1056- | Elem_Type _ ->
1057- fprintf fmt {|
1058- \section* {% s}
1059- % a
1060- | } latex_name pp_elem elem
1061- | Elem_RenderTypes _ ->
1062- fprintf fmt {|
1063- \section* {% s}
1064- % a
1065- | } latex_name pp_elem elem
1066- | Elem_RenderRule _ ->
1083+ | Elem_Relation _ when is_operator elem -> ()
1084+ | Elem_Constant _ | Elem_Type _ | Elem_RenderTypes _
1085+ | Elem_RenderRule _ | Elem_Relation _ ->
10671086 fprintf fmt {|
10681087\section* {% s}
10691088% a
0 commit comments