diff --git a/docs/docs_writer.py b/docs/docs_writer.py index 9eec6cd7..82241a48 100644 --- a/docs/docs_writer.py +++ b/docs/docs_writer.py @@ -28,6 +28,7 @@ class DocsWriter: self.table_columns = 0 self.table_columns_left = None self.write_copy_script = False + self._script = '' # High level writing def write_head(self, title, relative_css_path): @@ -254,6 +255,12 @@ class DocsWriter: self.write('' .format(text_to_copy, text)) + def add_script(self, src='', relative_src=None): + if relative_src: + self._script += ''.format(relative_src) + elif src: + self._script += ''.format(src) + def end_body(self): """Ends the whole document. This should be called the last""" if self.write_copy_script: @@ -268,7 +275,9 @@ class DocsWriter: 'catch(e){}}' '') - self.write('') + self.write('') + self.write(self._script) + self.write('') # "Low" level writing def write(self, s): diff --git a/docs/generate.py b/docs/generate.py index 4feb1518..ae2bd43c 100755 --- a/docs/generate.py +++ b/docs/generate.py @@ -224,6 +224,16 @@ def get_description(arg): return ' '.join(desc) +def copy_replace(src, dst, replacements): + """Copies the src file into dst applying the replacements dict""" + with open(src) as infile, open(dst, 'w') as outfile: + outfile.write(re.sub( + '|'.join(re.escape(k) for k in replacements), + lambda m: str(replacements[m.group(0)]), + infile.read() + )) + + def generate_documentation(scheme_file): """Generates the documentation HTML files from from scheme.tl to /methods and /constructors, etc. @@ -231,6 +241,7 @@ def generate_documentation(scheme_file): original_paths = { 'css': 'css/docs.css', 'arrow': 'img/arrow.svg', + 'search.js': 'js/search.js', '404': '404.html', 'index_all': 'index.html', 'index_types': 'types/index.html', @@ -366,6 +377,10 @@ def generate_documentation(scheme_file): else: docs.write_text('This type has no members.') + # TODO Bit hacky, make everything like this? (prepending '../') + depth = '../' * (2 if tlobject.namespace else 1) + docs.add_script(src='prependPath = "{}";'.format(depth)) + docs.add_script(relative_src=paths['search.js']) docs.end_body() # Find all the available types (which are not the same as the constructors) @@ -540,36 +555,31 @@ def generate_documentation(scheme_file): type_urls = fmt(types, get_path_for_type) constructor_urls = fmt(constructors, get_create_path_for) - replace_dict = { - 'type_count': len(types), - 'method_count': len(methods), - 'constructor_count': len(tlobjects) - len(methods), - 'layer': layer, - - 'request_names': request_names, - 'type_names': type_names, - 'constructor_names': constructor_names, - 'request_urls': request_urls, - 'type_urls': type_urls, - 'constructor_urls': constructor_urls - } - shutil.copy('../res/404.html', original_paths['404']) - - with open('../res/core.html') as infile,\ - open(original_paths['index_all'], 'w') as outfile: - text = infile.read() - for key, value in replace_dict.items(): - text = text.replace('{' + key + '}', str(value)) - - outfile.write(text) + copy_replace('../res/core.html', original_paths['index_all'], { + '{type_count}': len(types), + '{method_count}': len(methods), + '{constructor_count}': len(tlobjects) - len(methods), + '{layer}': layer, + }) + os.makedirs(os.path.abspath(os.path.join( + original_paths['search.js'], os.path.pardir + )), exist_ok=True) + copy_replace('../res/js/search.js', original_paths['search.js'], { + '{request_names}': request_names, + '{type_names}': type_names, + '{constructor_names}': constructor_names, + '{request_urls}': request_urls, + '{type_urls}': type_urls, + '{constructor_urls}': constructor_urls + }) # Everything done print('Documentation generated.') def copy_resources(): - for d in ['css', 'img']: + for d in ('css', 'img'): os.makedirs(d, exist_ok=True) shutil.copy('../res/img/arrow.svg', 'img') diff --git a/docs/res/core.html b/docs/res/core.html index 368a04d5..0d1673aa 100644 --- a/docs/res/core.html +++ b/docs/res/core.html @@ -14,34 +14,7 @@
- - - -
- - -
Methods (0) -
    -
-
- -
Types (0) -
    -
-
- -
Constructors (0) -
    -
-
-
- -
+

Telethon API

This documentation was generated straight from the scheme.tl provided by Telegram. However, there is no official documentation per se @@ -167,137 +140,6 @@ users.getUsers#0d91a548 id:Vector<InputUser> = Vector<User> here.

- -
- + diff --git a/docs/res/js/search.js b/docs/res/js/search.js new file mode 100644 index 00000000..c63672e7 --- /dev/null +++ b/docs/res/js/search.js @@ -0,0 +1,172 @@ +root = document.getElementById("main_div"); +root.innerHTML = ` + + + +
+ + +
Methods (0) + +
+ +
Types (0) + +
+ +
Constructors (0) + +
+
+
+` + root.innerHTML + "
"; + +// HTML modified, now load documents +contentDiv = document.getElementById("contentDiv"); +searchDiv = document.getElementById("searchDiv"); +searchBox = document.getElementById("searchBox"); + +// Search lists +methodsList = document.getElementById("methodsList"); +methodsCount = document.getElementById("methodsCount"); + +typesList = document.getElementById("typesList"); +typesCount = document.getElementById("typesCount"); + +constructorsList = document.getElementById("constructorsList"); +constructorsCount = document.getElementById("constructorsCount"); + +// Exact match +exactMatch = document.getElementById("exactMatch"); +exactList = document.getElementById("exactList"); + +try { + requests = [{request_names}]; + types = [{type_names}]; + constructors = [{constructor_names}]; + + requestsu = [{request_urls}]; + typesu = [{type_urls}]; + constructorsu = [{constructor_urls}]; +} catch (e) { + requests = []; + types = []; + constructors = []; + requestsu = []; + typesu = []; + constructorsu = []; +} + +if (typeof prependPath !== 'undefined') { + for (var i = 0; i != requestsu.length; ++i) { + requestsu[i] = prependPath + requestsu[i]; + } + for (var i = 0; i != typesu.length; ++i) { + typesu[i] = prependPath + typesu[i]; + } + for (var i = 0; i != constructorsu.length; ++i) { + constructorsu[i] = prependPath + constructorsu[i]; + } +} + +// Given two input arrays "original" and "original urls" and a query, +// return a pair of arrays with matching "query" elements from "original". +// +// TODO Perhaps return an array of pairs instead a pair of arrays (for cache). +function getSearchArray(original, originalu, query) { + var destination = []; + var destinationu = []; + + for (var i = 0; i < original.length; ++i) { + if (original[i].toLowerCase().indexOf(query) != -1) { + destination.push(original[i]); + destinationu.push(originalu[i]); + } + } + + return [destination, destinationu]; +} + +// Modify "countSpan" and "resultList" accordingly based on the elements +// given as [[elements], [element urls]] (both with the same length) +function buildList(countSpan, resultList, foundElements) { + var result = ""; + for (var i = 0; i < foundElements[0].length; ++i) { + result += '
  • '; + result += ''; + result += foundElements[0][i]; + result += '
  • '; + } + + if (countSpan) { + countSpan.innerHTML = "" + foundElements[0].length; + } + resultList.innerHTML = result; +} + +function updateSearch() { + if (searchBox.value) { + contentDiv.style.display = "none"; + searchDiv.style.display = ""; + + var query = searchBox.value.toLowerCase(); + + var foundRequests = getSearchArray(requests, requestsu, query); + var foundTypes = getSearchArray(types, typesu, query); + var foundConstructors = getSearchArray( + constructors, constructorsu, query + ); + + buildList(methodsCount, methodsList, foundRequests); + buildList(typesCount, typesList, foundTypes); + buildList(constructorsCount, constructorsList, foundConstructors); + + // Now look for exact matches + var original = requests.concat(constructors); + var originalu = requestsu.concat(constructorsu); + var destination = []; + var destinationu = []; + + for (var i = 0; i < original.length; ++i) { + if (original[i].toLowerCase().replace("request", "") == query) { + destination.push(original[i]); + destinationu.push(originalu[i]); + } + } + + if (destination.length == 0) { + exactMatch.style.display = "none"; + } else { + exactMatch.style.display = ""; + buildList(null, exactList, [destination, destinationu]); + } + } else { + contentDiv.style.display = ""; + searchDiv.style.display = "none"; + } +} + +function getQuery(name) { + var query = window.location.search.substring(1); + var vars = query.split("&"); + for (var i = 0; i != vars.length; ++i) { + var pair = vars[i].split("="); + if (pair[0] == name) + return pair[1]; + } +} + +var query = getQuery('q'); +if (query) { + searchBox.value = query; +} + +updateSearch();