update of docs

This commit is contained in:
klemek
2020-05-01 22:24:41 +02:00
parent 6444a6e58d
commit 1aa26c06ef
3 changed files with 340 additions and 42 deletions
+164
View File
@@ -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
<sub><sup>[↑ back to top](#meme-otron-guide)</sup></sub>
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
<sub><sup>[↑ back to top](#meme-otron-guide)</sup></sub>
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 <URL>```
* 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
<sub><sup>[↑ back to top](#meme-otron-guide)</sup></sub>
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
<sub><sup>[↑ back to top](#meme-otron-guide)</sup></sub>
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
<sub><sup>[↑ back to top](#meme-otron-guide)</sup></sub>
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
<sub><sup>[↑ back to top](#meme-otron-guide)</sup></sub>
<!--LIST1-START-->
<!--LIST1-END-->
### Reactions (no text)
<sub><sup>[↑ back to top](#meme-otron-guide)</sup></sub>
<!--LIST2-START-->
<!--LIST2-END-->
## Examples
### Example 1: Simple template
<sub><sup>[↑ back to top](#meme-otron-guide)</sup></sub>
<!--EXAMPLE1-START-->
<!--EXAMPLE1-END-->
### Example 2: Use of empty texts
<sub><sup>[↑ back to top](#meme-otron-guide)</sup></sub>
<!--EXAMPLE2-START-->
<!--EXAMPLE2-END-->
### Example 3: Text + template
<sub><sup>[↑ back to top](#meme-otron-guide)</sup></sub>
<!--EXAMPLE3-START-->
<!--EXAMPLE3-END-->
### Example 4: Complex composition
<sub><sup>[↑ back to top](#meme-otron-guide)</sup></sub>
<!--EXAMPLE4-START-->
<!--EXAMPLE4-END-->
+107 -14
View File
@@ -1,12 +1,25 @@
# Meme-Otron guide
* [Commands](#commands) * [Commands](#commands)
* [Discord features](#discord-features) * [Simple use](#simple-use)
* [CLI features](#cli-features) * [Advanced use](#advanced-use)
* [Discord features](#discord-features)
* [CLI features](#cli-features)
* [List of templates](#list-of-templates) * [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 ## Commands
### Simple use
<sub><sup>[↑ back to top](#meme-otron-guide)</sup></sub>
You can generate memes by using the following arguments: 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 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 > * 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
<sub><sup>[↑ back to top](#meme-otron-guide)</sup></sub>
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 <URL>```
* 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
<sub><sup>[↑ back to top](#meme-otron-guide)</sup></sub>
Tag the bot and use the above syntax to get started. In addition, you can use the following commands: 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. Enjoy the full experience of this bot by using direct messages to keep your server free of spam.
## CLI features ### CLI features
<sub><sup>[↑ back to top](#meme-otron-guide)</sup></sub>
In this project directory, you can simply call: 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" ... 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 ## List of templates
<sub><sup>[↑ back to top](#meme-otron-guide)</sup></sub>
You can find here the full list of templates. You can find here the full list of templates.
Each one has extra info and an image showing how texts are placed. Each one has extra info and an image showing how texts are placed.
Click on an image to enlarge it. Click on an image to enlarge it.
### Standard Templates
<sub><sup>[↑ back to top](#meme-otron-guide)</sup></sub>
<!--START1--> <!--LIST1-START-->
<!--END1--> <!--LIST1-END-->
## List of reactions ### Reactions (no text)
<sub><sup>[↑ back to top](#meme-otron-guide)</sup></sub>
You can find here the full list of reactions (templates without texts). <!--LIST2-START-->
Each one has extra info.
Click on an image to enlarge it.
<!--START2--> <!--LIST2-END-->
<!--END2-->
## Examples
### Example 1: Simple template
<sub><sup>[↑ back to top](#meme-otron-guide)</sup></sub>
<!--EXAMPLE1-START-->
<!--EXAMPLE1-END-->
### Example 2: Use of empty texts
<sub><sup>[↑ back to top](#meme-otron-guide)</sup></sub>
<!--EXAMPLE2-START-->
<!--EXAMPLE2-END-->
### Example 3: Text + template
<sub><sup>[↑ back to top](#meme-otron-guide)</sup></sub>
<!--EXAMPLE3-START-->
<!--EXAMPLE3-END-->
### Example 4: Complex composition
<sub><sup>[↑ back to top](#meme-otron-guide)</sup></sub>
<!--EXAMPLE4-START-->
<!--EXAMPLE4-END-->
+69 -28
View File
@@ -1,10 +1,12 @@
import os import os
import logging import logging
from typing import List
import PIL import PIL
from os import path from os import path
from meme_otron import img_factory from meme_otron import img_factory
from meme_otron import meme_db from meme_otron import meme_db
from meme_otron import utils 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) 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") templates_dir = utils.relative_path(__file__, "templates")
preview_dir = utils.relative_path(__file__, "preview") 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") doc_file = utils.relative_path(__file__, "README.md")
COLUMNS = 3 COLUMNS = 3
IMG_HEIGHT = 400 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): def make_empty(target_dir: str):
if path.exists(target_dir): if path.exists(target_dir):
for file in os.listdir(target_dir): for file in os.listdir(target_dir):
@@ -28,13 +76,9 @@ def make_empty(target_dir: str):
os.mkdir(target_dir) os.mkdir(target_dir)
make_empty(templates_dir) def produce_template_list(content: str, tag: str, id_list: List[str]):
make_empty(preview_dir)
def produce_doc(id_list):
if len(id_list) == 0: if len(id_list) == 0:
return "" return content
doc_content = "|" * (COLUMNS + 1) \ doc_content = "|" * (COLUMNS + 1) \
+ "\n|" + ":---:|" * COLUMNS + "\n|" + ":---:|" * COLUMNS
info_line = None info_line = None
@@ -65,31 +109,28 @@ def produce_doc(id_list):
f"</a>|" f"</a>|"
print(i, meme_id) print(i, meme_id)
doc_content += "|" * (COLUMNS - (i % COLUMNS)) doc_content += "|" * (COLUMNS - (i % COLUMNS))
return doc_content return inject_content(doc_content, content, tag)
full_list = sorted(meme_db.LIST) def produce_example(content: str, tag: str, file_name: str, note: str, *args: str):
template_list = [meme_id for meme_id in full_list if len(meme_db.get_meme(meme_id).texts) > 0] doc_content = f"> {note}\n\n" \
reaction_list = [meme_id for meme_id in full_list if meme_id not in template_list] "```\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: def inject_content(new_content, content, tag):
content = "".join(f.readlines()) start_str = f"<!--{tag}-START-->"
end_str = f"<!--{tag}-END-->"
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("<!--START1-->")
i1 = content.index("<!--END1-->") + len("<!--END1-->")
i2 = content.index("<!--START2-->")
i3 = content.index("<!--END2-->") + len("<!--END2-->")
with open(doc_file, mode='w') as f: if __name__ == '__main__':
f.write(content[:i0]) main()
f.write("<!--START1-->\n")
f.write(doc_content1)
f.write("\n<!--END1-->")
f.write(content[i1:i2])
f.write("<!--START2-->\n")
f.write(doc_content2)
f.write("\n<!--END2-->")
f.write(content[i3:])