Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package ocaml-pp for openSUSE:Factory checked in at 2025-03-04 18:32:01 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ocaml-pp (Old) and /work/SRC/openSUSE:Factory/.ocaml-pp.new.19136 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ocaml-pp" Tue Mar 4 18:32:01 2025 rev:6 rq:1249881 version:2.0.0 Changes: -------- --- /work/SRC/openSUSE:Factory/ocaml-pp/ocaml-pp.changes 2023-09-22 21:50:46.532182101 +0200 +++ /work/SRC/openSUSE:Factory/.ocaml-pp.new.19136/ocaml-pp.changes 2025-03-04 18:32:21.205361752 +0100 @@ -1,0 +2,6 @@ +Mon Mar 3 03:03:03 UTC 2025 - oher...@suse.de + +- Update to version 2.0.0 + see included CHANGES.md file for details + +------------------------------------------------------------------- Old: ---- ocaml-pp-1.2.0.tar.xz New: ---- ocaml-pp-2.0.0.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ocaml-pp.spec ++++++ --- /var/tmp/diff_new_pack.0vXyqn/_old 2025-03-04 18:32:21.709382572 +0100 +++ /var/tmp/diff_new_pack.0vXyqn/_new 2025-03-04 18:32:21.713382737 +0100 @@ -1,7 +1,7 @@ # # spec file for package ocaml-pp # -# Copyright (c) 2023 SUSE LLC +# Copyright (c) 2025 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -31,7 +31,7 @@ %define pkg ocaml-pp Name: %pkg%nsuffix -Version: 1.2.0 +Version: 2.0.0 Release: 0 %{?ocaml_preserve_bytecode} Summary: Pretty-printing library @@ -41,7 +41,7 @@ URL: https://opam.ocaml.org/packages/pp Source0: %pkg-%version.tar.xz BuildRequires: ocaml-dune >= 2.8 -BuildRequires: ocaml-rpm-macros >= 20230101 +BuildRequires: ocaml-rpm-macros >= 20240909 BuildRequires: ocaml(ocaml_base_version) >= 4.08 %if "%build_flavor" == "testsuite" ++++++ _service ++++++ --- /var/tmp/diff_new_pack.0vXyqn/_old 2025-03-04 18:32:21.777385380 +0100 +++ /var/tmp/diff_new_pack.0vXyqn/_new 2025-03-04 18:32:21.777385380 +0100 @@ -1,7 +1,7 @@ <services> - <service name="tar_scm" mode="disabled"> + <service name="tar_scm" mode="manual"> <param name="filename">ocaml-pp</param> - <param name="revision">83b68c740f21acdcfe54436355ab328372871357</param> + <param name="revision">b6741dd41ef5fc5bda8b3640097ac29818a43577</param> <param name="scm">git</param> <param name="submodules">disable</param> <param name="url">https://github.com/ocaml-dune/pp.git</param> @@ -9,10 +9,10 @@ <param name="versionrewrite-pattern">[v]?([^+]+)(.*)</param> <param name="versionrewrite-replacement">\1</param> </service> - <service name="recompress" mode="disabled"> + <service name="recompress" mode="manual"> <param name="file">*.tar</param> <param name="compression">xz</param> </service> - <service name="set_version" mode="disabled"/> + <service name="set_version" mode="manual"/> </services> ++++++ ocaml-pp-1.2.0.tar.xz -> ocaml-pp-2.0.0.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocaml-pp-1.2.0/.github/workflows/ci.yml new/ocaml-pp-2.0.0/.github/workflows/ci.yml --- old/ocaml-pp-1.2.0/.github/workflows/ci.yml 2023-09-15 10:53:27.000000000 +0200 +++ new/ocaml-pp-2.0.0/.github/workflows/ci.yml 2024-09-16 09:43:24.000000000 +0200 @@ -14,8 +14,27 @@ - ubuntu-latest - windows-latest ocaml-compiler: + - 5.2.x - 4.14.x - - 4.08.x + - 4.13.x + include: + # OCaml 4.12.x: skipping windows (fail) + - ocaml-compiler: 4.12.x + os: ubuntu-latest + - ocaml-compiler: 4.12.x + os: macos-latest + # OCaml 4.11.x: skipping macos & windows (fail) + - ocaml-compiler: 4.11.x + os: ubuntu-latest + # OCaml 4.10.x: skipping windows (fail) + - ocaml-compiler: 4.10.x + os: ubuntu-latest + - ocaml-compiler: 4.10.x + os: macos-latest + # OCaml 4.08.x: skipping macos & windows (fail) + # Keep the minimal version of OCaml in sync in here and `dune-project` + - ocaml-compiler: 4.08.x + os: ubuntu-latest runs-on: ${{ matrix.os }} @@ -27,15 +46,27 @@ git config --global core.ignorecase false - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Use OCaml ${{ matrix.ocaml-compiler }} - uses: ocaml/setup-ocaml@v2 + uses: ocaml/setup-ocaml@v3 with: ocaml-compiler: ${{ matrix.ocaml-compiler }} - - run: opam install . --deps-only --with-test + - name: Install dependencies + run: opam install . --deps-only --with-doc --with-test --with-dev-setup - - run: opam exec -- dune build + - name: Build + run: opam exec -- dune build - - run: opam exec -- dune runtest + - name: Run tests + run: opam exec -- dune runtest + + - name: Check for uncommitted changes + run: git diff --exit-code + + - name: Lint fmt + uses: ocaml/setup-ocaml/lint-fmt@v3 + + - name: Lint doc + uses: ocaml/setup-ocaml/lint-doc@v3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocaml-pp-1.2.0/.ocamlformat new/ocaml-pp-2.0.0/.ocamlformat --- old/ocaml-pp-1.2.0/.ocamlformat 2023-09-15 10:53:27.000000000 +0200 +++ new/ocaml-pp-2.0.0/.ocamlformat 2024-09-16 09:43:24.000000000 +0200 @@ -1,4 +1,4 @@ -version=0.26.0 +version=0.26.2 break-separators=before dock-collection-brackets=false break-sequences=true diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocaml-pp-1.2.0/CHANGES.md new/ocaml-pp-2.0.0/CHANGES.md --- old/ocaml-pp-1.2.0/CHANGES.md 2023-09-15 10:53:27.000000000 +0200 +++ new/ocaml-pp-2.0.0/CHANGES.md 2024-09-16 09:43:24.000000000 +0200 @@ -1,3 +1,20 @@ +2.0.0 +----- + +- Prepare release (#21, @mbarbin) + - Upgrade to `ocamlformat.0.26.2`. + - Fmt the code + - Add CI badge to README + - Upgrade GitHub workflow actions dependencies (checkout@v4, setup-ocaml@v3) + - Add more validation steps in CI + - Add `ocamlformat` as dev-setup dependency + +- Add `Pp.verbatimf`. (#18, @mbarbin) + +- Add `Pp.paragraph` and `Pp.paragraphf` (#19, @Alizter) + +- Remove `of_fmt` constructor. (#17, @Alizter) + 1.2.0 ----- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocaml-pp-1.2.0/Makefile new/ocaml-pp-2.0.0/Makefile --- old/ocaml-pp-1.2.0/Makefile 2023-09-15 10:53:27.000000000 +0200 +++ new/ocaml-pp-2.0.0/Makefile 2024-09-16 09:43:24.000000000 +0200 @@ -17,9 +17,6 @@ clean: dune clean -all-supported-ocaml-versions: - dune runtest --workspace dune-workspace.dev - release: dune-release tag dune-release distrib --skip-build --skip-lint --skip-tests -n pp diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocaml-pp-1.2.0/README.md new/ocaml-pp-2.0.0/README.md --- old/ocaml-pp-1.2.0/README.md 2023-09-15 10:53:27.000000000 +0200 +++ new/ocaml-pp-2.0.0/README.md 2024-09-16 09:43:24.000000000 +0200 @@ -1,6 +1,8 @@ Pp - Pretty printing ==================== +[](https://github.com/ocaml-dune/pp/actions/workflows/ci.yml) + This library provides a lean alternative to the [Format][format] module of the OCaml standard library. It aims to make it easy for users to do the right thing. If you have tried `Format` before but diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocaml-pp-1.2.0/dune-project new/ocaml-pp-2.0.0/dune-project --- old/ocaml-pp-1.2.0/dune-project 2023-09-15 10:53:27.000000000 +0200 +++ new/ocaml-pp-2.0.0/dune-project 2024-09-16 09:43:24.000000000 +0200 @@ -14,8 +14,12 @@ (package (name pp) (depends - (ocaml (>= 4.08.0)) - (ppx_expect :with-test)) + (ocaml (>= 4.08)) + (ppx_expect :with-test) + (ocamlformat + (and + :with-dev-setup + (= 0.26.2)))) (synopsis "Pretty-printing library") (description " This library provides a lean alternative to the Format [1] module of diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocaml-pp-1.2.0/dune-workspace.dev new/ocaml-pp-2.0.0/dune-workspace.dev --- old/ocaml-pp-1.2.0/dune-workspace.dev 2023-09-15 10:53:27.000000000 +0200 +++ new/ocaml-pp-2.0.0/dune-workspace.dev 1970-01-01 01:00:00.000000000 +0100 @@ -1,4 +0,0 @@ -(lang dune 1.0) - -;; This file is used by `make all-supported-ocaml-versions` -(context (opam (switch 4.04.2))) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocaml-pp-1.2.0/ocaml-pp.changes new/ocaml-pp-2.0.0/ocaml-pp.changes --- old/ocaml-pp-1.2.0/ocaml-pp.changes 1970-01-01 01:00:00.000000000 +0100 +++ new/ocaml-pp-2.0.0/ocaml-pp.changes 2024-09-16 09:43:24.000000000 +0200 @@ -0,0 +1,16 @@ +5197d6e chore: consistent maming of type vars and add missing comments (#15) +86281b1 feature: Pp.paragraph (#16) +faf15db refactor: remove Format constructor (#17) +6749c14 add Pp.verbatimf (#18) +fe1d7cc fix: type of Pp.paragraphf and add changelog (#19) +da0cde5 Add ocamlformat as dev-setup dependency +bfb5582 Add more validation steps in CI +8819e69 Upgrade GitHub workflow actions deps +07eef74 Add CI badge to README +a9a291d Fmt +624aa23 Upgrade to ocamlformat.0.26.2 +9a76ee2 Prepare release notes +4a323f1 Add more validations to CI +34f6477 Simplify ocaml lower bound expression +cd743f8 Remove unused file +b6741dd (tag: 2.0.0) Merge pull request #21 from mbarbin/prepare-release diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocaml-pp-1.2.0/pp.opam new/ocaml-pp-2.0.0/pp.opam --- old/ocaml-pp-1.2.0/pp.opam 2023-09-15 10:53:27.000000000 +0200 +++ new/ocaml-pp-2.0.0/pp.opam 2024-09-16 09:43:24.000000000 +0200 @@ -30,8 +30,9 @@ bug-reports: "https://github.com/ocaml-dune/pp/issues" depends: [ "dune" {>= "2.8"} - "ocaml" {>= "4.08.0"} + "ocaml" {>= "4.08"} "ppx_expect" {with-test} + "ocamlformat" {with-dev-setup & = "0.26.2"} "odoc" {with-doc} ] build: [ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocaml-pp-1.2.0/src/pp.ml new/ocaml-pp-2.0.0/src/pp.ml --- old/ocaml-pp-1.2.0/src/pp.ml 2023-09-15 10:53:27.000000000 +0200 +++ new/ocaml-pp-2.0.0/src/pp.ml 2024-09-16 09:43:24.000000000 +0200 @@ -24,59 +24,12 @@ | Tag of 'a * 'a t end -type +'a t = - | Nop - | Seq of 'a t * 'a t - | Concat of 'a t * 'a t list - | Box of int * 'a t - | Vbox of int * 'a t - | Hbox of 'a t - | Hvbox of int * 'a t - | Hovbox of int * 'a t - | Verbatim of string - | Char of char - | Break of (string * int * string) * (string * int * string) - | Newline - | Text of string - | Tag of 'a * 'a t - | Format of (Format.formatter -> unit) +include Ast -let rec of_ast : 'a. 'a Ast.t -> 'a t = function - | Nop -> Nop - | Seq (x, y) -> Seq (of_ast x, of_ast y) - | Concat (x, y) -> Concat (of_ast x, List.map ~f:of_ast y) - | Box (x, y) -> Box (x, of_ast y) - | Vbox (x, y) -> Vbox (x, of_ast y) - | Hbox x -> Hbox (of_ast x) - | Hvbox (x, y) -> Hvbox (x, of_ast y) - | Hovbox (x, y) -> Hovbox (x, of_ast y) - | Verbatim s -> Verbatim s - | Char c -> Char c - | Break (x, y) -> Break (x, y) - | Newline -> Newline - | Text s -> Text s - | Tag (a, x) -> Tag (a, of_ast x) - -let to_ast x = - let rec to_ast : 'a t -> 'a Ast.t = function - | Nop -> Nop - | Seq (x, y) -> Seq (to_ast x, to_ast y) - | Concat (x, y) -> Concat (to_ast x, List.map ~f:(fun x -> to_ast x) y) - | Box (x, y) -> Box (x, to_ast y) - | Vbox (x, y) -> Vbox (x, to_ast y) - | Hbox x -> Hbox (to_ast x) - | Hvbox (x, y) -> Hvbox (x, to_ast y) - | Hovbox (x, y) -> Hovbox (x, to_ast y) - | Verbatim s -> Verbatim s - | Char c -> Char c - | Break (x, y) -> Break (x, y) - | Newline -> Newline - | Tag (a, x) -> Tag (a, to_ast x) - | Text s -> Text s - | Format _ -> raise_notrace Exit - in - try Ok (to_ast x) with - | Exit -> Error () +let of_ast = Fun.id +let to_ast = Fun.id + +type ('a, 'tag) format_string = ('a, unit, string, 'tag t) format4 let rec map_tags t ~f = match t with @@ -90,7 +43,6 @@ | Hovbox (indent, t) -> Hovbox (indent, map_tags t ~f) | (Verbatim _ | Char _ | Break _ | Newline | Text _) as t -> t | Tag (tag, t) -> Tag (f tag, map_tags t ~f) - | Format f -> Format f let rec filter_map_tags t ~f = match t with @@ -109,7 +61,6 @@ match f tag with | None -> t | Some tag -> Tag (tag, t)) - | Format f -> Format f module Render = struct open Format @@ -152,7 +103,6 @@ | Newline -> pp_force_newline ppf () | Text s -> pp_print_text ppf s | Tag (tag, t) -> tag_handler ppf tag t - | Format f -> f ppf end let to_fmt_with_tags = Render.render @@ -186,6 +136,7 @@ let hvbox ?(indent = 0) t = Hvbox (indent, t) let hovbox ?(indent = 0) t = Hovbox (indent, t) let verbatim x = Verbatim x +let verbatimf fmt = Printf.ksprintf verbatim fmt let char x = Char x let custom_break ~fits ~breaks = Break (fits, breaks) @@ -196,8 +147,10 @@ let cut = break ~nspaces:0 ~shift:0 let newline = Newline let text s = Text s -let textf fmt = Printf.ksprintf text fmt +let textf (fmt : ('a, 'tag) format_string) = Printf.ksprintf text fmt let tag tag t = Tag (tag, t) +let paragraph s = hovbox (text s) +let paragraphf (fmt : ('a, 'tag) format_string) = Printf.ksprintf paragraph fmt let enumerate l ~f = vbox @@ -221,8 +174,6 @@ let ( ++ ) = seq end -let of_fmt f x = Format (fun ppf -> f ppf x) - let compare = let compare_both (type a b) (f : a -> a -> int) (g : b -> b -> int) (a, b) (c, d) = @@ -297,10 +248,5 @@ | Text _, _ -> -1 | _, Text _ -> 1 | Tag (a, b), Tag (c, d) -> compare_both compare_tag compare (a, b) (c, d) - | Format _, Format _ -> - raise - (Invalid_argument "[Pp.of_fmt] values not supported in [Pp.compare]") - | Format _, _ -> -1 - | _, Format _ -> 1 in compare diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocaml-pp-1.2.0/src/pp.mli new/ocaml-pp-2.0.0/src/pp.mli --- old/ocaml-pp-1.2.0/src/pp.mli 2023-09-15 10:53:27.000000000 +0200 +++ new/ocaml-pp-2.0.0/src/pp.mli 2024-09-16 09:43:24.000000000 +0200 @@ -1,37 +1,45 @@ (** Pretty-printing. *) -(** A document that is not yet rendered. The argument is the type of tags in the - document. For instance tags might be used for styles. *) +(** ['tag t] represents a document that is not yet rendered. The argument ['tag] + is the type of tags in the document. For instance tags might be used for + styles. + + If you want to serialise and deserialise this datastructure, you can use the + [Ast.t] type together with the [of_ast] and [to_ast] functions. *) type +'tag t (** {1 Basic combinators} *) (** A pretty printer that prints nothing *) -val nop : _ t +val nop : 'tag t (** [seq x y] prints [x] and then [y] *) -val seq : 'a t -> 'a t -> 'a t +val seq : 'tag t -> 'tag t -> 'tag t (** [concat ?sep l] prints elements in [l] separated by [sep]. [sep] defaults to [nop]. *) -val concat : ?sep:'a t -> 'a t list -> 'a t +val concat : ?sep:'tag t -> 'tag t list -> 'tag t + +(** Convenience function for [List.map] followed by [concat]. *) +val concat_map : ?sep:'tag t -> 'a list -> f:('a -> 'tag t) -> 'tag t -(** Convenience function for [List.map] followed by [concat] *) -val concat_map : ?sep:'a t -> 'b list -> f:('b -> 'a t) -> 'a t +(** Convenience function for [List.mapi] followed by [concat]. *) +val concat_mapi : ?sep:'tag t -> 'a list -> f:(int -> 'a -> 'tag t) -> 'tag t -val concat_mapi : ?sep:'a t -> 'b list -> f:(int -> 'b -> 'a t) -> 'a t +(** An indivisible block of text. *) +val verbatim : string -> 'tag t -(** An indivisible block of text *) -val verbatim : string -> _ t +(** Same as [verbatim] but take a format string as argument. *) +val verbatimf : ('a, unit, string, 'tag t) format4 -> 'a -(** A single character *) -val char : char -> _ t +(** A single character. *) +val char : char -> 'tag t (** Print a bunch of text. The line may be broken at any spaces in the text. *) -val text : string -> _ t +val text : string -> 'tag t (** Same as [text] but take a format string as argument. *) -val textf : ('a, unit, string, _ t) format4 -> 'a +val textf : ('a, unit, string, 'tag t) format4 -> 'a (** {1 Break hints} *) @@ -41,7 +49,7 @@ So for instance [verbatim "x" ++ space ++ verbatim "y"] might produce "x y" or "x\n<indentation>y". *) -val space : _ t +val space : 'tag t (** [cut] instructs the pretty-printing algorithm that the line may be broken at this point. If the algorithm decides not to break the line, nothing is @@ -49,14 +57,14 @@ So for instance [verbatim "x" ++ space ++ verbatim "y"] might produce "xy" or "x\n<indentation>y". *) -val cut : _ t +val cut : 'tag t (** [break] is a generalisation of [space] and [cut]. It also instructs the pretty-printing algorithm that the line may be broken at this point. If it ends up being broken, [shift] will be added to the indentation level, otherwise [nspaces] spaces will be printed. [shift] can be negative, in which case the indentation will be reduced. *) -val break : nspaces:int -> shift:int -> _ t +val break : nspaces:int -> shift:int -> 'tag t (** [custom_break ~fits:(a, b, c) ~breaks:(x, y, z)] is a generalisation of [break]. It also instructs the pretty-printing algorithm that the line may @@ -66,10 +74,13 @@ printed. The indentation [y] can be negative, in which case the indentation will be reduced. *) val custom_break : - fits:string * int * string -> breaks:string * int * string -> _ t + fits:string * int * string -> breaks:string * int * string -> 'tag t -(** Force a newline to be printed *) -val newline : _ t +(** Force a newline to be printed. Usage is discourage since it breaks printing + with boxes. If you need to add breaks to your text, put your items into + [box]es and [concat] with a separating [space] afterwhich wrapping it in a + [vbox]. *) +val newline : 'tag t (** {1 Boxes} *) @@ -105,20 +116,20 @@ (** Try to put as much as possible on each line. Additionally, a break hint always break the line if the breaking would reduce the indentation level inside the box ([break] with negative [shift] value). *) -val box : ?indent:int -> 'a t -> 'a t +val box : ?indent:int -> 'tag t -> 'tag t (** Always break the line when encountering a break hint. *) -val vbox : ?indent:int -> 'a t -> 'a t +val vbox : ?indent:int -> 'tag t -> 'tag t (** Print everything on one line, no matter what *) -val hbox : 'a t -> 'a t +val hbox : 'tag t -> 'tag t (** If possible, print everything on one line. Otherwise, behave as a [vbox] *) -val hvbox : ?indent:int -> 'a t -> 'a t +val hvbox : ?indent:int -> 'tag t -> 'tag t (** Try to put as much as possible on each line. Basically the same as [box] but without the rule about breaks with negative [shift] value. *) -val hovbox : ?indent:int -> 'a t -> 'a t +val hovbox : ?indent:int -> 'tag t -> 'tag t (** {1 Tags} *) @@ -127,15 +138,25 @@ terminal with colors. *) (** [tag x t] Tag the material printed by [t] with [x] *) -val tag : 'a -> 'a t -> 'a t +val tag : 'tag -> 'tag t -> 'tag t (** Convert tags in a documents *) -val map_tags : 'a t -> f:('a -> 'b) -> 'b t +val map_tags : 'from_tag t -> f:('from_tag -> 'to_tag) -> 'to_tag t -val filter_map_tags : 'a t -> f:('a -> 'b option) -> 'b t +(** Convert tags in a documents, possibly removing some tags. *) +val filter_map_tags : + 'from_tag t -> f:('from_tag -> 'to_tag option) -> 'to_tag t (** {1 Convenience functions} *) +(** [paragraph s] is [hovbox (text s)]. This is useful to preserve the structure + of a paragraph of text without worrying about it being broken by a [vbox]. *) +val paragraph : string -> 'tag t + +(** [paragraphf s] is [textf s] followed by a [hovbox]. The [textf] version of + [paragraph]. *) +val paragraphf : ('a, unit, string, 'tag t) format4 -> 'a + (** [enumerate l ~f] produces an enumeration of the form: {v @@ -144,7 +165,7 @@ - item3 ... v} *) -val enumerate : 'a list -> f:('a -> 'b t) -> 'b t +val enumerate : 'a list -> f:('a -> 'tag t) -> 'tag t (** [chain l ~f] is used to print a succession of items that follow each other. It produces an output of this form: @@ -155,66 +176,59 @@ -> item3 ... v} *) -val chain : 'a list -> f:('a -> 'b t) -> 'b t +val chain : 'a list -> f:('a -> 'tag t) -> 'tag t (** {1 Operators} *) module O : sig + (** Infix operators for [Pp.t] *) + (** Same as [seq] *) - val ( ++ ) : 'a t -> 'a t -> 'a t + val ( ++ ) : 'tag t -> 'tag t -> 'tag t end (** {1 Rendering} *) (** Render a document to a classic formatter *) -val to_fmt : Format.formatter -> _ t -> unit +val to_fmt : Format.formatter -> 'tag t -> unit val to_fmt_with_tags : Format.formatter - -> 'a t - -> tag_handler:(Format.formatter -> 'a -> 'a t -> unit) + -> 'tag t + -> tag_handler:(Format.formatter -> 'tag -> 'tag t -> unit) -> unit -(** {1 Injection} *) - -(** Inject a classic formatter in a document. - - Disclaimer: this function is to meant to help using [Pp] in existing code - that already use the [Format] module without having to port everything to - [Pp]. It is not meant as the normal way to create [Pp.t] values. *) -val of_fmt : (Format.formatter -> 'a -> unit) -> 'a -> _ t - (** {1 Ast} *) module Ast : sig - (** Stable representation useful for serialization *) - type 'a t = + (** Stable representation of [Pp.t] useful for serialization *) + + (** Stable abstract syntax tree for [Pp.t] that can be used for serialization + and deserialization. *) + type +'tag t = | Nop - | Seq of 'a t * 'a t - | Concat of 'a t * 'a t list - | Box of int * 'a t - | Vbox of int * 'a t - | Hbox of 'a t - | Hvbox of int * 'a t - | Hovbox of int * 'a t + | Seq of 'tag t * 'tag t + | Concat of 'tag t * 'tag t list + | Box of int * 'tag t + | Vbox of int * 'tag t + | Hbox of 'tag t + | Hvbox of int * 'tag t + | Hovbox of int * 'tag t | Verbatim of string | Char of char | Break of (string * int * string) * (string * int * string) | Newline | Text of string - | Tag of 'a * 'a t + | Tag of 'tag * 'tag t end -(** [of_ast t] [Ast.t] to [Pp.t] *) -val of_ast : 'a Ast.t -> 'a t +(** [of_ast t] converts an [Ast.t] to a [Pp.t]. *) +val of_ast : 'tag Ast.t -> 'tag t -(** [to_ast t] will try to convert [t] to [Ast.t]. When [t] contains values - constructed with [of_fmt], this function will fail and return [Error ()] *) -val to_ast : 'a t -> ('a Ast.t, unit) result +(** [to_ast t] converts a [Pp.t] to an [Ast.t]. *) +val to_ast : 'tag t -> 'tag Ast.t (** {1 Comparison} *) -(** [compare cmp x y] compares [x] and [y] using [cmp] to compare tags. - - @raise Invalid_argument if two [of_fmt] values are compared. *) -val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int +(** [compare cmp x y] compares [x] and [y] using [cmp] to compare tags. *) +val compare : ('tag -> 'tag -> int) -> 'tag t -> 'tag t -> int diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ocaml-pp-1.2.0/test/tests.ml new/ocaml-pp-2.0.0/test/tests.ml --- old/ocaml-pp-1.2.0/test/tests.ml 2023-09-15 10:53:27.000000000 +0200 +++ new/ocaml-pp-2.0.0/test/tests.ml 2024-09-16 09:43:24.000000000 +0200 @@ -102,6 +102,10 @@ x x x x x x x x x x x x |}] +let%expect_test "verbatimf" = + print (Pp.verbatimf "ident%d" 42); + [%expect {| ident42 |}] + (* Difference between box and hovbox *) let%expect_test _ = let pp f = f (xs 50 ++ Pp.break ~nspaces:2 ~shift:(-1) ++ xs 10) in @@ -209,19 +213,6 @@ x x x x x x x x x x x x x x x x x x x x x x x x x |}] -let pp_pair ppf (a, b) = Format.fprintf ppf "(%i,@ %i)" a b - -let%expect_test _ = - print - (Pp.text "hello" ++ Pp.newline - ++ Pp.vbox (Pp.of_fmt pp_pair (1, 2)) - ++ Pp.space ++ Pp.text "foo"); - [%expect {| - hello - (1, - 2) - foo |}] - let%expect_test "comparison" = let x = error_example_1 and y = Pp.hovbox ~indent:2 (xs 200) in @@ -234,3 +225,109 @@ comparison result: -1 comparison result: 0 comparison result: 1 |}] + +(* The differnces between [Pp.paragraph], [Pp.text], [Pp.verbatim] and box + + [Pp.text] when inside a [Pp.vbox]. *) +let%expect_test "paragraph" = + let lorem = + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum \ + euismod, nisl eget aliquam ultricies." + in + let seperator text _ = + Pp.vbox + @@ Pp.seq Pp.space + (Pp.hbox + @@ Pp.textf "-< %s >-%s" text + (String.init (20 - String.length text) ~f:(fun _ -> '-'))) + in + print @@ Pp.vbox + @@ Pp.concat_map ~sep:Pp.space + ~f:(fun f -> f lorem) + [ seperator "verbatim" + ; Pp.verbatim + ; seperator "text" + ; Pp.text + ; seperator "paragraph" + ; Pp.paragraph + ; seperator "hovbox + text" + ; (fun x -> Pp.hovbox (Pp.text x)) + ; seperator "hvbox + text" + ; (fun x -> Pp.hvbox (Pp.text x)) + ; seperator "hbox + text" + ; (fun x -> Pp.hbox (Pp.text x)) + ; seperator "vbox + text" + ; (fun x -> Pp.vbox (Pp.text x)) + ; seperator "box + text" + ; (fun x -> Pp.box (Pp.text x)) + ]; + [%expect + {| + -< verbatim >------------- + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum euismod, nisl eget aliquam ultricies. + + -< text >----------------- + Lorem + ipsum + dolor + sit + amet, + consectetur + adipiscing + elit. + Vestibulum + euismod, + nisl + eget + aliquam + ultricies. + + -< paragraph >------------ + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum euismod, + nisl eget aliquam ultricies. + + -< hovbox + text >-------- + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum euismod, + nisl eget aliquam ultricies. + + -< hvbox + text >--------- + Lorem + ipsum + dolor + sit + amet, + consectetur + adipiscing + elit. + Vestibulum + euismod, + nisl + eget + aliquam + ultricies. + + -< hbox + text >---------- + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum euismod, nisl eget aliquam ultricies. + + -< vbox + text >---------- + Lorem + ipsum + dolor + sit + amet, + consectetur + adipiscing + elit. + Vestibulum + euismod, + nisl + eget + aliquam + ultricies. + + -< box + text >----------- + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum euismod, + nisl eget aliquam ultricies. |}] + +let%expect_test "paragraphf" = + print (Pp.paragraphf "Hello World%s" "!"); + [%expect {| Hello World! |}]