Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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