The Gram-Schmidt process takes a set of N vectors or functions and an inner product. It then builds a set of N orthogonal vectors/functions from the original ones. It is a process that can be easily automated using symbolic calculations.
This is done using Mathematica in this notebook. It begins with defining the inner product as a Mathematica function:
ip[u_, v_] := Integrate[u v, {x, 0, X}]