login  home  contents  what's new  discussion  bug reports     help  links  subscribe  changes  refresh  edit

Edit detail for TexFormat1 revision 1 of 1

1
Editor: pagani
Time: 2020/02/27 21:00:30 GMT+0
Note:

changed:
-
\begin{spad}
)abbrev domain TEX TexFormat
++ Author: Robert S. Sutor
++ Date Created: 1987 through 1992
++ Basic Operations: coerce, convert, display, epilogue,
++   tex, new, prologue, setEpilogue!, setTex!, setPrologue!
++ Related Constructors: TexFormat1
++ Also See: ScriptFormulaFormat
++ AMS Classifications:
++ Keywords: TeX, LaTeX, output, format
++ References: \TeX{} is a trademark of the American Mathematical Society.
++ Description:
++   \spadtype{TexFormat} provides a coercion from \spadtype{OutputForm} to
++   \TeX{} format.  The particular dialect of \TeX{} used is \LaTeX{}.
++   The basic object consists of three parts: a prologue, a
++   tex part and an epilogue. The functions \spadfun{prologue},
++   \spadfun{tex} and \spadfun{epilogue} extract these parts,
++   respectively.  The main guts of the expression go into the tex part.
++   The other parts can be set (\spadfun{setPrologue!},
++   \spadfun{setEpilogue!}) so that contain the appropriate tags for
++   printing. For example, the prologue and epilogue might simply
++   contain ``\verb+\[+'' and ``\verb+\]+'', respectively, so that
++   the TeX section will be printed in LaTeX display math mode.
++ Revision:
++   25-FEB-2020 ... op PRIME (line 356), Greek characters x% (565 ff.)
++
TexFormat() : public == private where
  E      ==> OutputForm
  I      ==> Integer
  L      ==> List
  S      ==> String
  Sy     ==> Symbol
  US     ==> UniversalSegment(Integer)

  public == SetCategory with
    coerce :   E -> %
      ++ coerce(o) changes o in the standard output format to TeX
      ++ format.
    convert :  (E, I) -> %
      ++ convert(o, step) changes o in standard output format to
      ++ TeX format and also adds the given step number. This is useful
      ++ if you want to create equations with given numbers or have the
      ++ equation numbers correspond to the interpreter step numbers.
    convert :  (E, I, E) -> %
      ++ convert(o, step, type) changes o in standard output format to
      ++ TeX format and also adds the given step number and type. This
      ++ is useful if you want to create equations with given numbers
      ++ or have the equation numbers correspond to the interpreter step
      ++ numbers.
    display :  (%, I) -> Void
      ++ display(t, width) outputs the TeX formatted code t so that each
      ++ line has length less than or equal to \spadvar{width}.
    display :  % -> Void
      ++ display(t) outputs the TeX formatted code t so that each
      ++ line has length less than or equal to the value set by
      ++ the system command \spadsyscom{set output length}.
    epilogue : % -> L S
      ++ epilogue(t) extracts the epilogue section of a TeX form t.
    tex :      % -> L S
      ++ tex(t) extracts the TeX section of a TeX form t.
    new :      () -> %
      ++ new() create a new, empty object. Use \spadfun{setPrologue!},
      ++ \spadfun{setTex!} and \spadfun{setEpilogue!} to set the various
      ++ components of this object.
    prologue : % -> L S
      ++ prologue(t) extracts the prologue section of a TeX form t.
    setEpilogue! : (%, L S) -> L S
      ++ setEpilogue!(t, strings) sets the epilogue section of a TeX form t to strings.
    setTex! :  (%, L S) -> L S
      ++ setTex!(t, strings) sets the TeX section of a TeX form t to strings.
    setPrologue! : (%, L S) -> L S
      ++ setPrologue!(t, strings) sets the prologue section of a TeX form t to strings.

  private == add
    import from OutputForm
    import from Character
    import from Integer
    import from List OutputForm
    import from List String
    import from OutputFormTools

    Rep := Record(prolog : L S, TeX : L S, epilog : L S)

    -- local variable declarations and definitions

    expr : E
    prec, opPrec : I
    str :  S
    blank         : S := " \  "

    maxPrec       : I   := 1000000
    minPrec       : I   := 0

    unaryOps      : L Sy := ["-"::Sy]$(L Sy)
    unaryPrecs    : L I := [710]$(L I)

    -- the precedence of / in the following is relatively low because
    -- the bar obviates the need for parentheses.
    binaryOps     : L Sy := ["+->"::Sy, "|"::Sy, "^"::Sy, "/"::Sy, "="::Sy,
                             "~="::Sy, "<"::Sy, "<="::Sy, ">"::Sy, ">="::Sy,
                               'OVER, 'LET]
    binaryPrecs   : L I := [0, 0, 900, 700, 400,
                            400, 400, 400, 400, 400,
                              700, 125]$(L I)

    naryOps       : L Sy := ["-"::Sy, "+"::Sy, "*"::Sy, ","::Sy, ";"::Sy,
                             'ROW, 'STRSEP, 'TENSOR]
    naryPrecs     : L I := [700, 700, 800, 110, 110,
                            0, 0, 850]$(L I)
    naryNGOps     : L Sy := ['ROW]

    plexOps       : L Sy := ['SIGMA, 'SIGMA2, 'PI, 'PI2, 'INTSIGN]
    plexPrecs     : L I := [ 750, 750, 750, 750, 700]$(L I)

    specialOps    : L Sy := ['MATRIX, 'BRACKET, 'BRACE, 'CONCATB, 'VCONCAT,  _
                             'AGGLST, 'CONCAT, 'OVERBAR, 'ROOT, 'SUB, 'TAG, _
                             'SUPERSUB, 'ZAG, 'AGGSET, 'SC, 'PAREN, _
                             'SEGMENT, 'QUOTE, 'theMap, 'SLASH, 'PRIME]

    -- the next two lists provide translations for some strings for
    -- which TeX provides special macros.

    specialStrings : L Sy :=
      ['cos, 'cot, 'csc, 'log, 'sec, 'sin, 'tan,
        'cosh, 'coth, 'csch, 'sech, 'sinh, 'tanh,
          'acos, 'asin, 'atan, 'erf, "..."::Sy, "$"::Sy, 'infinity,
            'Gamma]

    specialStringsInTeX : L S :=
      ["\cos","\cot","\csc","\log","\sec","\sin","\tan",
        "\cosh","\coth","\csch","\sech","\sinh","\tanh",
          "\arccos","\arcsin","\arctan","\erf","\ldots","\$","\infty",
            "\Gamma"]

    -- local function signatures

    addBraces :      S -> S
    addBrackets :    S -> S
    group :          S -> S
    formatBinary :   (Sy, L E, I) -> S
    formatFunction : (E, L E, I) -> S
    formatMatrix :   L E -> S
    formatNary :     (Sy, S, I, L E, I) -> S
    formatNaryNoGroup : (Sy, S, I, L E, I) -> S
    formatNullary :  Sy -> S
    formatPlex :     (Sy, L E, I) -> S
    formatSpecial :  (Sy, L E, I) -> S
    formatUnary :    (Sy, E, I) -> S
    formatExpr :      (E, I) -> S
    newWithNum :     I -> %
    parenthesize :   S -> S
    postcondition :  S -> S
    splitLong :      (S, I) -> L S
    splitLong1 :     (S, I) -> L S
    stringify :      E -> S
    ungroup :        S -> S

    -- public function definitions

    new() : % ==
--    [["\["]$(L S), [""]$(L S), ["\]"]$(L S)]$Rep
      [["$$"]$(L S), [""]$(L S), ["$$"]$(L S)]$Rep

    newWithNum(stepNum : I) : % ==
--    num : S := concat("%FRICAS STEP NUMBER: ",string(stepNum)$S)
--    [["\["]$(L S), [""]$(L S), ["\]",num]$(L S)]$Rep
      num : S := concat(concat("\leqno(",string(stepNum)$S),")")$S
      [["$$"]$(L S), [""]$(L S), [num,"$$"]$(L S)]$Rep

    coerce(expr : E) : % ==
      f : % := new()$%
      f.TeX := [postcondition
          formatExpr(precondition expr, minPrec)]$(L S)
      f

    convert(expr : E, stepNum : I) : % ==
      f : % := newWithNum(stepNum)
      f.TeX := [postcondition
          formatExpr(precondition expr, minPrec)]$(L S)
      f

    sayExpr(s : S) : Void ==
        sayTeX$Lisp s

    display(f : %, len : I) ==
      s, t : S
      for s in f.prolog repeat sayExpr s
      for s in f.TeX repeat
        for t in splitLong(s, len) repeat sayExpr t
      for s in f.epilog repeat sayExpr s
      void()$Void

    display(f : %) ==
      display(f, _$LINELENGTH$Lisp pretend I)

    prologue(f : %) == f.prolog
    tex(f : %)  == f.TeX
    epilogue(f : %) == f.epilog

    setPrologue!(f : %, l : L S) == f.prolog := l
    setTex!(f : %, l : L S)  == f.TeX := l
    setEpilogue!(f : %, l : L S) == f.epilog := l

    coerce(f : %) : E ==
      s, t : S
      l : L S := []
      for s in f.prolog repeat l := concat(s, l)
      for s in f.TeX repeat
        for t in splitLong(s, (_$LINELENGTH$Lisp pretend Integer) - 4) repeat
          l := concat(t, l)
      for s in f.epilog repeat l := concat(s, l)
      (reverse l) :: E

    -- local function definitions

    ungroup(str : S) : S ==
      len : I := #str
      len < 2 => str
      lbrace : Character := char "{"
      rbrace : Character := char "}"
      -- drop leading and trailing braces
      if (str.1 =$Character lbrace) and (str.len =$Character rbrace) then
        u : US := segment(2, len-1)$US
        str := str.u
      str

    postcondition(str : S) : S ==
      str := ungroup str
      len : I := #str
      plus : Character := char "+"
      minus : Character := char "-"
      len < 4 => str
      for i in 1..(len-1) repeat
        if (str.i =$Character plus) and (str.(i+1) =$Character minus)
          then setelt!(str, i, char " ")$S
      str

    stringify expr == (mathObject2String$Lisp expr) pretend S

    lineConcat( line : S, lines : L S ) : L S ==
      length := #line

      if ( length > 0 ) then
        -- If the last character is a backslash then split at "\ ".
        -- Reinstate the blank.

        if (line.length = char "\" ) then line := concat(line, " ")

        -- Remark: for some reason, "\%" at the beginning
        -- of a line has the "\" erased when printed

        if ( line.1 = char "%" ) then line := concat(" \", line)
        else if ( line.1 = char "\" ) and length > 1 and ( line.2 = char "%" ) then
          line := concat(" ", line)

        lines := concat(line, lines)$List(S)
      lines

    splitLong(str : S, len : I) : L S ==
      -- this blocks into lines
      if len < 20 then len := _$LINELENGTH$Lisp
      splitLong1(str, len)

    splitLong1(str : S, len : I) ==
      -- We first build the list of lines backwards and then we
      -- reverse it.

      l : List S := []
      s : S := ""
      ls : I := 0
      ss : S
      lss : I
      for ss in split(str,char " ") repeat
        -- have the newline macro end a line (even if it means the line
        -- is slightly too long)

        ss = "\\" =>
          l := lineConcat( concat(s, ss), l )
          s := ""
          ls := 0

        lss := #ss

        -- place certain tokens on their own lines for clarity

        ownLine : Boolean :=
          u : US := segment(1, 4)$US
          (lss > 3) and ("\end" = ss.u) => true
          u      := segment(1, 5)$US
          (lss > 4) and ("\left" = ss.u) => true
          u      := segment(1, 6)$US
          (lss > 5) and (("\right" = ss.u) or ("\begin" = ss.u)) => true
          false

        if ownLine or (ls + lss > len) then
          if not empty? s then l := lineConcat( s, l )
          s := ""
          ls := 0

        ownLine or lss > len => l := lineConcat( ss, l )

        (lss = 1) and (ss.1 = char "\") =>
          ls := ls + lss + 2
          s := concat(s,concat(ss,"  ")$S)$S

        ls := ls + lss + 1
        s := concat(s,concat(ss," ")$S)$S

      if ls > 0 then l := lineConcat( s, l )

      reverse l

    group str ==
      concat ["{",str,"}"]

    addBraces str ==
      concat ["\left\{ ",str," \right\}"]

    addBrackets str ==
      concat ["\left[ ",str," \right]"]

    parenthesize str ==
      concat ["\left( ",str," \right)"]

    formatSpecial(op : Sy, args : L E, prec : I) : S ==
        arg : E
        prescript : Boolean := false
        op = 'theMap => "\mbox{theMap(...)}"
        op = 'AGGLST =>
            formatNary(","::Sy, "", 0, args, prec)
        op = 'AGGSET =>
            formatNary(";"::Sy, "", 0, args, prec)
        op = 'TAG =>
            group concat [formatExpr(first args, prec),
                          "\rightarrow",
                            formatExpr(second args, prec)]
        op = 'SLASH =>
            group concat [formatExpr(first args, prec),
                          "/", formatExpr(second args, prec)]
        op = 'VCONCAT =>
            group concat("\begin{array}{c}",
                         concat(concat([concat(formatExpr(u, minPrec), "\\")
                                    for u in args]::L S),
                            "\end{array}"))
        op = 'CONCATB =>
            formatNary('STRSEP, " \ ", 0, args, prec)
        op = 'CONCAT =>
            formatNary('STRSEP, "", 0, args, minPrec)
        op = 'QUOTE =>
            group concat("{\tt '}", formatExpr(first args, minPrec))
        op = 'BRACKET =>
            group addBrackets ungroup formatExpr(first args, minPrec)
        op = 'BRACE =>
            group addBraces ungroup formatExpr(first args, minPrec)
        op = 'PAREN =>
            group parenthesize ungroup formatExpr(first args, minPrec)
        op = 'PRIME =>
            p:=convert(second args)$E
            not atom? p => formatSpecial('SUPERSUB, [first args, hspace(1)$E, second args], prec) 
            string p=","   => group concat [formatExpr(first args, minPrec),"'"]
            string p=",,"  => group concat [formatExpr(first args, minPrec),"''"]
            string p=",,," => group concat [formatExpr(first args, minPrec),"'''"]           
        op = 'OVERBAR =>
            empty?(args) => ""
            group concat ["\overline ", formatExpr(first args, minPrec)]
        op = 'ROOT =>
            empty?(args) => ""
            tmp : S := group formatExpr(first args, minPrec)
            empty?(rest(args)) => group concat ["\sqrt ",tmp]
            group concat
                ["\root ", group formatExpr(first rest args, minPrec),
                   " \of ", tmp]
        op = 'SEGMENT =>
            tmp : S := concat [formatExpr(first args, minPrec), ".."]
            group
                empty?(rest(args)) =>  tmp
                concat [tmp, formatExpr(first rest args, minPrec)]
        op = 'SUB =>
            group concat [formatExpr(first args, minPrec), " \sb ",
                formatSpecial('AGGLST, rest args, minPrec)]
        op = 'SUPERSUB =>
            -- variable name
            form : List S := [formatExpr(first args, minPrec)]
            -- subscripts
            args := rest args
            empty?(args) => concat(form)$S
            tmp : S := formatExpr(first args, minPrec)
            if (tmp ~= "") and (tmp ~= "{}") and (tmp ~= " ") then
                form := append(form,[" \sb ",group tmp])$(List S)
            -- superscripts
            args := rest args
            empty?(args) => group concat(form)$S
            tmp : S := formatExpr(first args, minPrec)
            if (tmp ~= "") and (tmp ~= "{}") and (tmp ~= " ") then
                form := append(form,[" \sp ",group tmp])$(List S)
            -- presuperscripts
            args := rest args
            empty?(args) => group concat(form)$S
            tmp : S := formatExpr(first args, minPrec)
            if (tmp ~= "") and (tmp ~= "{}") and (tmp ~= " ") then
                form := append([" \sp ",group tmp],form)$(List S)
                prescript := true
            -- presubscripts
            args := rest args
            empty?(args) =>
                group concat
                    prescript => cons("{}",form)
                    form
            tmp : S := formatExpr(first args, minPrec)
            if (tmp ~= "") and (tmp ~= "{}") and (tmp ~= " ") then
                form := append([" \sb ",group tmp],form)$(List S)
                prescript := true
            group concat
                prescript => cons("{}",form)
                form
        op = 'SC =>
            -- need to handle indentation someday
            empty?(args) => ""
            tmp := formatNaryNoGroup('STRSEP, " \\ ", 800, args, minPrec)
            -- error "SC unhandled"
            group concat ["\begin{array}{l} ",tmp," \end{array} "]
        op = 'MATRIX => formatMatrix rest args
        op = 'ZAG =>
            concat [" \zag{", formatExpr(first args, minPrec), "}{",
                formatExpr(first rest args, minPrec), "}"]
        concat ["not done yet for ", string(op)]

    formatPlex(op : Sy, args : L E, prec : I) : S ==
        hold : S
        p : I := position(op, plexOps)
        p < 1 => error "unknown plex op"
        opPrec := plexPrecs.p
        n : I := #args
        (n ~= 2) and (n ~= 3) => error "wrong number of arguments for plex"
        s : S :=
            op = 'SIGMA   => "\sum"
            op = 'SIGMA2   => "\sum"
            op = 'PI      => "\prod"
            op = 'PI2     => "\prod"
            op = 'INTSIGN => "\int"
            "????"
        hold := formatExpr(first args, minPrec)
        args := rest args
        if hold ~= "" then
            s := concat [s, " \sb", group concat ["\displaystyle ", hold]]
        if not(empty?(rest(args))) then
            hold := formatExpr(first args, minPrec)
            if hold ~= "" then
                s := concat [s, " \sp",
                             group concat ["\displaystyle ", hold]]
            args := rest args
        s := concat [s, " ", formatExpr(first args, opPrec)]
        if opPrec < prec then s := parenthesize s
        group s

    formatMatrix(args : L E) : S ==
      -- format for args is [[ROW ...], [ROW ...], [ROW ...]]
      -- generate string for formatting columns (centered)
      cols : S := "{"
      for i in 1..#arguments(first(args)) repeat
        cols := concat(cols,"c")
      cols := concat(cols,"} ")
      group addBrackets concat
        ["\begin{array}", cols,
          formatNaryNoGroup('STRSEP, " \\ ", 0, args, minPrec),
            " \end{array} "]

    formatFunction(op : E, args : L E, prec : I) : S ==
        ops := formatExpr(op, minPrec)
        group concat [ops, " ", parenthesize
                      formatNary(","::Sy, "", 0, args, minPrec)]

    formatNullary(op : Sy) ==
        op = 'NOTHING => ""
        group concat [string(op), "()"]

    formatUnary(op : Sy, arg : E, prec : I) ==
        p : I := position(op, unaryOps)
        p < 1 => error "unknown unary op"
        opPrec := unaryPrecs.p
        s : S := concat [string(op), formatExpr(arg, opPrec)]
        opPrec < prec => group parenthesize s
        op = "-"::Sy => s
        group s

    formatBinary(op : Sy, args : L E, prec : I) : S ==
        p : I := position(op, binaryOps)
        p < 1 => error "unknown binary op"
        opPrec := binaryPrecs.p
        s1 := formatExpr(first args, opPrec)
        s2 := formatExpr(first rest args, (op = "^"::Sy => minPrec ; opPrec))
        ops : S :=
            op = "|"::Sy     => " \mid "
            op = "^"::Sy    => " \sp "
            op = "/"::Sy     => " \over "
            op = 'OVER  => " \over "
            op = "+->"::Sy   => " \mapsto "
            op = "~="::Sy => " \ne "
            op = "<="::Sy => " \leq "
            op = ">="::Sy => " \geq "
            -- FIXME how to do this properly ???
            op = 'LET   => " := "
            string(op)
        s :=
            op = "^"::Sy => concat [group(s1), ops, group(s2)]
            concat [s1, ops, s2]
        group
            op = "/"::Sy or op = 'OVER => s
            opPrec < prec => parenthesize s
            s

    formatNary(op : Sy, sep : S, opprec : I, args : L E, prec : I) : S ==
        group formatNaryNoGroup(op, sep, opprec, args, prec)

    formatNaryNoGroup(op : Sy, sep : S, opprec : I, args : L E, prec : I) : S ==
        empty?(args) => ""
        p : I := position(op, naryOps)
        p < 1 => error "unknown nary op"
        ops : S :=
            op = 'STRSEP => sep
            op = ","::Sy     => ", \: "
            op = ";"::Sy     => "; \: "
            op = "*"::Sy     => blank
            op = '_     => " \ "
            op = 'ROW   => " & "
            op = 'TENSOR => " \otimes "
            string(op)
        l : L S := []
        opPrec :=
            op = 'STRSEP => opprec
            naryPrecs.p
        for a in args repeat
            l := concat(ops, concat(formatExpr(a, opPrec), l)$L(S))$L(S)
        s : S := concat reverse rest l
        opPrec < prec => parenthesize s
        s

    formatExpr(expr : E, prec : I) : S ==
      i, len : Integer
      intSplitLen : Integer := 20
      str, s : S
      atom?(expr) =>
        str := stringify expr
        len := #str
        integer?(expr) =>
          i := integer(expr)
          if (i < 0) or (i > 9)
            then
              group
                 nstr : String := ""
                 -- insert some blanks into the string, if too long
                 while ((len := #str) > intSplitLen) repeat
                   nstr := concat [nstr, " ",
                     elt(str, segment(1, intSplitLen)$US)]
                   str := elt(str, segment(intSplitLen + 1)$US)
                 empty? nstr => str
                 nstr :=
                   empty? str => nstr
                   concat [nstr, " ", str]
                 elt(nstr, segment(2)$US)
            else str
        str = "%pi" => "\pi"
        str = "%e"  => "e"
        str = "%i"  => "i"
        --
        -- https://en.wikipedia.org/wiki/Greek_alphabet
        -- Traditional Latin transliteration
        --
        str = "a%" => "\alpha"
        str = "b%" => "\beta"
        str = "g%" => "\gamma"
        str = "d%" => "\delta"
        str = "e%" => "\epsilon"
        str = "z%" => "\zeta"
        str = "ee%" => "\eta"
        str = "th%" => "\theta"
        str = "i%" => "\iota"
        str = "k%" => "\kappa"
        str = "l%" => "\lambda"
        str = "m%" => "\mu"
        str = "n%" => "\nu"
        str = "x%" => "\xi"
        --str = "o%" => "\omicron"
        str = "p%" => "\pi"
        str = "r%" => "\rho"
        str = "s%" => "\sigma"
        str = "t%" => "\tau"
        str = "y%" => "\upsilon"
        str = "ph%" => "\phi"
        str = "ch%" => "\chi"
        str = "ps%" => "\psi"
        str = "oo%" => "\omega"
        str = "G%" => "\Gamma"
        str = "D%" => "\Delta"
        str = "Th%" => "\Theta"
        str = "L%" => "\Lambda"
        str = "X%" => "\Xi"
        str = "P%" => "\Pi"
        str = "S%" => "\Sigma"
        str = "Ph%" => "\Phi"
        --str = "Ch%" => "\Chi"
        str = "Ps%" => "\Psi"
        str = "OO%" => "\Omega"
        str = "hbar%" => "\hbar"
        --
        len > 1 and str.1 = char "%" and str.2 = char "%" =>
          u : US := segment(3, len)$US
          concat(" \%\%", str.u)
        len > 0 and str.1 = char "%" => concat(" \", str)
        len > 0 and str.1 = char "_"" =>
          s := "\verb#"
          for i in 1..len repeat
            if str.i = char "#" then
              s := concat(s, "#\verb-#-\verb#")
            else
              s := concat(s, (str.i)::S)
          concat(s, "#")
        len = 1 and str.1 = char " " => "{\ }"
        -- escape the underscore character
        s := ""
        for i in 1..len repeat
            s := concat(s, (if str.i = char "__" then "\__" else (str.i)::S))
        str := s
        len > 1 and digit? str.1 => group str -- should handle floats
        if symbol?(expr) then
            op := symbol(expr)
            (i := position(op, specialStrings)) > 0 =>
                str := specialStringsInTeX.i
        (i := position(char " ", str)) > 0 =>
          -- We want to preserve spacing, so use a roman font.
          concat [" \mbox{\rm ", str, "} "]
        str
      opf : E := operator(expr)
      args : L E := arguments(expr)
      nargs : I := #args

      symbol?(opf) =>
          op := symbol(opf)
          -- special cases
          member?(op, specialOps) => formatSpecial(op, args, prec)
          member?(op, plexOps)    => formatPlex(op, args, prec)

          -- nullary case
          0 = nargs => formatNullary op

          -- unary case
          (1 = nargs) and member?(op, unaryOps) =>
            formatUnary(op, first args, prec)

          -- binary case
          (2 = nargs) and member?(op, binaryOps) =>
            formatBinary(op, args, prec)

          -- nary case
          member?(op, naryNGOps) => formatNaryNoGroup(op, "", 0, args, prec)
          member?(op, naryOps) => formatNary(op, "", 0, args, prec)
          formatFunction(opf, args, prec)
      formatFunction(opf, args, prec)

)abbrev package TEX1 TexFormat1
++ Author: Robert S. Sutor
++ Date Created: 1987 through 1990
++ Basic Operations: coerce
++ Related Constructors: TexFormat
++ Also See: ScriptFormulaFormat, ScriptFormulaFormat1
++ AMS Classifications:
++ Keywords: TeX, output, format
++ References: \TeX{} is a trademark of the American Mathematical
++   Society.
++ Description:
++   \spadtype{TexFormat1} provides a utility coercion for changing
++   to TeX format anything that has a coercion to the standard output
++   format.

TexFormat1(S : SetCategory) : public == private where
  public  ==  with
    coerce : S -> TexFormat()
      ++ coerce(s) provides a direct coercion from a domain S to
      ++ TeX format. This allows the user to skip the step of first
      ++ manually coercing the object to standard output format before
      ++ it is coerced to TeX format.

  private == add
    import from TexFormat()

    coerce(s : S) : TexFormat ==
      coerce(s :: OutputForm)$TexFormat

--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
--All rights reserved.
--
--Redistribution and use in source and binary forms, with or without
--modification, are permitted provided that the following conditions are
--met:
--
--    - Redistributions of source code must retain the above copyright
--      notice, this list of conditions and the following disclaimer.
--
--    - Redistributions in binary form must reproduce the above copyright
--      notice, this list of conditions and the following disclaimer in
--      the documentation and/or other materials provided with the
--      distribution.
--
--    - Neither the name of The Numerical ALgorithms Group Ltd. nor the
--      names of its contributors may be used to endorse or promote products
--      derived from this software without specific prior written permission.
--
--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\end{spad}

\begin{axiom}

)set output tex off
)set output tex on

f:=operator 'f

eq1:=D(f(x),x) = x^n
eq2:=D(eq1,x)
eq3:=D(eq2,x)
eq4:=D(eq3,x)

X:=map(operator,[X[i] for i in 1..3])
eq5:=D((X.1)(t),t) = t^a%
eq6:=D(eq5,t)
eq7:=D(eq6,t)
eq8:=D(eq7,t)
eq9:=D(eq8,t,2)

glc:=[a%,b%,g%,d%,e%,z%,ee%,th%,i%,k%,l%,m%,x%,p%,r%,s%,t%,y%,ph%,ch%,ps%,oo%]

guc:=[G%,D%,Th%,L%,X%,P%,S%,Ph%,Ps%,OO%,hbar%]

G:=operator 'G%
eq:=(a%+b%+th%)^2 = OO% - L% + hbar% * G(z%)

\end{axiom}

fricas
(1) -> <spad>
fricas
)abbrev domain TEX TexFormat
++ Author: Robert S. Sutor
++ Date Created: 1987 through 1992
++ Basic Operations: coerce, convert, display, epilogue,
++   tex, new, prologue, setEpilogue!, setTex!, setPrologue!
++ Related Constructors: TexFormat1
++ Also See: ScriptFormulaFormat
++ AMS Classifications:
++ Keywords: TeX, LaTeX, output, format
++ References: \TeX{} is a trademark of the American Mathematical Society.
++ Description:
++   \spadtype{TexFormat} provides a coercion from \spadtype{OutputForm} to
++   \TeX{} format.  The particular dialect of \TeX{} used is \LaTeX{}.
++   The basic object consists of three parts: a prologue, a
++   tex part and an epilogue. The functions \spadfun{prologue},
++   \spadfun{tex} and \spadfun{epilogue} extract these parts,
++   respectively.  The main guts of the expression go into the tex part.
++   The other parts can be set (\spadfun{setPrologue!},
++   \spadfun{setEpilogue!}) so that contain the appropriate tags for
++   printing. For example, the prologue and epilogue might simply
++   contain ``\verb+\[+'' and ``\verb+\]+'', respectively, so that
++   the TeX section will be printed in LaTeX display math mode.
++ Revision:
++   25-FEB-2020 ... op PRIME (line 356), Greek characters x% (565 ff.)
++
TexFormat() : public == private where
  E      ==> OutputForm
  I      ==> Integer
  L      ==> List
  S      ==> String
  Sy     ==> Symbol
  US     ==> UniversalSegment(Integer)
public == SetCategory with coerce : E -> % ++ coerce(o) changes o in the standard output format to TeX ++ format. convert : (E, I) -> % ++ convert(o, step) changes o in standard output format to ++ TeX format and also adds the given step number. This is useful ++ if you want to create equations with given numbers or have the ++ equation numbers correspond to the interpreter step numbers. convert : (E, I, E) -> % ++ convert(o, step, type) changes o in standard output format to ++ TeX format and also adds the given step number and type. This ++ is useful if you want to create equations with given numbers ++ or have the equation numbers correspond to the interpreter step ++ numbers. display : (%, I) -> Void ++ display(t, width) outputs the TeX formatted code t so that each ++ line has length less than or equal to \spadvar{width}. display : % -> Void ++ display(t) outputs the TeX formatted code t so that each ++ line has length less than or equal to the value set by ++ the system command \spadsyscom{set output length}. epilogue : % -> L S ++ epilogue(t) extracts the epilogue section of a TeX form t. tex : % -> L S ++ tex(t) extracts the TeX section of a TeX form t. new : () -> % ++ new() create a new, empty object. Use \spadfun{setPrologue!}, ++ \spadfun{setTex!} and \spadfun{setEpilogue!} to set the various ++ components of this object. prologue : % -> L S ++ prologue(t) extracts the prologue section of a TeX form t. setEpilogue! : (%, L S) -> L S ++ setEpilogue!(t, strings) sets the epilogue section of a TeX form t to strings. setTex! : (%, L S) -> L S ++ setTex!(t, strings) sets the TeX section of a TeX form t to strings. setPrologue! : (%, L S) -> L S ++ setPrologue!(t, strings) sets the prologue section of a TeX form t to strings.
private == add import from OutputForm import from Character import from Integer import from List OutputForm import from List String import from OutputFormTools
Rep := Record(prolog : L S, TeX : L S, epilog : L S)
-- local variable declarations and definitions
expr : E prec, opPrec : I str : S blank : S := " \ "
maxPrec : I := 1000000 minPrec : I := 0
unaryOps : L Sy := ["-"::Sy]$(L Sy) unaryPrecs : L I := [710]$(L I)
-- the precedence of / in the following is relatively low because -- the bar obviates the need for parentheses. binaryOps : L Sy := ["+->"::Sy, "|"::Sy, "^"::Sy, "/"::Sy, "="::Sy, "~="::Sy, "<"::Sy, "<="::Sy, ">"::Sy, ">="::Sy, 'OVER, 'LET] binaryPrecs : L I := [0, 0, 900, 700, 400, 400, 400, 400, 400, 400, 700, 125]$(L I)
naryOps : L Sy := ["-"::Sy, "+"::Sy, "*"::Sy, ","::Sy, ";"::Sy, 'ROW, 'STRSEP, 'TENSOR] naryPrecs : L I := [700, 700, 800, 110, 110, 0, 0, 850]$(L I) naryNGOps : L Sy := ['ROW]
plexOps : L Sy := ['SIGMA, 'SIGMA2, 'PI, 'PI2, 'INTSIGN] plexPrecs : L I := [ 750, 750, 750, 750, 700]$(L I)
specialOps : L Sy := ['MATRIX, 'BRACKET, 'BRACE, 'CONCATB, 'VCONCAT, _ 'AGGLST, 'CONCAT, 'OVERBAR, 'ROOT, 'SUB, 'TAG, _ 'SUPERSUB, 'ZAG, 'AGGSET, 'SC, 'PAREN, _ 'SEGMENT, 'QUOTE, 'theMap, 'SLASH, 'PRIME]
-- the next two lists provide translations for some strings for -- which TeX provides special macros.
specialStrings : L Sy := ['cos, 'cot, 'csc, 'log, 'sec, 'sin, 'tan, 'cosh, 'coth, 'csch, 'sech, 'sinh, 'tanh, 'acos, 'asin, 'atan, 'erf, "..."::Sy, "$"::Sy, 'infinity, 'Gamma]
specialStringsInTeX : L S := ["\cos","\cot","\csc","\log","\sec","\sin","\tan", "\cosh","\coth","\csch","\sech","\sinh","\tanh", "\arccos","\arcsin","\arctan","\erf","\ldots","\$","\infty", "\Gamma"]
-- local function signatures
addBraces : S -> S addBrackets : S -> S group : S -> S formatBinary : (Sy, L E, I) -> S formatFunction : (E, L E, I) -> S formatMatrix : L E -> S formatNary : (Sy, S, I, L E, I) -> S formatNaryNoGroup : (Sy, S, I, L E, I) -> S formatNullary : Sy -> S formatPlex : (Sy, L E, I) -> S formatSpecial : (Sy, L E, I) -> S formatUnary : (Sy, E, I) -> S formatExpr : (E, I) -> S newWithNum : I -> % parenthesize : S -> S postcondition : S -> S splitLong : (S, I) -> L S splitLong1 : (S, I) -> L S stringify : E -> S ungroup : S -> S
-- public function definitions
new() : % == -- [["\["]$(L S), [""]$(L S), ["\]"]$(L S)]$Rep [["$$"]$(L S), [""]$(L S), ["$$"]$(L S)]$Rep
newWithNum(stepNum : I) : % == -- num : S := concat("%FRICAS STEP NUMBER: ",string(stepNum)$S) -- [["\["]$(L S), [""]$(L S), ["\]",num]$(L S)]$Rep num : S := concat(concat("\leqno(",string(stepNum)$S),")")$S [["$$"]$(L S), [""]$(L S), [num,"$$"]$(L S)]$Rep
coerce(expr : E) : % == f : % := new()$% f.TeX := [postcondition formatExpr(precondition expr, minPrec)]$(L S) f
convert(expr : E, stepNum : I) : % == f : % := newWithNum(stepNum) f.TeX := [postcondition formatExpr(precondition expr, minPrec)]$(L S) f
sayExpr(s : S) : Void == sayTeX$Lisp s
display(f : %, len : I) == s, t : S for s in f.prolog repeat sayExpr s for s in f.TeX repeat for t in splitLong(s, len) repeat sayExpr t for s in f.epilog repeat sayExpr s void()$Void
display(f : %) == display(f, _$LINELENGTH$Lisp pretend I)
prologue(f : %) == f.prolog tex(f : %) == f.TeX epilogue(f : %) == f.epilog
setPrologue!(f : %, l : L S) == f.prolog := l setTex!(f : %, l : L S) == f.TeX := l setEpilogue!(f : %, l : L S) == f.epilog := l
coerce(f : %) : E == s, t : S l : L S := [] for s in f.prolog repeat l := concat(s, l) for s in f.TeX repeat for t in splitLong(s, (_$LINELENGTH$Lisp pretend Integer) - 4) repeat l := concat(t, l) for s in f.epilog repeat l := concat(s, l) (reverse l) :: E
-- local function definitions
ungroup(str : S) : S == len : I := #str len < 2 => str lbrace : Character := char "{" rbrace : Character := char "}" -- drop leading and trailing braces if (str.1 =$Character lbrace) and (str.len =$Character rbrace) then u : US := segment(2, len-1)$US str := str.u str
postcondition(str : S) : S == str := ungroup str len : I := #str plus : Character := char "+" minus : Character := char "-" len < 4 => str for i in 1..(len-1) repeat if (str.i =$Character plus) and (str.(i+1) =$Character minus) then setelt!(str, i, char " ")$S str
stringify expr == (mathObject2String$Lisp expr) pretend S
lineConcat( line : S, lines : L S ) : L S == length := #line
if ( length > 0 ) then -- If the last character is a backslash then split at "\ ". -- Reinstate the blank.
if (line.length = char "\" ) then line := concat(line, " ")
-- Remark: for some reason, "\%" at the beginning -- of a line has the "\" erased when printed
if ( line.1 = char "%" ) then line := concat(" \", line) else if ( line.1 = char "\" ) and length > 1 and ( line.2 = char "%" ) then line := concat(" ", line)
lines := concat(line, lines)$List(S) lines
splitLong(str : S, len : I) : L S == -- this blocks into lines if len < 20 then len := _$LINELENGTH$Lisp splitLong1(str, len)
splitLong1(str : S, len : I) == -- We first build the list of lines backwards and then we -- reverse it.
l : List S := [] s : S := "" ls : I := 0 ss : S lss : I for ss in split(str,char " ") repeat -- have the newline macro end a line (even if it means the line -- is slightly too long)
ss = "\\" => l := lineConcat( concat(s, ss), l ) s := "" ls := 0
lss := #ss
-- place certain tokens on their own lines for clarity
ownLine : Boolean := u : US := segment(1, 4)$US (lss > 3) and ("\end" = ss.u) => true u := segment(1, 5)$US (lss > 4) and ("\left" = ss.u) => true u := segment(1, 6)$US (lss > 5) and (("\right" = ss.u) or ("\begin" = ss.u)) => true false
if ownLine or (ls + lss > len) then if not empty? s then l := lineConcat( s, l ) s := "" ls := 0
ownLine or lss > len => l := lineConcat( ss, l )
(lss = 1) and (ss.1 = char "\") => ls := ls + lss + 2 s := concat(s,concat(ss," ")$S)$S
ls := ls + lss + 1 s := concat(s,concat(ss," ")$S)$S
if ls > 0 then l := lineConcat( s, l )
reverse l
group str == concat ["{",str,"}"]
addBraces str == concat ["\left\{ ",str," \right\}"]
addBrackets str == concat ["\left[ ",str," \right]"]
parenthesize str == concat ["\left( ",str," \right)"]
formatSpecial(op : Sy, args : L E, prec : I) : S == arg : E prescript : Boolean := false op = 'theMap => "\mbox{theMap(...)}" op = 'AGGLST => formatNary(","::Sy, "", 0, args, prec) op = 'AGGSET => formatNary(";"::Sy, "", 0, args, prec) op = 'TAG => group concat [formatExpr(first args, prec), "\rightarrow", formatExpr(second args, prec)] op = 'SLASH => group concat [formatExpr(first args, prec), "/", formatExpr(second args, prec)] op = 'VCONCAT => group concat("\begin{array}{c}", concat(concat([concat(formatExpr(u, minPrec), "\\") for u in args]::L S), "\end{array}")) op = 'CONCATB => formatNary('STRSEP, " \ ", 0, args, prec) op = 'CONCAT => formatNary('STRSEP, "", 0, args, minPrec) op = 'QUOTE => group concat("<code>'</code>", formatExpr(first args, minPrec)) op = 'BRACKET => group addBrackets ungroup formatExpr(first args, minPrec) op = 'BRACE => group addBraces ungroup formatExpr(first args, minPrec) op = 'PAREN => group parenthesize ungroup formatExpr(first args, minPrec) op = 'PRIME => p:=convert(second args)$E not atom? p => formatSpecial('SUPERSUB, [first args, hspace(1)$E, second args], prec) string p="," => group concat [formatExpr(first args, minPrec),"'"] string p=",," => group concat [formatExpr(first args, minPrec),"''"] string p=",,," => group concat [formatExpr(first args, minPrec),"'''"] op = 'OVERBAR => empty?(args) => "" group concat ["\overline ", formatExpr(first args, minPrec)] op = 'ROOT => empty?(args) => "" tmp : S := group formatExpr(first args, minPrec) empty?(rest(args)) => group concat ["\sqrt ",tmp] group concat ["\root ", group formatExpr(first rest args, minPrec), " \of ", tmp] op = 'SEGMENT => tmp : S := concat [formatExpr(first args, minPrec), ".."] group empty?(rest(args)) => tmp concat [tmp, formatExpr(first rest args, minPrec)] op = 'SUB => group concat [formatExpr(first args, minPrec), " \sb ", formatSpecial('AGGLST, rest args, minPrec)] op = 'SUPERSUB => -- variable name form : List S := [formatExpr(first args, minPrec)] -- subscripts args := rest args empty?(args) => concat(form)$S tmp : S := formatExpr(first args, minPrec) if (tmp ~= "") and (tmp ~= "{}") and (tmp ~= " ") then form := append(form,[" \sb ",group tmp])$(List S) -- superscripts args := rest args empty?(args) => group concat(form)$S tmp : S := formatExpr(first args, minPrec) if (tmp ~= "") and (tmp ~= "{}") and (tmp ~= " ") then form := append(form,[" \sp ",group tmp])$(List S) -- presuperscripts args := rest args empty?(args) => group concat(form)$S tmp : S := formatExpr(first args, minPrec) if (tmp ~= "") and (tmp ~= "{}") and (tmp ~= " ") then form := append([" \sp ",group tmp],form)$(List S) prescript := true -- presubscripts args := rest args empty?(args) => group concat prescript => cons("{}",form) form tmp : S := formatExpr(first args, minPrec) if (tmp ~= "") and (tmp ~= "{}") and (tmp ~= " ") then form := append([" \sb ",group tmp],form)$(List S) prescript := true group concat prescript => cons("{}",form) form op = 'SC => -- need to handle indentation someday empty?(args) => "" tmp := formatNaryNoGroup('STRSEP, " \\ ", 800, args, minPrec) -- error "SC unhandled" group concat ["\begin{array}{l} ",tmp," \end{array} "] op = 'MATRIX => formatMatrix rest args op = 'ZAG => concat [" \zag{", formatExpr(first args, minPrec), "}{", formatExpr(first rest args, minPrec), "}"] concat ["not done yet for ", string(op)]
formatPlex(op : Sy, args : L E, prec : I) : S == hold : S p : I := position(op, plexOps) p < 1 => error "unknown plex op" opPrec := plexPrecs.p n : I := #args (n ~= 2) and (n ~= 3) => error "wrong number of arguments for plex" s : S := op = 'SIGMA => "\sum" op = 'SIGMA2 => "\sum" op = 'PI => "\prod" op = 'PI2 => "\prod" op = 'INTSIGN => "\int" "????" hold := formatExpr(first args, minPrec) args := rest args if hold ~= "" then s := concat [s, " \sb", group concat ["\displaystyle ", hold]] if not(empty?(rest(args))) then hold := formatExpr(first args, minPrec) if hold ~= "" then s := concat [s, " \sp", group concat ["\displaystyle ", hold]] args := rest args s := concat [s, " ", formatExpr(first args, opPrec)] if opPrec < prec then s := parenthesize s group s
formatMatrix(args : L E) : S == -- format for args is [[ROW ...], [ROW ...], [ROW ...]] -- generate string for formatting columns (centered) cols : S := "{" for i in 1..#arguments(first(args)) repeat cols := concat(cols,"c") cols := concat(cols,"} ") group addBrackets concat ["\begin{array}", cols, formatNaryNoGroup('STRSEP, " \\ ", 0, args, minPrec), " \end{array} "]
formatFunction(op : E, args : L E, prec : I) : S == ops := formatExpr(op, minPrec) group concat [ops, " ", parenthesize formatNary(","::Sy, "", 0, args, minPrec)]
formatNullary(op : Sy) == op = 'NOTHING => "" group concat [string(op), "()"]
formatUnary(op : Sy, arg : E, prec : I) == p : I := position(op, unaryOps) p < 1 => error "unknown unary op" opPrec := unaryPrecs.p s : S := concat [string(op), formatExpr(arg, opPrec)] opPrec < prec => group parenthesize s op = "-"::Sy => s group s
formatBinary(op : Sy, args : L E, prec : I) : S == p : I := position(op, binaryOps) p < 1 => error "unknown binary op" opPrec := binaryPrecs.p s1 := formatExpr(first args, opPrec) s2 := formatExpr(first rest args, (op = "^"::Sy => minPrec ; opPrec)) ops : S := op = "|"::Sy => " \mid " op = "^"::Sy => " \sp " op = "/"::Sy => " \over " op = 'OVER => " \over " op = "+->"::Sy => " \mapsto " op = "~="::Sy => " \ne " op = "<="::Sy => " \leq " op = ">="::Sy => " \geq " -- FIXME how to do this properly ??? op = 'LET => " := " string(op) s := op = "^"::Sy => concat [group(s1), ops, group(s2)] concat [s1, ops, s2] group op = "/"::Sy or op = 'OVER => s opPrec < prec => parenthesize s s
formatNary(op : Sy, sep : S, opprec : I, args : L E, prec : I) : S == group formatNaryNoGroup(op, sep, opprec, args, prec)
formatNaryNoGroup(op : Sy, sep : S, opprec : I, args : L E, prec : I) : S == empty?(args) => "" p : I := position(op, naryOps) p < 1 => error "unknown nary op" ops : S := op = 'STRSEP => sep op = ","::Sy => ", \: " op = ";"::Sy => "; \: " op = "*"::Sy => blank op = '_ => " \ " op = 'ROW => " & " op = 'TENSOR => " \otimes " string(op) l : L S := [] opPrec := op = 'STRSEP => opprec naryPrecs.p for a in args repeat l := concat(ops, concat(formatExpr(a, opPrec), l)$L(S))$L(S) s : S := concat reverse rest l opPrec < prec => parenthesize s s
formatExpr(expr : E, prec : I) : S == i, len : Integer intSplitLen : Integer := 20 str, s : S atom?(expr) => str := stringify expr len := #str integer?(expr) => i := integer(expr) if (i < 0) or (i > 9) then group nstr : String := "" -- insert some blanks into the string, if too long while ((len := #str) > intSplitLen) repeat nstr := concat [nstr, " ", elt(str, segment(1, intSplitLen)$US)] str := elt(str, segment(intSplitLen + 1)$US) empty? nstr => str nstr := empty? str => nstr concat [nstr, " ", str] elt(nstr, segment(2)$US) else str str = "%pi" => "\pi" str = "%e" => "e" str = "%i" => "i" -- -- https://en.wikipedia.org/wiki/Greek_alphabet -- Traditional Latin transliteration -- str = "a%" => "\alpha" str = "b%" => "\beta" str = "g%" => "\gamma" str = "d%" => "\delta" str = "e%" => "\epsilon" str = "z%" => "\zeta" str = "ee%" => "\eta" str = "th%" => "\theta" str = "i%" => "\iota" str = "k%" => "\kappa" str = "l%" => "\lambda" str = "m%" => "\mu" str = "n%" => "\nu" str = "x%" => "\xi" --str = "o%" => "\omicron" str = "p%" => "\pi" str = "r%" => "\rho" str = "s%" => "\sigma" str = "t%" => "\tau" str = "y%" => "\upsilon" str = "ph%" => "\phi" str = "ch%" => "\chi" str = "ps%" => "\psi" str = "oo%" => "\omega" str = "G%" => "\Gamma" str = "D%" => "\Delta" str = "Th%" => "\Theta" str = "L%" => "\Lambda" str = "X%" => "\Xi" str = "P%" => "\Pi" str = "S%" => "\Sigma" str = "Ph%" => "\Phi" --str = "Ch%" => "\Chi" str = "Ps%" => "\Psi" str = "OO%" => "\Omega" str = "hbar%" => "\hbar" -- len > 1 and str.1 = char "%" and str.2 = char "%" => u : US := segment(3, len)$US concat(" \%\%", str.u) len > 0 and str.1 = char "%" => concat(" \", str) len > 0 and str.1 = char "_"" => s := "\verb#" for i in 1..len repeat if str.i = char "#" then s := concat(s, "verb-#-\verb#") else s := concat(s, (str.i)::S) concat(s, "#") len = 1 and str.1 = char " " => "{\ }" -- escape the underscore character s := "" for i in 1..len repeat s := concat(s, (if str.i = char "__" then "\__" else (str.i)::S)) str := s len > 1 and digit? str.1 => group str -- should handle floats if symbol?(expr) then op := symbol(expr) (i := position(op, specialStrings)) > 0 => str := specialStringsInTeX.i (i := position(char " ", str)) > 0 => -- We want to preserve spacing, so use a roman font. concat [" \mbox{\rm ", str, "} "] str opf : E := operator(expr) args : L E := arguments(expr) nargs : I := #args
symbol?(opf) => op := symbol(opf) -- special cases member?(op, specialOps) => formatSpecial(op, args, prec) member?(op, plexOps) => formatPlex(op, args, prec)
-- nullary case 0 = nargs => formatNullary op
-- unary case (1 = nargs) and member?(op, unaryOps) => formatUnary(op, first args, prec)
-- binary case (2 = nargs) and member?(op, binaryOps) => formatBinary(op, args, prec)
-- nary case member?(op, naryNGOps) => formatNaryNoGroup(op, "", 0, args, prec) member?(op, naryOps) => formatNary(op, "", 0, args, prec) formatFunction(opf, args, prec) formatFunction(opf, args, prec)
fricas
)abbrev package TEX1 TexFormat1
++ Author: Robert S. Sutor
++ Date Created: 1987 through 1990
++ Basic Operations: coerce
++ Related Constructors: TexFormat
++ Also See: ScriptFormulaFormat, ScriptFormulaFormat1
++ AMS Classifications:
++ Keywords: TeX, output, format
++ References: \TeX{} is a trademark of the American Mathematical
++   Society.
++ Description:
++   \spadtype{TexFormat1} provides a utility coercion for changing
++   to TeX format anything that has a coercion to the standard output
++   format.
TexFormat1(S : SetCategory) : public == private where public == with coerce : S -> TexFormat() ++ coerce(s) provides a direct coercion from a domain S to ++ TeX format. This allows the user to skip the step of first ++ manually coercing the object to standard output format before ++ it is coerced to TeX format.
private == add import from TexFormat()
coerce(s : S) : TexFormat == coerce(s :: OutputForm)$TexFormat
--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. --All rights reserved. -- --Redistribution and use in source and binary forms, with or without --modification, are permitted provided that the following conditions are --met: -- -- - Redistributions of source code must retain the above copyright -- notice, this list of conditions and the following disclaimer. -- -- - Redistributions in binary form must reproduce the above copyright -- notice, this list of conditions and the following disclaimer in -- the documentation and/or other materials provided with the -- distribution. -- -- - Neither the name of The Numerical ALgorithms Group Ltd. nor the -- names of its contributors may be used to endorse or promote products -- derived from this software without specific prior written permission. -- --THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS --IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED --TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A --PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER --OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, --EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, --PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR --PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF --LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING --NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS --SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</spad>
fricas
Compiling FriCAS source code from file 
      /var/lib/zope2.10/instance/axiom-wiki/var/LatexWiki/2552111487917728190-25px001.spad
      using old system compiler.
   TEX abbreviates domain TexFormat 
------------------------------------------------------------------------
   initializing NRLIB TEX for TexFormat 
   compiling into NRLIB TEX 
   importing OutputForm
   importing Character
   importing Integer
   importing List OutputForm
   importing List String
   importing OutputFormTools
   compiling exported new : () -> %
Time: 0.01 SEC.
compiling local newWithNum : Integer -> % Time: 0 SEC.
compiling exported coerce : OutputForm -> % Time: 0 SEC.
compiling exported convert : (OutputForm,Integer) -> % Time: 0 SEC.
compiling local sayExpr : String -> Void TEX;sayExpr is replaced by sayTeX Time: 0 SEC.
compiling exported display : (%,Integer) -> Void Time: 0 SEC.
compiling exported display : % -> Void Time: 0 SEC.
compiling exported prologue : % -> List String TEX;prologue;%L;8 is replaced by QVELTf0 Time: 0 SEC.
compiling exported tex : % -> List String TEX;tex;%L;9 is replaced by QVELTf1 Time: 0 SEC.
compiling exported epilogue : % -> List String TEX;epilogue;%L;10 is replaced by QVELTf2 Time: 0 SEC.
compiling exported setPrologue! : (%,List String) -> List String TEX;setPrologue!;%2L;11 is replaced by QSETVELTf0l Time: 0 SEC.
compiling exported setTex! : (%,List String) -> List String TEX;setTex!;%2L;12 is replaced by QSETVELTf1l Time: 0 SEC.
compiling exported setEpilogue! : (%,List String) -> List String TEX;setEpilogue!;%2L;13 is replaced by QSETVELTf2l Time: 0 SEC.
compiling exported coerce : % -> OutputForm Time: 0 SEC.
compiling local ungroup : String -> String Time: 0 SEC.
compiling local postcondition : String -> String Time: 0 SEC.
compiling local stringify : OutputForm -> String TEX;stringify is replaced by mathObject2String Time: 0 SEC.
compiling local lineConcat : (String,List String) -> List String Time: 0.03 SEC.
compiling local splitLong : (String,Integer) -> List String Time: 0 SEC.
compiling local splitLong1 : (String,Integer) -> List String Time: 0.01 SEC.
compiling local group : String -> String Time: 0 SEC.
compiling local addBraces : String -> String Time: 0 SEC.
compiling local addBrackets : String -> String Time: 0 SEC.
compiling local parenthesize : String -> String Time: 0 SEC.
compiling local formatSpecial : (Symbol,List OutputForm,Integer) -> String Time: 0.03 SEC.
compiling local formatPlex : (Symbol,List OutputForm,Integer) -> String Time: 0 SEC.
compiling local formatMatrix : List OutputForm -> String Time: 0 SEC.
compiling local formatFunction : (OutputForm,List OutputForm,Integer) -> String Time: 0 SEC.
compiling local formatNullary : Symbol -> String Time: 0 SEC.
compiling local formatUnary : (Symbol,OutputForm,Integer) -> String Time: 0 SEC.
compiling local formatBinary : (Symbol,List OutputForm,Integer) -> String Time: 0 SEC.
compiling local formatNary : (Symbol,String,Integer,List OutputForm,Integer) -> String Time: 0 SEC.
compiling local formatNaryNoGroup : (Symbol,String,Integer,List OutputForm,Integer) -> String Time: 0 SEC.
compiling local formatExpr : (OutputForm,Integer) -> String Time: 0.07 SEC.
(time taken in buildFunctor: 0)
;;; *** |TexFormat| REDEFINED
;;; *** |TexFormat| REDEFINED Time: 0 SEC.
Warnings: [1] coerce: TeX has no value [2] convert: TeX has no value [3] display: prolog has no value [4] display: TeX has no value [5] display: epilog has no value [6] display: pretend(Integer) -- should replace by @ [7] prologue: prolog has no value [8] tex: TeX has no value [9] epilogue: epilog has no value [10] setPrologue!: prolog has no value [11] setTex!: TeX has no value [12] setEpilogue!: epilog has no value [13] coerce: prolog has no value [14] coerce: pretend(Integer) -- should replace by @ [15] coerce: epilog has no value [16] stringify: pretend(String) -- should replace by @ [17] splitLong1: l has no value [18] splitLong1: ls has no value [19] splitLong1: s has no value [20] formatSpecial: form has no value [21] formatSpecial: prescript has no value [22] formatPlex: s has no value [23] formatExpr: str has no value
Cumulative Statistics for Constructor TexFormat Time: 0.19 seconds
finalizing NRLIB TEX Processing TexFormat for Browser database: --------constructor--------- --------(coerce (% (OutputForm)))--------- --------(convert (% (OutputForm) (Integer)))--------- --------(convert (% (OutputForm) (Integer) (OutputForm)))--------- --------(display ((Void) % (Integer)))--------- --------(display ((Void) %))--------- --->/usr/local/lib/fricas/target/x86_64-linux-gnu/../../src/algebra/TEX.spad-->TexFormat((display ((Void) %))): Unexpected HT command: \spadsyscom "\\spad{display(t)} outputs the TeX formatted code \\spad{t} so that each line has length less than or equal to the value set by the system command \\spadsyscom{set output length}." --------(epilogue ((List (String)) %))--------- --------(tex ((List (String)) %))--------- --------(new (%))--------- --------(prologue ((List (String)) %))--------- --------(setEpilogue! ((List (String)) % (List (String))))--------- --------(setTex! ((List (String)) % (List (String))))--------- --------(setPrologue! ((List (String)) % (List (String))))--------- ; compiling file "/var/aw/var/LatexWiki/TEX.NRLIB/TEX.lsp" (written 31 OCT 2024 07:20:05 PM):
; wrote /var/aw/var/LatexWiki/TEX.NRLIB/TEX.fasl ; compilation finished in 0:00:00.160 ------------------------------------------------------------------------ TexFormat is now explicitly exposed in frame initial TexFormat will be automatically loaded when needed from /var/aw/var/LatexWiki/TEX.NRLIB/TEX
TEX1 abbreviates package TexFormat1 ------------------------------------------------------------------------ initializing NRLIB TEX1 for TexFormat1 compiling into NRLIB TEX1 importing TexFormat compiling exported coerce : S -> TexFormat Time: 0 SEC.
(time taken in buildFunctor: 0)
;;; *** |TexFormat1| REDEFINED
;;; *** |TexFormat1| REDEFINED Time: 0 SEC.
Cumulative Statistics for Constructor TexFormat1 Time: 0 seconds
finalizing NRLIB TEX1 Processing TexFormat1 for Browser database: --------constructor--------- --------(coerce ((TexFormat) S))--------- ; compiling file "/var/aw/var/LatexWiki/TEX1.NRLIB/TEX1.lsp" (written 31 OCT 2024 07:20:05 PM):
; wrote /var/aw/var/LatexWiki/TEX1.NRLIB/TEX1.fasl ; compilation finished in 0:00:00.020 ------------------------------------------------------------------------ TexFormat1 is now explicitly exposed in frame initial TexFormat1 will be automatically loaded when needed from /var/aw/var/LatexWiki/TEX1.NRLIB/TEX1

fricas
)set output tex off
 
fricas
)set output tex on
f:=operator 'f

\label{eq1}f(1)
Type: BasicOperator?
fricas
eq1:=D(f(x),x) = x^n

\label{eq2}{{f'}\left({x}\right)}={{x}^{n}}(2)
Type: Equation(Expression(Integer))
fricas
eq2:=D(eq1,x)

\label{eq3}{{f''}\left({x}\right)}={n \ {{x}^{n - 1}}}(3)
Type: Equation(Expression(Integer))
fricas
eq3:=D(eq2,x)

\label{eq4}{{f'''}\left({x}\right)}={{\left({{n}^{2}}- n \right)}\ {{x}^{n - 2}}}(4)
Type: Equation(Expression(Integer))
fricas
eq4:=D(eq3,x)

\label{eq5}{{f_{\ }^{\left(iv \right)}}\left({x}\right)}={{\left({{n}^{3}}-{3 \ {{n}^{2}}}+{2 \  n}\right)}\ {{x}^{n - 3}}}(5)
Type: Equation(Expression(Integer))
fricas
X:=map(operator,[X[i] for i in 1..3])

\label{eq6}\left[{X_{1}}, \:{X_{2}}, \:{X_{3}}\right](6)
Type: List(BasicOperator?)
fricas
eq5:=D((X.1)(t),t) = t^a%

\label{eq7}{{{X_{1}}'}\left({t}\right)}={{t}^{\alpha}}(7)
Type: Equation(Expression(Integer))
fricas
eq6:=D(eq5,t)

\label{eq8}{{{X_{1}}''}\left({t}\right)}={\alpha \ {{t}^{\alpha - 1}}}(8)
Type: Equation(Expression(Integer))
fricas
eq7:=D(eq6,t)

\label{eq9}{{{X_{1}}'''}\left({t}\right)}={{\left({{\alpha}^{2}}- \alpha \right)}\ {{t}^{\alpha - 2}}}(9)
Type: Equation(Expression(Integer))
fricas
eq8:=D(eq7,t)

\label{eq10}{{{X_{1}}_{\ }^{\left(iv \right)}}\left({t}\right)}={{\left({{\alpha}^{3}}-{3 \ {{\alpha}^{2}}}+{2 \  \alpha}\right)}\ {{t}^{\alpha - 3}}}(10)
Type: Equation(Expression(Integer))
fricas
eq9:=D(eq8,t,2)

\label{eq11}{{{X_{1}}_{\ }^{\left(vi \right)}}\left({t}\right)}={{\left({{\alpha}^{5}}-{{10}\ {{\alpha}^{4}}}+{{35}\ {{\alpha}^{3}}}-{{50}\ {{\alpha}^{2}}}+{{24}\  \alpha}\right)}\ {{t}^{\alpha - 5}}}(11)
Type: Equation(Expression(Integer))
fricas
glc:=[a%,b%,g%,d%,e%,z%,ee%,th%,i%,k%,l%,m%,x%,p%,r%,s%,t%,y%,ph%,ch%,ps%,oo%]

\label{eq12}\begin{array}{@{}l}
\displaystyle
\left[ \alpha , \: \beta , \: \gamma , \: \delta , \: \epsilon , \: \zeta , \: \eta , \: \theta , \: \iota , \: \kappa , \: \right.
\
\
\displaystyle
\left.\lambda , \: \mu , \: \xi , \: \pi , \: \rho , \: \sigma , \: \tau , \: \upsilon , \: \phi , \: \chi , \: \psi , \: \right.
\
\
\displaystyle
\left.\omega \right] 
(12)
Type: List(OrderedVariableList([a%,b%,g%,d%,e%,z%,ee%,th%,i%,k%,l%,m%,x%,p%,r%,s%,t%,y%,ph%,ch%,ps%,oo%]))
fricas
guc:=[G%,D%,Th%,L%,X%,P%,S%,Ph%,Ps%,OO%,hbar%]

\label{eq13}\begin{array}{@{}l}
\displaystyle
\left[ \Gamma , \: \Delta , \: \Theta , \: \Lambda , \: \Xi , \: \Pi , \: \Sigma , \: \Phi , \: \Psi , \: \right.
\
\
\displaystyle
\left.\Omega , \: \hbar \right] 
(13)
Type: List(OrderedVariableList([G%,D%,Th%,L%,X%,P%,S%,Ph%,Ps%,OO%,hbar%]))
fricas
G:=operator 'G%

\label{eq14}\Gamma(14)
Type: BasicOperator?
fricas
eq:=(a%+b%+th%)^2 = OO% - L% + hbar% * G(z%)

\label{eq15}\begin{array}{@{}l}
\displaystyle
{{{\theta}^{2}}+{{\left({2 \  \beta}+{2 \  \alpha}\right)}\  \theta}+{{\beta}^{2}}+{2 \  \alpha \  \beta}+{{\alpha}^{2}}}= \
\
\displaystyle
{{\hbar \ {\Gamma \left({\zeta}\right)}}+ \Omega - \Lambda}
(15)
Type: Equation(Expression(Integer))