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""
+ 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()