--- /dev/null
+body {
+ font-family: "EB Garamond";
+}
+
+main {
+ width: max(500px, 60vw);
+ padding: 15px;
+ border-left: 1px solid gray;
+ margin: auto;
+}
+
+code {
+ color: white;
+ background-color: black;
+ padding: 1px 4px 1px 4px;
+ border-radius: 4px;
+}
+pre {
+ color: white;
+ background-color: black;
+ padding: 4px 4px 4px 4px;
+ border-radius: 4px;
+}
[TOC]
+# Reasoning
+
+There are currently a number of tools for writing.
+
+- *MS Word* Bloated. Includes unncecicary or distracting features and outputs documents that have a distinct and unplesant look to them. Libre Word alternatives suffer the same problems.
+- *Google Docs* happens on Googles side. You lose everything if they lose everything, or if they decide they need more space. They use documents in Google Docs to train their AI models.
+- *LaTeX*. Complicated and unncecicary for all but the people who are producing complicated and unncecicary works.
+- *Markdown*. Simple and useful for general writing but does not include references. Has some features I would personally regard as unncecicary.
+
+I was important, when designing Goodnight, to think what might be the responsibility of the parser, the stylesheet and the user. For example, although horizontal lines are almost always a common feature in Markdown flavors, I belive it is the responsibility of the stylesheet.
+
# Features
Along with the features below, some features where removed:
## Headings
-Headings are prefixed with the `#` hastag character as with standard markdown. There must not be a space before the `#` character. A space may or may not be put after the `#`. Inline formatting will be properly parsed. Inline references will be properly parsed.
+Headings are prefixed with the `#` hastag character as with standard markdown. There must not be a space before the `#` character. This can go up to five hashtag "levels". For LaTeX, this is: `section`, `subsection`, `subsubsection`, `paragraph` and `subparagraph`. For HTML, although there are normaly six levels of heading (`h1` - `h6`), the first is reserved for the title so "level one" translates to `h2`. Additionally, the title of the heading (lowercase and seperated by hyphens) is used as the anchor text for reference in the table of contents. For gemtext, there are normally no more than 3 levels, of which one is reserved for the title, so only 2 are used. In the case of gemtext, the table of contents will still refelect the sematic order of document up to the normal 5 levels. A space may or may not be put after the `#`. Inline formatting will be properly parsed. Inline references will be properly parsed.
+
+Example:
+
+```
+## Goodnight!
+```
+
+In HTML:
+
+```
+<h3 id="goodnight!">Goodnight!</h3>
+```
+
+In LaTeX:
+
+```
+\subsection{Goodnight!}
+```
+
+In gemtext:
+
+```
+### Goodnight!
+```
## Links
## Paragraphs
-`text about paragraphs`
+A paragraph is any line that does not start with one of the following: `#-.` or `\`\`\`` or one of the macros such as `[TOC]`
-## Images
+## Images & other external files
Still to be implemented
-## Inline code
+## Code
-Inline code blocks can be used with the `\`` backtick character.
-
-## Code blocks
+Inline code blocks can be used with the `\`` backtick character. In LaTeX this becomes `\\texttt{...}`, in html this becomes `<code>...</code>` and in gemtext it is included as written. A bar character cannot currently be used in an inline code block.
Code blocks can be used with 3 backtick characters: `\`\`\``. This sequence must start on the first character on a new line.
The metadata format used is the YAML format. To generate the title, the standard LaTeX keys of "title", "author" and "date", should be used. If "style" is used, the parser will introduce the stylesheet with the relevant extension. For example, `style: stylesheet` will introduce `stylesheet.css` for html and `stylesheet.sty` for LaTeX.
+Example:
+
```
---
-title: The Goodnight Markdown Specification
-author: William Greenwood
+title: The Goodnight Markdown Specification - Version 0.1.0
+author: Goodnight Publishing
+additional_information: This is some additional information
---
```
-### This is a test of the heading levels
+## Referencing
-#### Some further testing
+All referencing in Goodnight is APA 7th. Everything is the reference list is listed in the bibliography, even works not included in the text, so you are resposible for making sure this lines up with your work.
-## Referencing
+Each reference can happen anywhere in the text, begining with the ID for the reference. This ID can then be used in the body of the text to produce the inline reference. The text of the ID is arbitrary but can only contain alphanumeric characters. If "title" or "author" are used in square brackets directly after the inline id (for example `[goodnight][author]`) then that feild will be printed in the text. Following the ID, each on a new line, are a set of "keys" which describe the work.
-All referencing in Goodnight is APA 7th [lindsey2015]. It can be done similar to referenced links with a syntax similar to YAML metadata:
+Example:
```
-"Placeholder quote" [1]
+[goodnight][author] ([goodnight][year]) writes "Each reference can happen anywhere in the text"
-\[1]
-title: Placeholder title
-author: Placeholder name
+\[goodnight]
+title: The Goodnight Markdown Specification - Version 0.1.0
+author: Goodnight Publishing
+url: https://goodnight-publishing.co.uk
```
-If one of the keys is placed in square brackets after the in-text reference, it will be printed. If only the reference id is used, the full in-text reference will be used. If something that is not one of the keys is placed in square brackets within the full refrence, for example a page number.
+Becomes:
+
+```
+Goodnight Publishing (n.d.) writes "Each reference can happen anywhere in the text"
+```
The keys are as follows:
. `author`. The authors or entities behind the work seperated by the word "and". Wrap entity names in curly brackets
. `title`
-. `year` (optional)
+. `year`. "n.d." used if no year is given. (optional)
. `publisher` (optional)
. `url` (optional)
. `journaltitle`: Title of the book or journal the work is in (optional)
. `issuetitle`: Issue title of the book or journal the work is in (optional, must be used with `journaltitle`)
-. `editor`: Author of the book or journal the work is in (optional, must be used with `journaltitle`)
-. `volume`: Volume of the book or journal the work is in (optional, must be used with `journaltitle`)
-
-[REFS]
-
-[lindsey2015]
-author: Marley-Vincent Lindsey
-editor: William Value
-title: The Politics of Pokémon. Socialized Gaming, Religious Themes and the Construction of Communal Narratives
-journaltitle: Heidelberg Journal of Religions on the Internet
-issuetitle: Religion in Digital Games Reloaded. Immersion into the Field
-year: 2015
-volume: 7th
+. `editor`: Author of the book or journal the work is in. Should be formatted the same as "author". (optional, must be used with `journaltitle`)
+. `volume`: Volume of the book or journal the work is in. Example: "7th". (optional, must be used with `journaltitle`)
+use regex::Regex;
+
fn parse_inline (string: &str, symbol: char, front: &str, back: &str) -> String {
let mut text = string.to_string();
// makes a cycling itterable of the front and back replacement
text
}
-pub fn parse_inline_latex (string: &str) -> String {
- let mut text = parse_inline(string, '*', "\\textbf{", "}");
- text = parse_inline(&text, '_', "\\textit{", "}");
- parse_inline(&text, '`', "\\texttt{", "}").replace("#", "\\#")
-}
+fn de_escape (string: &str) -> String {
+ let mut new_string = string.to_string();
-pub fn parse_inline_html (string: &str) -> String {
- let mut text = parse_inline(string, '*', "<b>", "</b>");
- text = parse_inline(&text, '_', "<em>", "</em>");
- parse_inline(&text, '`', "<code>", "</code>")
+ let re = Regex::new(r"\\(?<escaped>[\d\D])").unwrap();
+ for capture in re.captures_iter(&string).collect::<Vec<_>>().iter().rev() {
+ let mat = capture.name("escaped").unwrap();
+ if match mat.start() > 1 {
+ true => {&string[mat.start()-2..mat.start()-1] != r"\"}
+ false => {true}
+ } {
+ new_string.replace_range(mat.start()-1..mat.end(), mat.as_str());
+ }
+ }
+
+ new_string
}
-pub fn parse_inline_gemtext (string: &str) -> String {
+pub fn parse_inline_remove (string: &str) -> String {
let mut text = parse_inline(string, '*', "", "");
text = parse_inline(&text, '_', "", "");
parse_inline(&text, '`', "", "")
}
-pub fn parse_inline_remove (string: &str) -> String {
- parse_inline_gemtext(string)
+pub fn parse_inline_latex (string: &str) -> String {
+ let mut text = string.replace(r"\\", r"\\\");
+ text = parse_inline(&text, '*', r"\\textbf{", "}");
+ text = parse_inline(&text, '_', r"\\textit{", "}");
+ text = parse_inline(&text, '`', r"\\texttt{", "}");
+ de_escape(&text)
+ .replace(r"&", r"\&{}")
+ .replace(r"#", r"\#{}")
+ .replace(r"`", r"\`{}")
+}
+
+pub fn parse_inline_html (string: &str) -> String {
+ let mut text = string
+ .replace(r"&", r"&")
+ .replace(r"<", r"<")
+ .replace(r">", r">");
+ text = parse_inline(&text, '*', "<b>", "</b>");
+ text = parse_inline(&text, '_', "<em>", "</em>");
+ text = parse_inline(&text, '`', "<code>", "</code>");
+ de_escape(&text)
+}
+
+pub fn parse_inline_gemtext (string: &str) -> String {
+ let text = parse_inline_remove(string);
+ de_escape(&text)
}
#[cfg(test)]
}
// match all heading patterns
- ('#', '#', '#', '#', '#', '#') => {
- document.push(Box::new(Heading{text: parse_reference(&reference_list, line[6..].to_string()), level: 6}))
- },
('#', '#', '#', '#', '#', ..) => {
document.push(Box::new(Heading{text: parse_reference(&reference_list, line[5..].to_string()), level: 5}))
},
}
// match all heading patterns
- ('#', '#', '#', '#', '#', '#') => {
- elements.push(Heading{text: parse_reference(&reference_list, line[6..].to_string()), level: 6})
- },
('#', '#', '#', '#', '#', ..) => {
elements.push(Heading{text: parse_reference(&reference_list, line[5..].to_string()), level: 5})
},
}
fn render_html(&self) -> String {
- String::from("<pre>") + &self.text.trim() + "</pre>\n"
+ String::from("<pre>") + &self.text.trim().replace("<", "<").replace(">", ">") + "</pre>\n"
}
fn render_gemtext(&self) -> String {