diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3b4bbc2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,28 @@ +BSD 3-Clause License + +Copyright (c) 2026, Julian Müller (ChaoticByte) + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md index 7be99fe..0432241 100644 --- a/README.md +++ b/README.md @@ -1,97 +1,68 @@ -# mint - Minimal Text Markup +# MINT - Minimal Text Markup -Mint is a minimal text markup language that can be compiled to html. +MINT is a minimal text markup language that can be compiled to html. -As of version 0.1, mint supports - - - comments - - headings - - subheadings - - italic text - - bold text - - underline text - - keep whitespaces (html `
`)
-    - manual line breaks (html `br`)
+For a syntax- and feature-overview, have a look at [Quick Reference](#quick-reference).
 
 
-# Syntax
+# Markup
+
+Version 2
 
 > [!NOTE]  
 > See `example.mint` for a working usage example.
 
-Like HTML, Mint uses tags to style documents.
+Like HTML, MINT uses tags to style documents.
 A tag consists of a forward slash `/`, one letter (e.g. `b`) and another forward slash.
 Tags toggle a style, so you can start bold text with `/b/` and end it with `/b/`.
 
-## Comments
 
-```
-/#/This is a comment/#/
-```
-> [!WARNING]  
-> Comments aren't compiled into html comments, but skipped!
+## Quick Reference
 
-
-## Headings and Sub-headings
-
-```
-/h/Heading/h/
-
-/s/Subheading/s/
-```
-
-Headings are compiled into `

`, subheadings into `

`. - - -## Bold, italic and underlined text - -``` -Text can be /b/bold/b/, /i/italic/i/ and /u/underlined/u/, or /b//i//u/everything at once/b//i//u/. -``` - -## Keep whitespaces - -Whitespaces (spaces, newlines, etc.) won't get rendered in HTML. -To preserve whitespaces, use - -``` -/e/ -This text - will be indented. -/e/ -``` - -## Newlines - -You can insert newlines with - -``` -/l/ -``` - -> [!NOTE] -> This tag cannot be closed. - - -## Escape slashes - -If you want to write a `/`, use a - -``` -// -``` +| Markup | HTML | Meaning | +| :---------: | :--------------: | ---------------------- | +| `/#/.../#/` | | Comment (**not compiled into HTML!**) | +| `/p/.../p/` | `

...

` | Paragraph | +| `/q/.../q/` | `
...
` | Blockquote | +| `/h/.../h/` | `

...

` | Heading | +| `/s/.../s/` | `

...

` | Subheading | +| `/i/.../i/` | `...` | _Italic text_ | +| `/b/.../b/` | `...` | **Bold text** | +| `/u/.../u/` | `...` | Underlined text | +| `/d/.../d/` | `...` | ~~Deleted text~~ | +| `/e/.../e/` | `
...
` | Keep whitespaces (spaces, new lines, ...) | +| `/...` | Switch to left text-alignment | +| `/\|/...` | `
...` | Switch to center text-alignment | +| `/>/...` | `
...` | Switch to right text-alignment | +| `/=/...` | `
...` | Switch to justified text-alignment | +| `/l/` | `
` | Line-break (new line) | +| `//` | `/` | Escape a forward slash | # Converter -To convert mint to html, use `mint2html.py`. +To convert MINT to HTML, use the `mint2html.py` command-line tool. -Example: -``` +## Supported platforms + +I develop and test on **Linux** with **Python 3.13**, so the code should generally run on Unix-based systems. + +There is no code implemented that only works on Unix systems, so it _should_ work on Microslop Windows, although I'm too lazy to test this. + + +## Example + +```bash ./mint2html.py -i input_file.mint -o output_file.html ``` You can also omit the input/output files to read from stdin/output to stdout. Use `mint2html.py --help` to view the full help text. + +Tip: If you are in a bash shell, and have pandoc installed, you can pipe the output of mint2html.py directly into pandoc, e.g.: + +```bash +./mint2html.py --input-file example.mint --minify | pandoc --from html -o example.epub +``` diff --git a/example.mint b/example.mint index ef78daf..8b56f71 100644 --- a/example.mint +++ b/example.mint @@ -3,34 +3,64 @@ /#/ Example comment /#/ + +Per default, text is aligned left +/|/ +but you can also center it +/>/ +or align it to the right. + +/#/ put a newline: /#/ + +// +bye :) diff --git a/mint2html.py b/mint2html.py index daa5f57..c69e74c 100755 --- a/mint2html.py +++ b/mint2html.py @@ -1,7 +1,9 @@ #!/usr/bin/env python3 -# Copyright 2026 ChaoticByte (Julian Müller) -# pylint: disable=line-too-long,missing-module-docstring,missing-class-docstring,missing-function-docstring +# Copyright (c) 2026, Julian Müller (ChaoticByte) +# Licensed under the BSD 3-Clause License + +# pylint: disable=line-too-long,missing-module-docstring,missing-class-docstring,missing-function-docstring,invalid-name from html import escape from pathlib import Path @@ -40,14 +42,18 @@ class ConverterState: # wether this cycle actually converted something: cycle_had_op = False - # (in)active styles/formats + # (in)active styles/formats/blocks comment = False + paragraph = False + blockquote = False heading = False subheading = False italic = False bold = False underline = False + strike_through = False whitespace_pre = False + alignment = "" # left: < center: | right > justify: = def complete_cycle(self): self.pos += self.pos_offset @@ -64,14 +70,26 @@ class MintToHtmlConverter: '''A simple converter from Mint to HTML Currently supports: - - comments /#/ - - heading /h/ - - subheading /s/ - - italic /i/ - - bold /b/ - - underline /u/ - - keep whitespaces /e/ - - line breaks /l/ + - comments /#/ + + - paragraphs /p/ + - block quotes /q/ + + - headings /h/ + - subheadings /s/ + + - italic /i/ + - bold /b/ + - underline /u/ + - deleted (strike-through) /d/ + + - align to left // + - align justified /=/ + + - keep whitespaces /e/ + - line breaks /l/ ''' def __init__( @@ -81,24 +99,38 @@ class MintToHtmlConverter: ): self.escape_html = escape_html self.css = css + self.comment_tag = MintTagToHtml("#", None, "comment") self.tags = [ - MintTagToHtml("#", None, "comment"), + self.comment_tag, + MintTagToHtml("p", "p", "paragraph"), + MintTagToHtml("q", "blockquote", "blockquote"), MintTagToHtml("h", "h1", "heading"), MintTagToHtml("s", "h2", "subheading"), MintTagToHtml("i", "i", "italic"), MintTagToHtml("b", "b", "bold"), MintTagToHtml("u", "u", "underline"), + MintTagToHtml("d", "s", "strike_through"), MintTagToHtml("e", "pre", "whitespace_pre"), MintTagToHtml("l", "br", None) ] + self.alignments = { + "<": "left", + "|": "center", + ">": "right", + "=": "justify" + } def __call__(self, text_in: str, ) -> str: '''Convert mint to html''' # replace unwanted characters text_in = text_in.replace("\r", "") # html escape + text_in = text_in.replace("//", "/ralgn/") if self.escape_html: text_in = escape(text_in) + text_in = text_in.replace("/lalgn/", "//") # parsing & conversion state = ConverterState() @@ -134,7 +166,7 @@ class MintToHtmlConverter: break c1 = text_in[state.pos + 1] if c == TAG_BOUNDARY: - if c1 == TAG_BOUNDARY: + if c1 == TAG_BOUNDARY and not state.comment: # e.g. // -> / state.pos_offset += 1 state.add_output(TAG_BOUNDARY) @@ -143,14 +175,27 @@ class MintToHtmlConverter: if state.pos + 2 < len_text_in: c2 = text_in[state.pos + 2] if c2 == TAG_BOUNDARY: - # process tags - for t in self.tags: - process_inline_tag(c1, state, t) + if state.comment: + process_inline_tag(c1, state, self.comment_tag) + else: + for t in self.tags: + process_inline_tag(c1, state, t) + # toggle alignment + if c1 in self.alignments: + state.pos_offset += 2 + if state.alignment == c1: + pass + elif state.alignment != "": + state.add_output("
") + state.add_output(f"
") + state.alignment = c1 if not state.cycle_had_op and not state.comment: state.output += c # complete this cycle's state state.complete_cycle() # cleanup + if state.alignment != "": + state.add_output("
") state.output = state.output.strip() # return result return state.output @@ -160,7 +205,7 @@ if __name__ == "__main__": from argparse import ArgumentParser argp = ArgumentParser() - argp.add_argument("-i", "--input-file", help="Input file (will read from stdin until eof when omitted)", type=Path, required=False) + argp.add_argument("-i", "--input-file", help="Input file(s) (will read from stdin until eof when omitted)", type=Path, required=False, nargs="*") argp.add_argument("-o", "--output-file", help="Output file (will print to stdout when omitted)", type=Path, required=False) argp.add_argument("--css", help="Add css to the html output", type=str, default="") argp.add_argument("--no-escape-html", help="Don't escape html in the input", action="store_true") @@ -176,11 +221,14 @@ if __name__ == "__main__": input_lines = [] for l in stdin: input_lines.append(l) - input_text = "\n".join(input_lines) # pylint: disable=invalid-name + input_text = "\n".join(input_lines) del input_lines else: - log(f"Reading text from {str(args.input_file)} ...") - input_text = args.input_file.read_text() + log(f"Reading text from {str([str(f) for f in args.input_file])} ...") + inputs = [] + for f in args.input_file: + inputs.append(f.read_text()) + input_text = "\n".join(inputs) log("Converting text ...") output_document = MintToHtmlConverter( @@ -191,7 +239,7 @@ if __name__ == "__main__": if args.minify_html: log("Minifying html output ...") import minify_html - output_document = minify_html.minify(output_document) + output_document = minify_html.minify(output_document) # pylint: disable=no-member if args.output_file is None: log("Writing output to stdout ...")