]> OzVa Git service - gn-parser/commitdiff
Fixed some inline parser bugs and added stylesheet
authorMax Value <greenwoodw50@gmail.com>
Sat, 10 May 2025 00:12:52 +0000 (01:12 +0100)
committerMax Value <greenwoodw50@gmail.com>
Sat, 10 May 2025 00:12:52 +0000 (01:12 +0100)
+ Default stylesheet
+ More info to the schema
~ Fixed inline parser HTML and LaTeX bugs

default.css [new file with mode: 0644]
default.sty [new file with mode: 0644]
goodnight.gn
src/inline.rs
src/parser.rs
src/types/preformatted.rs

diff --git a/default.css b/default.css
new file mode 100644 (file)
index 0000000..b3a9cfb
--- /dev/null
@@ -0,0 +1,23 @@
+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;
+}
diff --git a/default.sty b/default.sty
new file mode 100644 (file)
index 0000000..e69de29
index dec3edff753af3d64b6d96f5ea41d08b8690b853..ff75da81f7e3129bef99c01d8e0acbf12d1b9c98 100644 (file)
@@ -8,6 +8,17 @@ style: default
 
 [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:
@@ -19,7 +30,31 @@ I don't belive in line breaks and horizontal rules are the responsibility of the
 
 ## 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
 
@@ -31,17 +66,15 @@ Still to be implemented
 
 ## 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.
 
@@ -77,50 +110,47 @@ To generate the title, table of contents and bibliography, the following macros
 
 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`)
index d1ec55dfa295d5650561eeac15145ecd1705b0d7..5ec5a03952637b78a29581b39e6ff59534c5810b 100644 (file)
@@ -1,3 +1,5 @@
+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
@@ -11,26 +13,54 @@ fn parse_inline (string: &str, symbol: char, front: &str, back: &str) -> String
        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"&amp;")
+               .replace(r"<", r"&lt;")
+               .replace(r">", r"&gt;");
+       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)]
index 5091d05166382b784e98df43eb1a4d7d41deafa6..4ce1a6457b98ec35045ef7abc5e2e0ad8e3e8e05 100644 (file)
@@ -44,9 +44,6 @@ pub fn parse_body (string: String, metadata: Metadata, reference_list: Option<Re
                                }
 
                                // 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}))
                                },
@@ -168,9 +165,6 @@ fn parse_headings(string: String, reference_list: Option<ReferenceList>) -> Opti
                                }
 
                                // 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})
                                },
index 2cc024440c0e1d8377cd3ca81f94f83749511f40..5415f75b27f94a8a02f9f18a448c3d207afadbe6 100644 (file)
@@ -12,7 +12,7 @@ impl Renderable for Preformatted {
        }
 
        fn render_html(&self) -> String {
-               String::from("<pre>") + &self.text.trim() + "</pre>\n"
+               String::from("<pre>") + &self.text.trim().replace("<", "&lt;").replace(">", "&gt;") + "</pre>\n"
        }
 
        fn render_gemtext(&self) -> String {