Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
prettypr(3)		   Erlang Module Definition		   prettypr(3)

       prettypr	- A generic pretty printer library.

       A  generic pretty printer library. This module uses a strict-style con-
       text passing implementation of John Hughes algorithm, described in "The
       design  of  a Pretty-printing Library". The paragraph-style formatting,
       empty documents,	floating documents, and	null strings are my own	 addi-
       tions to	the algorithm.

       To  get	started,  you  should read about the document()	data type; the
       main constructor	functions: text/1, above/2, beside/2,  nest/2,	sep/1,
       and par/2; and the main layout function format/3.

       If  you	simply	want to	format a paragraph of plain text, you probably
       want to use the text_par/2 function, as in the following	example:

	 prettypr:format(prettypr:text_par("Lorem ipsum	dolor sit amet"), 20)

	 deep_string() = [char() | deep_string()]:

	 document()  =	null  |	 #text{s=deep_string()}	 |  #nest{n=integer(),
	 d=document()}	   |	 #beside{d1=document(),	   d2=document()}    |
	 #above{d1=document(), d2=document()} |	#sep{ds=[document()],  i=inte-
	 ger(),	 p=boolean()} |	#float{d=document(), h=integer(), v=integer()}
	 | #union{d1=document(), d2=document()}	| #fit{d=document()}:

       above(D1::document(), D2::document()) ->	#above{d1=document(), d2=docu-

	      Concatenates documents vertically. Returns a document represent-
	      ing the concatenation of the documents D1	and D2 such  that  the
	      first line of D2 follows directly	below the last line of D1, and
	      the first	character of D2	is in the same	horizontal  column  as
	      the first	character of D1, in all	possible layouts.


		   ab  cd  =>  ab

		   abc	 fgh  =>   de
		    de	  ij	  fgh

       beside(D1::document(),	 D2::document())   ->	#beside{d1=document(),

	      Concatenates documents horizontally. Returns a  document	repre-
	      senting  the  concatenation of the documents D1 and D2 such that
	      the last character of D1 is horizontally adjacent	to  the	 first
	      character	of D2, in all possible layouts.	(Note: any indentation
	      of D2 is lost.)


		   ab  cd  =>  abcd

		   ab  ef      ab
		   cd  gh  =>  cdef

       best(D::document(), W::integer(), R::integer()) -> empty	| document()

	      Selects a	"best" layout for a document, creating a corresponding
	      fixed-layout  document. If no layout could be produced, the atom
	      empty is returned	instead.  For  details	about  PaperWidth  and
	      LineWidth, see format/3. The function is idempotent.

	      One  possible  use of this function is to	compute	a fixed	layout
	      for a document, which can	then be	included as part of  a	larger
	      document.	For example:

		   above(text("Example:"), nest(8, best(D, W - 12, L - 6)))

	      will  format  D as a displayed-text example indented by 8, whose
	      right margin is indented by 4 relative to	the paper width	 W  of
	      the  surrounding	document,  and	whose  maximum individual line
	      length is	shorter	by 6 than the line length L of the surrounding

	      This function is used by the format/3 function to	prepare	a doc-
	      ument before being laid out as text.

       break(D::document()) -> #above{d1=document(), d2=document()}

	      Forces a line break at the end of	the given document. This is  a
	      utility function;	see empty/0 for	details.

       empty() -> null

	      Yields  the  empty document, which has neither height nor	width.
	      (empty is	thus different from an empty text  string,  which  has
	      zero width but height 1.)

	      Empty  documents	are  occasionally  useful; in particular, they
	      have the property	that above(X, empty()) will force a  new  line
	      after  X without leaving an empty	line below it; since this is a
	      common idiom, the	utility	function break/1 will  place  a	 given
	      document in such a context.

	      See also:	text/1.

       floating(D::document())	->  #float{d=document(),  h=integer(), v=inte-

	      Equivalent to floating(D,	0, 0).

       floating(D::document(), H::integer(), V::integer())  ->	#float{d=docu-
       ment(), h=integer(), v=integer()}

	      Creates  a  "floating"  document.	The result represents the same
	      set of layouts as	D; however, a floating document	may  be	 moved
	      relative to other	floating documents immediately beside or above
	      it, according to their relative horizontal and vertical  priori-
	      ties. These priorities are set with the Hp and Vp	parameters; if
	      omitted, both default to zero.

	      Notes: Floating documents	appear to work well, but are currently
	      less general than	you might wish,	losing effect when embedded in
	      certain contexts.	It  is	possible  to  nest  floating-operators
	      (even  with different priorities), but the effects may be	diffi-
	      cult to predict. In any case, note that the  way	the  algorithm
	      reorders	floating documents amounts to a	"bubblesort", so don't
	      expect it	to be able to sort large sequences of  floating	 docu-
	      ments quickly.

       follow(D1::document(),	 D2::document())   ->	#beside{d1=document(),

	      Equivalent to follow(D1, D2, 0).

       follow(D1::document(), D2::document(), N::integer()) -> #beside{d1=doc-
       ument(),	d2=document()}

	      Separates	 two  documents	 by  either  a single space, or	a line
	      break and	intentation. In	other words, one of the	layouts

		   abc def



	      will be generated, using the optional offset in the latter case.
	      This  is	often useful for typesetting programming language con-

	      This is a	utility	function; see par/2 for	further	details.

	      See also:	follow/2.

       format(D::document()) ->	string()

	      Equivalent to format(D, 80).

       format(D::document(), W::integer()) -> string()

	      Equivalent to format(D, PaperWidth, 65).

       format(D::document(), W::integer(), R::integer()) -> string()

	      Computes a layout	for a document and returns  the	 corresponding
	      text.  See  document() for further information. Throws no_layout
	      if no layout could be selected.

	      PaperWidth specifies the total width (in character positions) of
	      the field	for which the text is to be laid out. LineWidth	speci-
	      fies the desired maximum width (in number	of characters) of  the
	      text printed on any single line, disregarding leading and	trail-
	      ing white	space. These parameters	need to	be  properly  balanced
	      in  order	 to produce good layouts. By default, PaperWidth is 80
	      and LineWidth is 65.

	      See also:	best/3.

       nest(N::integer(), D::document()) -> document()

	      Indents a	document a number of character positions to the	right.
	      Note  that  N may	be negative, shifting the text to the left, or
	      zero, in which case D is returned	unchanged.

       null_text(S::string()) -> #text{s=deep_string()}

	      Similar to text/1, but the result	 is  treated  as  having  zero
	      width.  This  is	regardless of the actual length	of the string.
	      Null text	is typically used for markup,  which  is  supposed  to
	      have no effect on	the actual layout.

	      The  standard  example is	when formatting	source code as HTML to
	      be placed	within _pre_..._/pre_ markup, and using	e.g.  _i_  and
	      _b_  to  make  parts of the source code stand out. In this case,
	      the markup does not add to the width of the text when viewed  in
	      an HTML browser, so the layout engine should simply pretend that
	      the markup has zero width.

	      See also:	empty/0, text/1.

       par(Ds::[document()])  ->  #sep{ds=[document()],	 i=integer(),  p=bool-

	      Equivalent to par(Ds, 0).

       par(Ds::[document()],  N::integer())  ->	 #sep{ds=[document()], i=inte-
       ger(), p=boolean()}

	      Arranges documents in a paragraph-like layout. Returns  a	 docu-
	      ment  representing all possible left-aligned paragraph-like lay-
	      outs of the (nonempty) sequence Docs of documents.  Elements  in
	      Docs  are	separated horizontally by a single space character and
	      vertically with a	single line break.  All	 lines	following  the
	      first  (if  any) are indented to the same	left column, whose in-
	      dentation	is specified by	the optional Offset parameter relative
	      to  the position of the first element in Docs. For example, with
	      an offset	of -4, the following layout can	 be  produced,	for  a
	      list of documents	representing the numbers 0 to 15:

		       0 1 2 3
		   4 5 6 7 8 9
		   10 11 12 13
		   14 15

	      or with an offset	of +2:

		   0 1 2 3 4 5 6
		     7 8 9 10 11
		     12	13 14 15

	      The  utility function text_par/2 can be used to easily transform
	      a	string of text into a par representation by splitting it  into

	      Note  that whenever a document in	Docs contains a	line break, it
	      will be placed on	a separate line. Thus, neither a  layout  such

		   ab cd


		   cd ef

	      will be generated. However, a useful idiom for making the	former
	      variant possible (when wanted) is	beside(par([D1,	text("")], N),
	      D2)  for	two  documents D1 and D2. This will break the line be-
	      tween D1 and D2 if D1 contains a line  break  (or	 if  otherwise
	      necessary),  and optionally further indent D2 by N character po-
	      sitions. The utility function follow/3 creates this context  for
	      two documents D1 and D2, and an optional integer N.

	      See also:	par/1, text_par/2.

       sep(Ds::[document()])  ->  #sep{ds=[document()],	 i=integer(),  p=bool-

	      Arranges documents  horizontally	or  vertically,	 separated  by
	      whitespace. Returns a document representing two alternative lay-
	      outs of the (nonempty) sequence Docs of documents, such that ei-
	      ther  all	 elements  in  Docs are	concatenated horizontally, and
	      separated	by a space character, or all elements are concatenated
	      vertically (without extra	separation).

	      Note: If some document in	Docs contains a	line break, the	verti-
	      cal layout will always be	selected.


		   ab  cd  ef  =>  ab cd ef  |	cd

		   ab		ab
		   cd  ef  =>	cd

	      See also:	par/2.

       text(S::string()) -> #text{s=deep_string()}

	      Yields a document	representing a fixed, unbreakable sequence  of
	      characters.  The string should contain only printable characters
	      (tabs allowed but	not recommended), and not newline, line	 feed,
	      vertical	tab,  etc. A tab character (\t)	is interpreted as pad-
	      ding of 1-8 space	characters to the next column of 8  characters
	      within the string.

	      See also:	empty/0, null_text/1, text_par/2.

       text_par(S::string()) ->	document()

	      Equivalent to text_par(Text, 0).

       text_par(S::string(), N::integer()) -> document()

	      Yields  a	 document representing paragraph-formatted plain text.
	      The optional Indentation parameter specifies the extra  indenta-
	      tion   of	  the  first  line  of	the  paragraph.	 For  example,
	      text_par("Lorem ipsum dolor sit amet", N)	could represent

		   Lorem ipsum dolor
		   sit amet

	      if N = 0,	or

		     Lorem ipsum
		   dolor sit amet

	      if N = 2,	or

		   Lorem ipsum dolor
		     sit amet

	      if N = -2.

	      (The sign	of the indentation is thus reversed  compared  to  the
	      par/2  function,	and the	behaviour varies slightly depending on
	      the sign in order	to match the expected layout of	a paragraph of

	      Note  that  this	is just	a utility function, which does all the
	      work of splitting	the  given  string  into  words	 separated  by
	      whitespace  and  setting	up  a par with the proper indentation,
	      containing a list	of text	elements.

	      See also:	par/2, text/1, text_par/1.

       Richard Carlsson	_carlsson.richard@gmail.com_

			       syntax_tools 2.6			   prettypr(3)


Want to link to this manual page? Use this URL:

home | help