diff --git a/src/scripts/gendoc/doc_alias.template b/src/scripts/gendoc/doc_alias.template
new file mode 100644
index 0000000000..c0d5fa7a3d
--- /dev/null
+++ b/src/scripts/gendoc/doc_alias.template
@@ -0,0 +1,24 @@
+doc_macros.include#!
+~~Title: ${alias.full_name}$~~
+====== ${alias.full_name}$ (alias) ======
+
+${BEST_SUMMARY(obj=alias)}$
+
+${BEST_DESCRIPTION(obj=alias)}$
+
+${BEST_SINCE(obj=alias)}$
+
+${OBJECT_STATIC_CONTENT(obj=alias, section='description')}$
+
+===== Signature =====
+
+
+TODO
+
+
+===== C signature =====
+
+
+TODO
+
+
diff --git a/src/scripts/gendoc/doc_class.template b/src/scripts/gendoc/doc_class.template
new file mode 100644
index 0000000000..60f6779af1
--- /dev/null
+++ b/src/scripts/gendoc/doc_class.template
@@ -0,0 +1,106 @@
+doc_macros.include#!
+~~Title: ${cls.full_name}$~~
+====== ${cls.full_name}$ (${CLS_TYPE}$) ======
+
+${BEST_SUMMARY(obj=cls)}$
+
+${BEST_DESCRIPTION(obj=cls)}$
+
+${BEST_SINCE(obj=cls)}$
+
+${OBJECT_STATIC_CONTENT(obj=cls, section='description')}$
+
+
+===== Inheritance =====
+
+
+ => ${CLS_LINK(cls=inherit)}$#!
+
+
+++++ Full hierarchy |
+
+
+ * ${CLS_LINK(cls=inherit)}$ //(${CLS_TYPE(cls=inherit)}$)//
+
+ * ${CLS_LINK(cls=inherit)}$ //(${CLS_TYPE(cls=inherit)}$)//
+
+ * ${CLS_LINK(cls=inherit)}$ //(${CLS_TYPE(cls=inherit)}$)//
+
+ * ${CLS_LINK(cls=inherit)}$ //(${CLS_TYPE(cls=inherit)}$)//
+
+ * ${CLS_LINK(cls=inherit)}$ //(${CLS_TYPE(cls=inherit)}$)//
+
+ * ${CLS_LINK(cls=inherit)}$ //(${CLS_TYPE(cls=inherit)}$)//
+
+ * ${CLS_LINK(cls=inherit)}$ //(${CLS_TYPE(cls=inherit)}$)//
+
+ * ${CLS_LINK(cls=inherit)}$ //(${CLS_TYPE(cls=inherit)}$)//
+
+ * ${CLS_LINK(cls=inherit)}$ //(${CLS_TYPE(cls=inherit)}$)//
+
+ * ${CLS_LINK(cls=inherit)}$ //(${CLS_TYPE(cls=inherit)}$)//
+
+
+
+
+
+
+
+
+
+
+
+++++
+
+
+===== Properties =====
+
+
+
+${IMPLEMENT_FULL(impl=impl, cls=cls)}$
+\\
+
+
+No properties defined in this class.
+
+
+===== Methods =====
+
+
+
+${IMPLEMENT_FULL(impl=impl, cls=cls)}$
+\\
+
+
+No Methods defined in this class.
+
+
+===== Inherited members =====
+
+
+^ ${CLS_LINK(cls=cls2)}$ //(${CLS_TYPE(cls=cls2)}$)//^^^
+
+| ${FUNC_SCOPE(func=impl.function)}$ #!
+| **${FUNC_LINK(func=impl.function)}$** #!
+| ${BEST_SUMMARY(obj=impl)}$ |
+
+
+No inherits defined in this class.
+
+
+===== Events =====
+
+
+
+^ Local implemented ^^ event info ^
+
+| ''${ev.name}$'' | ${BEST_SUMMARY(obj=ev)}$ ${OBJECT_SCOPE(obj=ev)}$ ${EVENT_TAGS}$| ${TYPE_LINK(type=ev.type) if ev.type else 'None'}$ |
+
+
+
+
+^ Inherited from ${CLS_LINK(cls=cls2)}$ //(${CLS_TYPE(cls=cls2)}$)// ^^ event info ^
+
+| ''${ev.name}$'' | ${BEST_SUMMARY(obj=ev)}$ ${OBJECT_SCOPE(obj=ev)}$ ${EVENT_TAGS}$ | ${TYPE_LINK(type=ev.type) if ev.type else 'None'}$ |
+
+
diff --git a/src/scripts/gendoc/doc_enum.template b/src/scripts/gendoc/doc_enum.template
new file mode 100644
index 0000000000..03f6cd62cd
--- /dev/null
+++ b/src/scripts/gendoc/doc_enum.template
@@ -0,0 +1,39 @@
+doc_macros.include#!
+~~Title: ${enum.full_name}$~~
+====== ${enum.full_name}$ (enum) ======
+
+${BEST_SUMMARY(obj=enum)}$
+
+${BEST_DESCRIPTION(obj=enum)}$
+
+${BEST_SINCE(obj=enum)}$
+
+${OBJECT_STATIC_CONTENT(obj=enum, section='description')}$
+
+===== Fields =====
+
+${OBJECT_STATIC_CONTENT(obj=enum, section='fields')}$
+
+
+ * **${field.name}$** - ${BEST_SUMMARY(obj=field)}$
+
+
+===== Signature =====
+
+
+enum {
+
+ ${field.name}$: ${field.value.serialize}$,
+
+}
+
+
+===== C Signature =====
+
+
+typedef enum {
+
+ ${field.c_name}$ = ${field.value.serialize}$,
+
+} ${enum.full_name.replace('.', '_')}$;
+
diff --git a/src/scripts/gendoc/doc_macros.include b/src/scripts/gendoc/doc_macros.include
new file mode 100644
index 0000000000..ac01b99722
--- /dev/null
+++ b/src/scripts/gendoc/doc_macros.include
@@ -0,0 +1,253 @@
+#!##############################################################################
+#!#### BEST_SUMMARY(obj) #####################################################
+#!##############################################################################
+
+
+
+${UNTOKENIZE(tokens=obj.documentation_get(obj.function.type).summary_tokens)}$#!
+
+
+
+
+${UNTOKENIZE(tokens=parent_impl.documentation_get(parent_impl.function.type).summary_tokens)}$#!
+
+
+
+
+
+${UNTOKENIZE(tokens=obj.documentation.summary_tokens)}$#!
+
+**MISSING DOCS !!!!!**#!
+
+
+#!##############################################################################
+#!#### BEST_DESCRIPTION(obj) #################################################
+#!##############################################################################
+
+
+
+${UNTOKENIZE(tokens=obj.documentation_get(obj.function.type).description_tokens)}$#!
+
+
+
+
+${UNTOKENIZE(tokens=parent_impl.documentation_get(parent_impl.function.type).description_tokens)}$#!
+
+
+
+
+
+${UNTOKENIZE(tokens=obj.documentation.description_tokens)}$#!
+
+**MISSING DOCS !!!!!**#!
+
+
+#!##############################################################################
+#!#### BEST_SINCE(obj) #######################################################
+#!##############################################################################
+
+
+//Since ${obj.documentation.since}$//
+
+
+#!##############################################################################
+#!#### UNTOKENIZE(tokens) ####################################################
+#!##############################################################################
+
+
+${'\n\n' if i else ''}$#!
+
+
+%%${token.text}$%%#!
+
+**REF ${token.text}$ ${token.ref}$ ??**#!
+
+''${token.text}$''#!
+
+
+${token.text}$
+
+
+
+${token.text}$
+
+
+
+${token.text}$
+
+
+
+**TODO:** ${token.text}$
+
+
+**USUPPORTED TOKEN TYPE ${token}$**
+
+
+
+
+#!##############################################################################
+#!#### CLS_TYPE(cls) #########################################################
+#!##############################################################################
+
+
+class#!
+
+class#!
+
+mixin#!
+
+interface#!
+
+
+#!##############################################################################
+#!#### CLS_LINK(cls) #########################################################
+#!##############################################################################
+
+[[:develop:api#!
+
+:${n.lower()}$#!
+
+:${cls.name.lower()}$|${cls.full_name}$]]
+
+#!##############################################################################
+#!#### EVENT_LINK(cls, ev) ###################################################
+#!##############################################################################
+
+[[:develop:api#!
+
+:${n.lower()}$#!
+
+:${cls.name.lower()}$#!
+:event#!
+:${ev.name.lower().replace(',','_')}$|${ev.name}$]]
+
+#!##############################################################################
+#!#### TYPEDECL_LINK(typedecl) ###############################################
+#!##############################################################################
+
+[[:develop:api#!
+
+:${n.lower()}$#!
+
+:${typedecl.name.lower()}$|${typedecl.full_name}$]]
+
+#!##############################################################################
+#!#### TYPE_LINK(type) #######################################################
+#!##############################################################################
+
+[[:develop:api#!
+
+:${n.lower()}$#!
+
+:${type.name.lower()}$|${type.full_name}$]]
+
+#!##############################################################################
+#!#### FUNC_LINK(func) #######################################################
+#!##############################################################################
+
+[[:develop:api#!
+
+:${n.lower()}$#!
+
+
+:method#!
+
+:property#!
+
+:${func.name}$|${func.name}$]]
+
+#!##############################################################################
+#!#### FUNC_SCOPE(func) ######################################################
+#!##############################################################################
+
+
+ ''class method'' #!
+
+
+
+ ''protected get'' #!
+
+ ''private get'' #!
+
+
+ ''protected set'' #!
+
+ ''private set'' #!
+
+
+
+ ''protected'' #!
+
+ ''private'' #!
+
+
+
+#!##############################################################################
+#!#### OBJECT_SCOPE(obj) #####################################################
+#!##############################################################################
+
+
+ ''private'' #!
+
+ ''protected'' #!
+
+
+#!##############################################################################
+#!#### EVENT_TAGS(ev) ########################################################
+#!##############################################################################
+
+
+ ''hot'' #!
+
+ ''restart'' #!
+
+
+#!##############################################################################
+#!#### IMPLEMENT_FULL(impl, cls) #############################################
+#!##############################################################################
+
+**${FUNC_LINK(func=impl.function)}$** #!
+(#!
+
+
+${', ' if i else ''}$${val.type.name}$#!
+
+
+
+${', ' if i else ''}$#!
+//${param.type.name}$// ''${param.direction.name.lower()}$'' **${param.name}$**#!
+
+
+)#!
+
+ ''rw'' #!
+
+ ''read only'' #!
+
+ ''write only'' #!
+
+
+ => //${impl.function.method_return_type.name}$// #!
+
+ => //None// #!
+
+
+${FUNC_SCOPE(func=impl.function)}$#!
+
+//[Overridden from ${CLS_LINK(cls=impl.class_)}$]// #!
+
+\\
+> ${BEST_SUMMARY(obj=impl)}$
+
+#!##############################################################################
+#!#### OBJECT_STATIC_CONTENT(obj, section) ###################################
+#!##############################################################################
+
+{{page>:develop:api-include#!
+
+:${ns.lower()}$#!
+
+:${obj.name.lower()}$#!
+:{section}#!
+&nouser&nolink&nodate}}
+
diff --git a/src/scripts/gendoc/doc_start.template b/src/scripts/gendoc/doc_start.template
new file mode 100644
index 0000000000..640f805d9d
--- /dev/null
+++ b/src/scripts/gendoc/doc_start.template
@@ -0,0 +1,52 @@
+doc_macros.include#!
+~~Title: EFL Reference~~
+{{page>:develop:api-include:reference:general&nouser&nolink&nodate}}
+
+
+
+===== ${ns.name}$ =====
+
+
+
+^ Classes ^^
+
+| ${CLS_LINK}$ | ${BEST_SUMMARY(obj=cls)}$ |
+
+#!
+
+
+^ Interfaces ^^
+
+| ${CLS_LINK}$ | ${BEST_SUMMARY(obj=cls)}$ |
+
+#!
+
+
+^ Mixins ^^
+
+| ${CLS_LINK}$ | ${BEST_SUMMARY(obj=cls)}$ |
+
+#!
+
+
+^ Aliases ^^
+
+| ${TYPEDECL_LINK}$ | ${BEST_SUMMARY(obj=typedecl)}$ |
+
+#!
+
+
+^ Structures ^^
+
+| ${TYPEDECL_LINK}$ | ${BEST_SUMMARY(obj=typedecl)}$ |
+
+#!
+
+
+^ Enumerations ^^
+
+| ${TYPEDECL_LINK}$ | ${BEST_SUMMARY(obj=typedecl)}$ |
+
+
+
+
diff --git a/src/scripts/gendoc/doc_struct.template b/src/scripts/gendoc/doc_struct.template
new file mode 100644
index 0000000000..370e9be6e9
--- /dev/null
+++ b/src/scripts/gendoc/doc_struct.template
@@ -0,0 +1,39 @@
+doc_macros.include#!
+~~Title: ${struct.full_name}$~~
+====== ${struct.full_name}$ (struct) ======
+
+${BEST_SUMMARY(obj=struct)}$
+
+${BEST_DESCRIPTION(obj=struct)}$
+
+${BEST_SINCE(obj=struct)}$
+
+${OBJECT_STATIC_CONTENT(obj=struct, section='description')}$
+
+===== Fields =====
+
+${OBJECT_STATIC_CONTENT(obj=struct, section='fields')}$
+
+
+ * **${field.name}$** - ${BEST_SUMMARY(obj=field)}$
+
+
+===== Signature =====
+
+
+struct ${struct.full_name}$ {
+
+ ${field.name}$: ${field.type.name}$,
+
+}
+
+
+===== C Signature =====
+
+
+typedef struct _${struct.full_name.replace('.', '_')}$ {
+
+ ${field.name}$: **TODO (issue with Typedecl.c_type need Unit)**,
+
+} ${struct.full_name.replace('.', '_')}$;
+
diff --git a/src/scripts/gendoc/gendoc.py b/src/scripts/gendoc/gendoc.py
new file mode 100755
index 0000000000..394c641f44
--- /dev/null
+++ b/src/scripts/gendoc/gendoc.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python3
+# encoding: utf-8
+"""
+Efl documentation generator
+
+Use this script without arguments to generate the full documentation of the Efl
+namespace in a folder called 'dokuwiki' (-v to see all generated files)
+
+ --help to see all other options
+
+"""
+import os
+import sys
+import argparse
+import atexit
+
+
+# Use .eo files from the source tree (not the installed ones)
+script_path = os.path.dirname(os.path.realpath(__file__))
+root_path = os.path.abspath(os.path.join(script_path, '..', '..', '..'))
+SCAN_FOLDER = os.path.join(root_path, 'src', 'lib')
+
+
+# Use pyolian from source (not installed)
+pyolian_path = os.path.join(root_path, 'src', 'scripts')
+sys.path.insert(0, pyolian_path)
+from pyolian import eolian
+from pyolian.generator import Template
+
+
+# parse args
+parser = argparse.ArgumentParser(description='Pyolian DocuWiki generator.')
+parser.add_argument('--root-path', '-r', metavar='FOLDER', default='dokuwiki',
+ help='where to write files to (root of dokuwiki) '
+ 'default to: "./dokuwiki"')
+parser.add_argument('--verbose', '-v', action='store_true',
+ help='print a line for each rendered file')
+parser.add_argument('--namespace', '-n', metavar='ROOT', default='Efl',
+ help='root namespace of the docs. (default to "Efl")')
+_choices = ['start', 'classes', 'enums', 'structs', 'aliases']
+parser.add_argument('--step', '-s', metavar='STEP', default=None,
+ choices=_choices,
+ help='A single step to run (default to all), '
+ 'valid choises: '+ ', '.join(_choices))
+args = parser.parse_args()
+
+
+# load the whole eolian db (from .eo files in source tree)
+eolian_db = eolian.Eolian()
+if not isinstance(eolian_db, eolian.Eolian):
+ raise(RuntimeError('Eolian, failed to create Eolian state'))
+
+if not eolian_db.directory_scan(SCAN_FOLDER):
+ raise(RuntimeError('Eolian, failed to scan source directory'))
+
+if not eolian_db.all_eot_files_parse():
+ raise(RuntimeError('Eolian, failed to parse all EOT files'))
+
+if not eolian_db.all_eo_files_parse():
+ raise(RuntimeError('Eolian, failed to parse all EO files'))
+
+
+# cleanup the database on exit
+def cleanup_db():
+ global eolian_db
+ del eolian_db
+atexit.register(cleanup_db)
+
+
+# calculate the full path for the txt page of the given object
+def page_path_for_object(obj):
+ path = ['data', 'pages', 'develop', 'api']
+ for ns in obj.namespaces:
+ path.append(ns.lower())
+ output_file = obj.name.lower() + '.txt'
+ return os.path.join(args.root_path, *path, output_file)
+
+
+# render the main start.txt page
+if args.step in ('start', None):
+ t = Template('doc_start.template')
+ output_file = os.path.join(args.root_path,'data','pages','develop','api','start.txt')
+ t.render(output_file, args.verbose, nspaces=eolian_db.all_namespaces)
+
+# render a page for each Class
+if args.step in ('classes', None):
+ t = Template('doc_class.template')
+ for cls in eolian_db.all_classes:
+ if cls.full_name.startswith(args.namespace):
+ output_file = page_path_for_object(cls)
+ t.render(output_file, args.verbose, cls=cls.full_name)
+
+# render a page for each Enum
+if args.step in ('enums', None):
+ t = Template('doc_enum.template')
+ for enum in eolian_db.typedecl_all_enums:
+ if enum.full_name.startswith(args.namespace):
+ output_file = page_path_for_object(enum)
+ t.render(output_file, args.verbose, enum=enum.full_name)
+
+# render a page for each Struct
+if args.step in ('structs', None):
+ t = Template('doc_struct.template')
+ for struct in eolian_db.typedecl_all_structs:
+ if struct.full_name.startswith(args.namespace):
+ output_file = page_path_for_object(struct)
+ t.render(output_file, args.verbose, struct=struct.full_name)
+
+# render a page for each Alias
+if args.step in ('aliases', None):
+ t = Template('doc_alias.template')
+ for alias in eolian_db.typedecl_all_aliases:
+ if alias.full_name.startswith(args.namespace):
+ output_file = page_path_for_object(alias)
+ t.render(output_file, args.verbose, alias=alias.full_name)