From 1aa26c06ef46407b1ff23fc351c28c4b3ea5098f Mon Sep 17 00:00:00 2001 From: klemek Date: Fri, 1 May 2020 22:24:41 +0200 Subject: [PATCH] update of docs --- docs/README-template.md | 164 ++++++++++++++++++++++++++++++++++++++++ docs/README.md | 121 +++++++++++++++++++++++++---- docs/build.py | 97 +++++++++++++++++------- 3 files changed, 340 insertions(+), 42 deletions(-) create mode 100644 docs/README-template.md diff --git a/docs/README-template.md b/docs/README-template.md new file mode 100644 index 0000000..1283b23 --- /dev/null +++ b/docs/README-template.md @@ -0,0 +1,164 @@ +# Meme-Otron guide + +* [Commands](#commands) + * [Simple use](#simple-use) + * [Advanced use](#advanced-use) + * [Discord features](#discord-features) + * [CLI features](#cli-features) +* [List of templates](#list-of-templates) + * [Standard Templates](#standard-templates) + * [Reactions (no text)](#reactions-no-text) +* [Examples](#examples) + * [Example 1: Simple template](#example-1-simple-template) + * [Example 2: Use of empty texts](#example-2-use-of-empty-texts) + * [Example 3: Text + Template](#example-3-text--template) + * [Example 4: Complex composition](#example-4-complex-composition) + + +## Commands + +### Simple use +[↑ back to top](#meme-otron-guide) + +You can generate memes by using the following arguments: + +``` +[meme id] "text1" "text2" ... +``` + +Depending of the number of `"text"` arguments, several behavior occurs: +* **None**: you get the template that gives you the locations of texts. (see below) +* **Less than the template's**: the remaining texts are blank on the output +* **More than the template's**: the extra arguments are ignored + +> Notes +> * You don't have to use all texts shown on the templates +> * You can use an empty text argument ( `""` ) to skip a text and keep it blank + +See [Examples](#examples) to get an idea of how to use it. + +### Advanced use +[↑ back to top](#meme-otron-guide) + +Since version 1.3, Meme-Otron allows you to "pipe" parts in order to compose more advanced memes. The syntax is as follows: + +``` +[part1] - [part2] - ... +``` + +Each part can be one of the following: + +* A template: as described in [Simple use](#simple-use) +* Texts: ```text "text 1" "text 2" ...``` + * Black Arial texts on white background + * Each text is it's own paragraph +* Images: ```image ``` + * Takes an image from input or an URL (optional) + * Input depends on the system: + * the Discord bot takes the attachment + * the CLI takes stdin or `--input` argument. + +> Notes +> * Input of `image` is always the same, don't expect multiple instances of `image` to get different results if you don't indicate an URL + +See [Examples](#examples) to get an idea of how to use it. + +### Discord features +[↑ back to top](#meme-otron-guide) + +Tag the bot and use the above syntax to get started. In addition, you can use the following commands: + +* Use `help` to get a simple help message +* Use `list` to get a list of all meme ids +* Use `delete` to delete the last message sent by the bot (directed to you) + +To get the template info, just send the meme id without texts. + +> Tip : You can use `\\n` in your texts to add a line break + +Enjoy the full experience of this bot by using direct messages to keep your server free of spam. + +### CLI features +[↑ back to top](#meme-otron-guide) + +In this project directory, you can simply call: +``` +python -m meme_otron [meme id] "text1" "text2" ... > output.jpg +``` +Without pipe redirection with `-o [output]`: +``` +python -m meme_otron -o output.png [meme id] "text1" "text2" ... +``` + +You can even pipe input images like this: +``` +python -m meme_otron [arguments] < input.jpg > output.jpg +``` + +Available arguments: +* `--help` / `-h` + * Show a simple guide +* `--output [file]` / `-o [file]` + * Output file, you are free to choose the format +* `--input [file]` / `-i [file]` + * Input file used for `image` +* `-nw` / `--no-watermark` + * Removes the watermark +* `-d` / `--debug` + * Add more info to output like a box show the texts boundaries +* `-v` / `--verbose` + * Add more logging + + +## List of templates +[↑ back to top](#meme-otron-guide) + +You can find here the full list of templates. +Each one has extra info and an image showing how texts are placed. +Click on an image to enlarge it. + +### Standard Templates +[↑ back to top](#meme-otron-guide) + + + + + +### Reactions (no text) +[↑ back to top](#meme-otron-guide) + + + + + + +## Examples + +### Example 1: Simple template +[↑ back to top](#meme-otron-guide) + + + + + +### Example 2: Use of empty texts +[↑ back to top](#meme-otron-guide) + + + + + +### Example 3: Text + template +[↑ back to top](#meme-otron-guide) + + + + + + +### Example 4: Complex composition +[↑ back to top](#meme-otron-guide) + + + + \ No newline at end of file diff --git a/docs/README.md b/docs/README.md index 89a8212..1283b23 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,12 +1,25 @@ +# Meme-Otron guide + * [Commands](#commands) -* [Discord features](#discord-features) -* [CLI features](#cli-features) + * [Simple use](#simple-use) + * [Advanced use](#advanced-use) + * [Discord features](#discord-features) + * [CLI features](#cli-features) * [List of templates](#list-of-templates) -* [List of reactions](#list-of-templates) + * [Standard Templates](#standard-templates) + * [Reactions (no text)](#reactions-no-text) +* [Examples](#examples) + * [Example 1: Simple template](#example-1-simple-template) + * [Example 2: Use of empty texts](#example-2-use-of-empty-texts) + * [Example 3: Text + Template](#example-3-text--template) + * [Example 4: Complex composition](#example-4-complex-composition) ## Commands +### Simple use +[↑ back to top](#meme-otron-guide) + You can generate memes by using the following arguments: ``` @@ -22,7 +35,36 @@ Depending of the number of `"text"` arguments, several behavior occurs: > * You don't have to use all texts shown on the templates > * You can use an empty text argument ( `""` ) to skip a text and keep it blank -## Discord features +See [Examples](#examples) to get an idea of how to use it. + +### Advanced use +[↑ back to top](#meme-otron-guide) + +Since version 1.3, Meme-Otron allows you to "pipe" parts in order to compose more advanced memes. The syntax is as follows: + +``` +[part1] - [part2] - ... +``` + +Each part can be one of the following: + +* A template: as described in [Simple use](#simple-use) +* Texts: ```text "text 1" "text 2" ...``` + * Black Arial texts on white background + * Each text is it's own paragraph +* Images: ```image ``` + * Takes an image from input or an URL (optional) + * Input depends on the system: + * the Discord bot takes the attachment + * the CLI takes stdin or `--input` argument. + +> Notes +> * Input of `image` is always the same, don't expect multiple instances of `image` to get different results if you don't indicate an URL + +See [Examples](#examples) to get an idea of how to use it. + +### Discord features +[↑ back to top](#meme-otron-guide) Tag the bot and use the above syntax to get started. In addition, you can use the following commands: @@ -36,7 +78,8 @@ To get the template info, just send the meme id without texts. Enjoy the full experience of this bot by using direct messages to keep your server free of spam. -## CLI features +### CLI features +[↑ back to top](#meme-otron-guide) In this project directory, you can simply call: ``` @@ -47,25 +90,75 @@ Without pipe redirection with `-o [output]`: python -m meme_otron -o output.png [meme id] "text1" "text2" ... ``` -> Note: with `-o`, you are free to choose the output format +You can even pipe input images like this: +``` +python -m meme_otron [arguments] < input.jpg > output.jpg +``` + +Available arguments: +* `--help` / `-h` + * Show a simple guide +* `--output [file]` / `-o [file]` + * Output file, you are free to choose the format +* `--input [file]` / `-i [file]` + * Input file used for `image` +* `-nw` / `--no-watermark` + * Removes the watermark +* `-d` / `--debug` + * Add more info to output like a box show the texts boundaries +* `-v` / `--verbose` + * Add more logging + ## List of templates +[↑ back to top](#meme-otron-guide) You can find here the full list of templates. Each one has extra info and an image showing how texts are placed. Click on an image to enlarge it. +### Standard Templates +[↑ back to top](#meme-otron-guide) - + - + -## List of reactions +### Reactions (no text) +[↑ back to top](#meme-otron-guide) -You can find here the full list of reactions (templates without texts). -Each one has extra info. -Click on an image to enlarge it. + - + - + +## Examples + +### Example 1: Simple template +[↑ back to top](#meme-otron-guide) + + + + + +### Example 2: Use of empty texts +[↑ back to top](#meme-otron-guide) + + + + + +### Example 3: Text + template +[↑ back to top](#meme-otron-guide) + + + + + + +### Example 4: Complex composition +[↑ back to top](#meme-otron-guide) + + + + \ No newline at end of file diff --git a/docs/build.py b/docs/build.py index 85c8202..ca3e3a8 100644 --- a/docs/build.py +++ b/docs/build.py @@ -1,10 +1,12 @@ import os import logging +from typing import List import PIL from os import path from meme_otron import img_factory from meme_otron import meme_db from meme_otron import utils +from meme_otron import meme_otron logging.basicConfig(format="[%(asctime)s][%(levelname)s][%(module)s] %(message)s", level=logging.WARNING) @@ -13,12 +15,58 @@ meme_db.load_memes() templates_dir = utils.relative_path(__file__, "templates") preview_dir = utils.relative_path(__file__, "preview") +doc_template_file = utils.relative_path(__file__, "README-template.md") doc_file = utils.relative_path(__file__, "README.md") COLUMNS = 3 IMG_HEIGHT = 400 +def main(): + make_empty(templates_dir) + make_empty(preview_dir) + + with open(doc_template_file, mode='r') as f: + content = "".join(f.readlines()) + + full_list = sorted(meme_db.LIST) + template_list = [meme_id for meme_id in full_list if len(meme_db.get_meme(meme_id).texts) > 0] + reaction_list = [meme_id for meme_id in full_list if meme_id not in template_list] + + content = produce_template_list(content, "LIST1", template_list) + content = produce_template_list(content, "LIST2", reaction_list) + + content = produce_example(content, "EXAMPLE1", "example1.jpg", "", + "brain3", + "Making memes using an image editor", + "Making memes using a Python script", + "Making memes using a Discord bot") + + content = produce_example(content, "EXAMPLE2", "example2.jpg", + "The 5th text is not set and the 3rd is explicitly set to empty", + "see_that_guy", + "See that guy over there?", + "He uses an image editor to make memes", + "", + "meme-otron dev") + + content = produce_example(content, "EXAMPLE3", "example3.jpg", + "Note how texts make paragraphs", + "text", + "*Meme has a 'made with meme-otron' watermark*", + "reddit: ...", + "9gag: ...", + "meme-otron dev:", + "-", + "culture", + "meme otron") + + # TODO example 4 : complex composition + + with open(doc_file, mode='w') as f: + f.write(content) + + def make_empty(target_dir: str): if path.exists(target_dir): for file in os.listdir(target_dir): @@ -28,13 +76,9 @@ def make_empty(target_dir: str): os.mkdir(target_dir) -make_empty(templates_dir) -make_empty(preview_dir) - - -def produce_doc(id_list): +def produce_template_list(content: str, tag: str, id_list: List[str]): if len(id_list) == 0: - return "" + return content doc_content = "|" * (COLUMNS + 1) \ + "\n|" + ":---:|" * COLUMNS info_line = None @@ -65,31 +109,28 @@ def produce_doc(id_list): f"|" print(i, meme_id) doc_content += "|" * (COLUMNS - (i % COLUMNS)) - return doc_content + return inject_content(doc_content, content, tag) -full_list = sorted(meme_db.LIST) -template_list = [meme_id for meme_id in full_list if len(meme_db.get_meme(meme_id).texts) > 0] -reaction_list = [meme_id for meme_id in full_list if meme_id not in template_list] +def produce_example(content: str, tag: str, file_name: str, note: str, *args: str): + doc_content = f"> {note}\n\n" \ + "```\n" + \ + " \n".join(['"' + a + '"' if ' ' in a or len(a) == 0 else a for a in args]) + \ + "\n```\n\n" \ + f"![]({file_name})" + img, err = meme_otron.compute(*args) + if img is not None: + img.save(utils.relative_path(__file__, file_name)) + return inject_content(doc_content, content, tag) -doc_content1 = produce_doc(template_list) -doc_content2 = produce_doc(reaction_list) -with open(doc_file, mode='r') as f: - content = "".join(f.readlines()) +def inject_content(new_content, content, tag): + start_str = f"" + end_str = f"" + i0 = content.index(start_str) + i1 = content.index(end_str) + len(end_str) + return content[:i0] + start_str + "\n" + new_content + "\n" + end_str + content[i1:] -i0 = content.index("") -i1 = content.index("") + len("") -i2 = content.index("") -i3 = content.index("") + len("") -with open(doc_file, mode='w') as f: - f.write(content[:i0]) - f.write("\n") - f.write(doc_content1) - f.write("\n") - f.write(content[i1:i2]) - f.write("\n") - f.write(doc_content2) - f.write("\n") - f.write(content[i3:]) +if __name__ == '__main__': + main()