PreviousUpNext

15.4.836  src/lib/prettyprint/big/src/out/html-prettyprint-output-stream.pkg

## html-prettyprint-output-stream.pkg
#
# Prettyprinting using HTML markup to control layout.
# Supplying this package as an argument to
#
#     src/lib/prettyprint/big/src/base-prettyprinter-g.pkg
#
# yields a prettyprinter specialized to format HTML text.
#
# For an overview of prettyprinter output stream functionality see
#
#     src/lib/prettyprint/big/src/out/prettyprint-output-stream.api
#
# Compare to:
#
#     src/lib/prettyprint/big/src/out/plain-prettyprint-output-stream.pkg
#     src/lib/prettyprint/big/src/out/ansi-terminal-prettyprint-output-stream.pkg
#
# This file is currently referenced nowhere.

# Compiled by:
#     src/lib/prettyprint/big/prettyprinter.lib

stipulate
    package has =  html_abstract_syntax;                                # html_abstract_syntax                          is from   src/lib/html/html-abstract-syntax.pkg
herein

    api Html_Prettyprint_Output_Stream {
        #
        include api Prettyprint_Output_Stream;                          # Prettyprint_Output_Stream                     is from   src/lib/prettyprint/big/src/out/prettyprint-output-stream.api

        combine_textstyles:  (Texttraits, Texttraits) -> Texttraits;    # Combine two textstyles into one.

        textstyle_none:  Texttraits;                                    # Unstyled text.

        # Standard HTML text styles:
        #
        textstyle_tt:      Texttraits;
        textstyle_i:       Texttraits;
        textstyle_b:       Texttraits;
        textstyle_u:       Texttraits;
        textstyle_strike:  Texttraits;
        textstyle_em:      Texttraits;
        textstyle_strong:  Texttraits;
        textstyle_dfn:     Texttraits;
        textstyle_code:    Texttraits;
        textstyle_samp:    Texttraits;
        textstyle_kbd:     Texttraits;
        textstyle_var:     Texttraits;
        textstyle_cite:    Texttraits;

        color:  String -> Texttraits;                                   # Color text (using FONT element).

        # Hyper-text links and anchors:
        #
        link:    String -> Texttraits;
        anchor:  String -> Texttraits;
        link_anchor:  { name:  String, href:  String } -> Texttraits;

        make_markup_buffer:  { text_wide:  Null_Or( Int ) } -> Prettyprint_Output_Stream;

        done:  Prettyprint_Output_Stream -> has::Text;
    };


    package   html_prettyprint_output_stream
    : (weak)  Html_Prettyprint_Output_Stream
    {
        Texttraits
          = NOEMPH
          | TT
          | II
          | BB
          | UU
          | STRIKE
          | EM
          | STRONG
          | DFN
          | CODE
          | SAMP
          | KBD
          | VAR
          | CITE
          | COLOR  String
          | AA  { href:  Null_Or(String),
                  name:  Null_Or(String)
                }
          | STYS  List(Texttraits)
          ;

        Prettyprint_Output_Stream
      = PRETTYPRINT_OUTPUT_STREAM
              { text_wide:      Null_Or( Int ),
                emph_stk:       Ref( List( (List(has::Text), Texttraits) ) ) ,
                txt:            Ref( List(  has::Text ) )
              };

        fun cur_emph (PRETTYPRINT_OUTPUT_STREAM { emph_stk, ... } )                                             # Return the current emphasis.
            =
            case *emph_stk
                  []           => NOEMPH;
                 ((_, em) ! r) => em;
            esac;


        fun pcdata (PRETTYPRINT_OUTPUT_STREAM { txt, ... }, s)                                          # Add PCDATA to the text list.
            =
            txt := has::PCDATA s ! *txt;

        fun join_txt (PRETTYPRINT_OUTPUT_STREAM { txt, ... } )                                          # Replace the sequence of PCDATA elements at the head of the txt list with its concatenation.
            =
            f (*txt, [])
            where
                fun f ([], []) => [];
                    f (has::PCDATA s ! r, l) => f (r, s ! l);
                    f (r, l) => has::PCDATA (string::cat l) ! r;
                end;
            end;

        fun same_texttraits (s1:  Texttraits, s2)                                                       # Are two textstyles the same? 
            =
            s1 == s2;


        fun wrap_textstyle (sty, [], tl')
                =>
                tl';

            wrap_textstyle (sty, tl, tl')
                =>
                wrap (sty, t) ! tl'
                where
                    fun wrap (NOEMPH,  t) => t;
                        wrap (TT,      t) => has::TT t;
                        wrap (II,      t) => has::IX t;
                        wrap (BB,      t) => has::BX t;
                        wrap (UU,      t) => has::UX t;
                        wrap (STRIKE,  t) => has::STRIKE t;
                        wrap (EM,      t) => has::EM t;
                        wrap (STRONG,  t) => has::STRONG t;
                        wrap (DFN,     t) => has::DFN t;
                        wrap (CODE,    t) => has::CODE t;
                        wrap (SAMP,    t) => has::SAMP t;
                        wrap (KBD,     t) => has::KBD t;
                        wrap (VAR,     t) => has::VAR t;
                        wrap (CITE,    t) => has::CITE t;
                        wrap (COLOR c, t) => has::FONT { color=>THE c, size=>NULL, content=>t };
                        #       
                        wrap (AA { name, href }, t)
                            =>
                            has::AX {
                             name, href,
                             rel => NULL, reverse => NULL, title => NULL,
                             content => t
                           };

                        wrap (STYS l, t) => list::fold_backward wrap t l;
                    end;

                    t =   case tl
                              [t] => t;
                              _   => has::TEXT_LIST (list::reverse tl);
                          esac;
                end;
        end;

        fun push_texttraits (dev as PRETTYPRINT_OUTPUT_STREAM { emph_stk, txt, ... }, sty)                                      # Push a textstyle onto the markup_buffers textstyle stack.
            =
            {   emph_stk :=  (join_txt dev, sty) ! *emph_stk;
                txt      :=  [];
            };

        fun pop_texttraits (PRETTYPRINT_OUTPUT_STREAM { emph_stk as REF [], ... } )                                             # Pop a textstyle off the markup_buffers textstyle stack. A pop on an empty textstyle stack is a no-op.
                =>
                ();

            pop_texttraits (dev as PRETTYPRINT_OUTPUT_STREAM { emph_stk as REF ((tl, sty) ! r), txt, ... } )
                =>
                {   txt := wrap_textstyle (sty, join_txt dev, tl);
                    emph_stk := r;
                };
        end;


        fun default_texttraits _                                                                                # The default textstyle for the markup_buffer. This is the current textstyle if the textstyle stack is empty.
            =
            NOEMPH;

        put_string = pcdata;                                                                                    # Write a string in the current textstyle to the output stream.
# THE put_string FN SHOULD CONVERT BLANKS to ' ' STRINGS.                                                  XXX BUGGO FIXME
# THE put_string FN SHOULD CONVERT NEWLINES to   txt := has::BR { clear=>NULL } ! (join_txt dev);               XXX BUGGO FIXME

        fun flush _ = ();
        fun close _ = ();

        fun combine_textstyles (NOEMPH, sty)      =>  sty;
            combine_textstyles (sty, NOEMPH)      =>  sty;
            combine_textstyles (STYS l1, STYS l2) =>  STYS (l1 @ l2);
            combine_textstyles (sty, STYS l)      =>  STYS (sty ! l);
            combine_textstyles (sty1, sty2)       =>  STYS [sty1, sty2];
        end;

        textstyle_none = NOEMPH;
        textstyle_tt = TT;
        textstyle_i = II;
        textstyle_b = BB;
        textstyle_u = UU;
        textstyle_strike = STRIKE;
        textstyle_em = EM;
        textstyle_strong = STRONG;
        textstyle_dfn = DFN;
        textstyle_code = CODE;
        textstyle_samp = SAMP;
        textstyle_kbd = KBD;
        textstyle_var = VAR;
        textstyle_cite = CITE;
        color = COLOR;

        fun link   s = AA { href=>THE s, name=>NULL  };
        fun anchor s = AA { href=>NULL,  name=>THE s };

        fun link_anchor { name, href }
            =
            AA { href=>THE href, name => THE name };

        fun make_markup_buffer { text_wide }
            =
            PRETTYPRINT_OUTPUT_STREAM
              { txt      => REF [],
                emph_stk => REF [],
                text_wide
              };

        fun done (mb as PRETTYPRINT_OUTPUT_STREAM { emph_stk => REF [], txt, ... } )
                =>
                case (join_txt mb)
                    #              
                    [t] =>   { txt := [];   t; };
                    l   =>   { txt := [];   has::TEXT_LIST (list::reverse l); };
                esac;

            done _ =>  raise exception DIE "Unclosed boxes in markup_buffer -- cannot format it.";
        end;

    };  #  html_prettyprint_output_stream.pkg 
end;


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext