Skip to content

Commit

Permalink
feat: add the ability to order articles
Browse files Browse the repository at this point in the history
  • Loading branch information
Paqura committed Apr 3, 2023
1 parent d3c66c3 commit b74fdd6
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 2 deletions.
100 changes: 100 additions & 0 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ impl ParserStateMachine {

#[derive(Debug, Clone)]
pub struct Article {
pub order: i16,
pub topic: String,
pub content: String,
pub path: String,
Expand Down Expand Up @@ -150,6 +151,27 @@ enum Keyword {
* ```
*/
Article,
/**
* @Article Syntax
* `@Order <Order of the Article>` is for controlling the order of the article sections.
*
* Example:
*
* ```rust
* /**
* * @Article Usage example
* * @Order 2
* * ## Header2
* */
*
* /**
* * @Article Usage example
* * @Order 1
* * # Header1
* */
* ```
*/
Order,
/**
* @Article Syntax
* `@FileArticle` allows you to mark a whole file is a source of documentation for a specified
Expand Down Expand Up @@ -229,6 +251,7 @@ enum Keyword {
impl Keyword {
fn as_str(&self) -> &'static str {
match *self {
Keyword::Order => "@Order",
Keyword::Article => "@Article",
Keyword::FileArticle => "@FileArticle",
Keyword::Ignore => "@Ignore",
Expand Down Expand Up @@ -262,6 +285,7 @@ impl Parser {

let articles: Vec<Article> = vec![];
let current_article = Article {
order: 0,
topic: String::from(""),
content: String::from(""),
path: String::from(""),
Expand Down Expand Up @@ -327,6 +351,14 @@ impl Parser {
result
}

fn parse_article_order(&self, order_block_line: String) -> i16 {
order_block_line
.replace(Keyword::Order.as_str(), "")
.trim()
.parse()
.unwrap_or(0)
}

fn trim_article_line(&self, line: String) -> String {
line.trim_start()
.trim_start_matches(self.comment_symbol)
Expand All @@ -336,6 +368,7 @@ impl Parser {

fn new_article(&self) -> Article {
Article {
order: 0,
topic: String::from(""),
content: String::from(""),
path: String::from(""),
Expand All @@ -350,6 +383,7 @@ impl Parser {
let topic = name_chunks[2..].join(".");

vec![Article {
order: 0,
topic,
content: String::from(file_content),
path: String::from(file_path),
Expand Down Expand Up @@ -429,6 +463,13 @@ impl Parser {
self.current_article.topic = self.trim_article_line(topic);
self.current_article.start_line = line_number;
self.state_machine.to_article_mut();
} else if trimmed_line.starts_with(Keyword::Order.as_str())
&& self.state_machine.is_in(ParserState::ArticleParsing)
{
let parsed_order = self.parse_article_order(trimmed_line);

self.current_article.order = parsed_order;
self.current_article.start_line = line_number;
} else if trimmed_line.starts_with(Keyword::Ignore.as_str()) {
self.state_machine.to_skippintg_mut();
self.current_article = self.new_article();
Expand Down Expand Up @@ -484,6 +525,7 @@ impl Parser {
line_number += 1;
}

self.articles.sort_by_key(|a| a.order);
self.articles.clone()
}

Expand Down Expand Up @@ -559,6 +601,7 @@ pub fn test () {}

let articles = parser.parse_file(file_content, "");
let expected_result = vec![Article {
order: 0,
topic: String::from("Test article"),
content: String::from("some text"),
path: "".to_string(),
Expand All @@ -569,6 +612,48 @@ pub fn test () {}
assert_eq!(articles, expected_result);
}

#[test]
fn parse_articles_with_custom_order() {
let mut parser = Parser::new(get_test_config());
let file_content = "
/**
* @Article Test article3
* @Order 3
* some text3
*/
pub fn test () {}
/**
* @Article Test article1
* @Order 1
* some text
*/
pub fn test2 () {}
";

let articles = parser.parse_file(file_content, "");
let expected_result = vec![
Article {
order: 1,
topic: String::from("Test article1"),
content: String::from("some text"),
path: "".to_string(),
start_line: 11,
end_line: 12,
},
Article {
order: 3,
topic: String::from("Test article3"),
content: String::from("some text3"),
path: "".to_string(),
start_line: 4,
end_line: 5,
},
];

assert_eq!(articles, expected_result);
}

#[test]
fn ignore_comments_with_ignore_mark() {
let mut parser = Parser::new(get_test_config());
Expand Down Expand Up @@ -604,6 +689,7 @@ pub fn test () {}

let articles = parser.parse_file(file_content, "");
let expected_result = vec![Article {
order: 0,
topic: String::from("Test article"),
content: String::from("some multiline\nawesome text"),
path: "".to_string(),
Expand Down Expand Up @@ -650,6 +736,7 @@ pub fn test () {}

let articles = parser.parse_file(file_content, "");
let expected_result = vec![Article {
order: 0,
topic: String::from("Test article"),
content: String::from("```rust\nfn main() {\n println!(\"Hello world!\");\n}\n```\n\n```rust\nfn test() {\n println!(\"Hello world!\");\n}\n```"),
path: "".to_string(),
Expand Down Expand Up @@ -684,6 +771,7 @@ fn parse_documentation_with_indentation_before_comments() {

let articles = parser.parse_file(file_content, "");
let expected_result = vec![Article {
order: 0,
topic: String::from("Test article"),
content: String::from("#### [no-implicit-coercion](https://eslint.org/docs/rules/no-implicit-coercion)\nAll implicit coercions except `!!` are disallowed:\n```js\n// Fail\n+foo\n1 * foo\n\'\' + foo\n`${foo}`\n~foo.indexOf(bar)\n\n// Pass\n!!foo\n```"),
path: "".to_string(),
Expand Down Expand Up @@ -714,6 +802,7 @@ pub fn test () {}

let articles = parser.parse_file(file_content, "");
let expected_result = vec![Article {
order: 0,
topic: String::from("Test article"),
content: String::from("List:\n* Item 1\n* Item 2\n\n Item 2 subtext\n* Item 3"),
path: "".to_string(),
Expand All @@ -738,6 +827,7 @@ use std::io::prelude::*;

let articles = parser.parse_file(file_content, "");
let expected_result = vec![Article {
order: 0,
topic: String::from("Test article"),
content: String::from(""),
path: "".to_string(),
Expand All @@ -760,6 +850,7 @@ test

let articles = parser.parse_file(file_content, "");
let expected_result = vec![Article {
order: 0,
topic: String::from("Test article"),
content: String::from("test"),
path: "".to_string(),
Expand All @@ -784,6 +875,7 @@ const b = 2

let articles = parser.parse_file(file_content, "");
let expected_result = vec![Article {
order: 0,
topic: String::from("Test article"),
content: String::from("test"),
path: "".to_string(),
Expand Down Expand Up @@ -816,13 +908,15 @@ fn use_global_article_attribute() {
let articles = parser.parse_file(file_content, "");
let expected_result = vec![
Article {
order: 0,
topic: String::from("Test article"),
content: String::from("test"),
path: "".to_string(),
start_line: 6,
end_line: 7,
},
Article {
order: 0,
topic: String::from("Test article"),
content: String::from("test"),
path: "".to_string(),
Expand Down Expand Up @@ -856,6 +950,7 @@ fn ignore_sections_in_case_of_global_article() {

let articles = parser.parse_file(file_content, "");
let expected_result = vec![Article {
order: 0,
topic: String::from("Test article"),
content: String::from("test"),
path: "".to_string(),
Expand All @@ -881,6 +976,7 @@ const TIMEOUT = 3000

let articles = parser.parse_file(file_content, "");
let expected_result = vec![Article {
order: 0,
topic: String::from("Test article"),
content: String::from("Request timeout:\n```js/\nconst TIMEOUT = 3000\n```"),
path: "".to_string(),
Expand Down Expand Up @@ -908,6 +1004,7 @@ const TIMEOUT = 3000

let articles = parser.parse_file(file_content, "");
let expected_result = vec![Article {
order: 0,
topic: String::from("Test article"),
content: String::from("Request timeout:\n```js/\nconst TIMEOUT = 3000\n```"),
path: "".to_string(),
Expand All @@ -933,6 +1030,7 @@ fn parse_code_block_attribute_from_ending_comment_only() {

let articles = parser.parse_file(file_content, "");
let expected_result = vec![Article {
order: 0,
topic: String::from("Test article"),
content: String::from("Should ignore @CodeBlockEnd in a text block\n```rust/\n...\n```"),
path: "".to_string(),
Expand Down Expand Up @@ -960,6 +1058,7 @@ fn parse_nested_commends() {

let articles = parser.parse_file(file_content, "");
let expected_result = vec![Article {
order: 0,
topic: String::from("Test article"),
content: String::from("Example:\n/**\n* @Article Example article\n* Example\n*/\ntest"),
path: "".to_string(),
Expand Down Expand Up @@ -998,6 +1097,7 @@ fn parse_fdoc_file_check() {
let parser = Parser::new(get_test_config());
let result = parser.parse_fdoc_file("test", "/some/long/path/to/file.fdoc.md");
let expected_result = vec![Article {
order: 0,
topic: String::from("file"),
content: String::from("test"),
path: "/some/long/path/to/file.fdoc.md".to_string(),
Expand Down
4 changes: 2 additions & 2 deletions src/plugins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub struct Plugins {
* {{ #your-plugin-name
* any text here
* }}
*
*
* ```
*
* To create a plugin for parsing these blocks, you should add a file called `your-plugin-name.html.lua` into the plugins folder. By default, it's `./plugins`, but it's possible to change it in the config file.
Expand All @@ -44,7 +44,7 @@ pub struct Plugins {
*
* ```lua
* function transform(text)
* result = 'transformted text'
* result = 'transformted text'
* end
* ```
*
Expand Down

0 comments on commit b74fdd6

Please sign in to comment.