docs: def engine_schema(engine, out_names=None, filename=None, format="pdf"):
      """ Build a graphviz schema of a reliure :class:`.Engine`.
      
      It depends on `graphviz <https://pypi.python.org/pypi/graphviz>`_.
  
      :param engine: reliure engine to graph
      :type engine: :class:`.Engine`
      :param out_names: list of block output to consider as engine output (all by default)
      :param filename: output filename, create the file if given
      :param formal: output file formal (pdf, svg, png, ...)
  
      >>> from reliure.engine import Engine
      >>> egn = Engine("preproc", "proc1", "proc2")
      >>> egn.preproc.setup(in_name="input", out_name="data")
      >>> egn.proc1.setup(in_name="data", out_name="gold_data")
      >>> egn.proc2.setup(in_name="input", out_name="silver_data")
      >>> # you can create
      >>> schema = engine_schema(egn, filename='docs/img/engine_schema', format='png')
  
      it create the following image :
  
      .. image:: /../_static/engine_schema.png
  
      You can specify which block output will be consider as engine output:
  
      >>> schema = engine_schema(egn, ["gold_data", "silver_data"], filename='docs/img/engine_schema_simple', format='png')
  
      .. image:: /../_static/engine_schema_simple.png
  
      Note that it is also possible to draw a pdf;
  
      >>> schema = engine_schema(egn, ["gold_data", "silver_data"], filename='docs/img/engine_schema_simple', format='pdf')
      """
      import graphviz as pgv
      #engine.validate()
      dg = pgv.Digraph(format=format)
      input_node_name = "in"
      output_node_name = "out"
      dg.node(input_node_name, label=input_node_name, shape="ellipse")
      block_source = {} # witch block is the source for witch data
      for e_in_name in engine.in_name:
          block_source[e_in_name] = input_node_name
      # creation des sommets
      for block in engine:
          dg.node(block.name, label=' %s ' % block.name, shape="box")
      # creation des liens
      for block in engine:
          for in_name in block.in_name:
              dg.edge(block_source[in_name], block.name,
                  label=" %s " % in_name,
                  #fontsize=10,
              )
          block_source[block.out_name] = block.name
      
      if out_names is None:
          out_names = set([block.out_name for block in engine])
      
      if len(out_names):
          dg.node(output_node_name, label=' %s ' % output_node_name, shape="ellipse")
          for out_name in out_names:
              if out_name not in block_source:
                  raise ValueError("'%s' is not a generated data" % out_name)
              dg.edge(block_source[out_name], output_node_name,
                  label=" %s " % out_name,
                  #fontsize=10,
              )
      if filename:
          dg.render(filename)
      return dg