Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/nested tags #95

Merged
merged 5 commits into from
Apr 25, 2021
Merged
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
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased
### Added
- Nested tag support - "parent/child" tags used with the "Tag" hierarchy create nested folders.
- Nested tag support (Issue [#85](https://github.com/out-of-cheese-error/gooseberry/issues/85))
- `gooseberry config kb nested` and `nested_tag` config option to determine pattern to use for nesting tags.
- `parent<nested_tag>child` tags used with the "Tag" hierarchy create nested folders.
- Separate make and index commands, allow filtering annotations in both (
Issue [#90](https://github.com/out-of-cheese-error/gooseberry/issues/90))
- Better and more filtering options (Issue [#92](https://github.com/out-of-cheese-error/gooseberry/issues/92))
Expand Down
16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ This demonstrates the interactive search functionality. `Enter` adds a new tag,
* [Page template](#page-template)
* [Grouping annotations into folders and pages](#grouping-annotations-into-folders-and-pages)
* [Sorting annotations within a page](#sorting-annotations-within-a-page)
* [Tags and nesting](#tags-and-nesting)
* [Index link template](#index-link-template)
* [Index filename](#index-filename)
* [Ignoring tags](#ignoring-tags)
Expand Down Expand Up @@ -371,14 +372,25 @@ The available options are:
* Created
* Updated

Multiple sort options can be combined in order of priority e.g. `sort = ["Tag", "Created"]` sorts by tags, then by the date of creation.
Multiple sort options can be combined in order of priority e.g. `sort = ["Tag", "Created"]` sorts by tags, then by the
date of creation.

#### Tags and nesting

`gooseberry config kb nested`

This defines the pattern to use for nesting tags. e.g. if `nested_tag = "/"` then a tag of "parent/child" combined
with `hierarchy = ["Tag"]` would create a "parent" folder with a "child" file inside it.

Commas (",") and semicolons (";") should not be used inside tags as they are used as separators by Gooseberry.

#### Index link template

`gooseberry config kb link`

This configures the index file, which generally contains links to all other pages in the generated knowledge base
(unless `hierarchy=[]` in which case all annotations are rendered on the index page). The template controls how each of these links are rendered.
(unless `hierarchy=[]` in which case all annotations are rendered on the index page). The template controls how each of
these links are rendered.

Available keys:

Expand Down
18 changes: 18 additions & 0 deletions src/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crate::gooseberry::knowledge_base::{
};
use crate::{utils, NAME};

pub static DEFAULT_NESTED_TAG: &str = "/";
pub static DEFAULT_ANNOTATION_TEMPLATE: &str = r#"

### {{id}}
Expand Down Expand Up @@ -98,6 +99,8 @@ pub struct GooseberryConfig {
pub(crate) sort: Option<Vec<OrderBy>>,
/// Define tags to ignore
pub(crate) ignore_tags: Option<Vec<String>>,
/// Define nested tag pattern
pub(crate) nested_tag: Option<String>,
}

/// Main project directory, cross-platform
Expand All @@ -123,6 +126,7 @@ impl Default for GooseberryConfig {
hierarchy: None,
sort: None,
ignore_tags: None,
nested_tag: None,
};
config.make_dirs().unwrap();
config
Expand All @@ -146,12 +150,14 @@ kb_dir = '<knowledge-base folder>'
hierarchy = ['Tag']
sort = ['Created']
ignore_tags = []
nested_tag = {}
annotation_template = '''{}'''
page_template = '''{}'''
index_link_template = '''{}'''
index_name = '{}'
file_extension = '{}'
"#,
DEFAULT_NESTED_TAG,
DEFAULT_ANNOTATION_TEMPLATE,
DEFAULT_PAGE_TEMPLATE,
DEFAULT_INDEX_LINK_TEMPLATE,
Expand Down Expand Up @@ -299,6 +305,7 @@ file_extension = '{}'
self.set_page_template()?;
self.set_index_link_template()?;
self.set_index_name()?;
self.set_nested_tag()?;
self.set_file_extension()?;
self.set_hierarchy()?;
self.set_sort()?;
Expand Down Expand Up @@ -727,6 +734,17 @@ file_extension = '{}'
Ok(())
}

pub fn set_nested_tag(&mut self) -> color_eyre::Result<()> {
self.nested_tag = Some(utils::user_input(
"What pattern should gooseberry use to define nested tags",
Some(self.nested_tag.as_deref().unwrap_or(DEFAULT_NESTED_TAG)),
true,
false,
)?);
self.store()?;
Ok(())
}

pub fn set_file_extension(&mut self) -> color_eyre::Result<()> {
self.file_extension = Some(utils::user_input(
"What extension should gooseberry use for wiki files",
Expand Down
3 changes: 3 additions & 0 deletions src/gooseberry/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,8 @@ pub enum KbConfigCommand {
Sort,
/// Set which tags to ignore
Ignore,
/// Set string defining nested tags (e.g "/" => parent/child)
Nest,
}

impl ConfigCommand {
Expand Down Expand Up @@ -295,6 +297,7 @@ impl ConfigCommand {
KbConfigCommand::Page => config.set_page_template()?,
KbConfigCommand::Link => config.set_index_link_template()?,
KbConfigCommand::Index => config.set_index_name()?,
KbConfigCommand::Nest => config.set_nested_tag()?,
KbConfigCommand::Extension => config.set_file_extension()?,
KbConfigCommand::Hierarchy => config.set_hierarchy()?,
KbConfigCommand::Sort => config.set_sort()?,
Expand Down
15 changes: 10 additions & 5 deletions src/gooseberry/knowledge_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ pub struct PageTemplate {
fn group_annotations_by_order(
order: OrderBy,
annotations: Vec<AnnotationTemplate>,
nested_tag: Option<&String>,
) -> HashMap<String, Vec<AnnotationTemplate>> {
let mut order_to_annotations = HashMap::new();
match order {
Expand All @@ -173,7 +174,10 @@ fn group_annotations_by_order(
.push(annotation);
} else {
for tag in &annotation.annotation.tags {
let tag = tag.replace("/", path_separator);
let mut tag = tag.to_owned();
if let Some(nested_tag) = nested_tag {
tag = tag.replace(nested_tag, path_separator);
}
order_to_annotations
.entry(tag)
.or_insert_with(Vec::new)
Expand Down Expand Up @@ -290,7 +294,6 @@ impl Gooseberry {
self.make_book(annotations, &kb_dir, make, index).await?;
Ok(())
}

/// Write markdown files for wiki
async fn make_book(
&self,
Expand Down Expand Up @@ -380,9 +383,11 @@ impl Gooseberry {
if make && !folder.exists() {
fs::create_dir(&folder)?;
}
for (new_folder, annotations) in
group_annotations_by_order(order[depth], inner_annotations)
{
for (new_folder, annotations) in group_annotations_by_order(
order[depth],
inner_annotations,
self.config.nested_tag.as_ref(),
) {
(recurse_folder.f)(
recurse_folder,
annotations,
Expand Down
28 changes: 27 additions & 1 deletion tests/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ hypothesis_group = '{}'
kb_dir = '{}'
hierarchy = ['Tag']
sort = ['Created']
nested_tag = ' : '
annotation_template = '''{}'''
page_template = '''{}'''
index_link_template = '''{}'''
Expand Down Expand Up @@ -448,6 +449,22 @@ async fn make() -> color_eyre::Result<()> {
.tags
.contains(&"test tag5".to_owned()));

// add a nested tag
thread::sleep(duration);
let mut cmd = Command::cargo_bin("gooseberry")?;
cmd.env("GOOSEBERRY_CONFIG", &test_data.config_file)
.arg("tag")
.arg("--tags=test_tag")
.arg("test_tag6 : test_tag7")
.assert()
.success();
assert!(test_data
.hypothesis_client
.fetch_annotation(&test_data.annotations[0].id)
.await?
.tags
.contains(&"test_tag6 : test_tag7".to_owned()));

// make
thread::sleep(duration);
let mut cmd = Command::cargo_bin("gooseberry")?;
Expand Down Expand Up @@ -491,10 +508,19 @@ async fn make() -> color_eyre::Result<()> {
.exists());

// check all tag files
assert!(["test_tag", "test_tag1", "test_tag2", "test tag5"]
assert!(["test_tag", "test_tag1", "test_tag2", "test tag5",]
.iter()
.all(|t| file_names.contains(&format!("{}.md", t))));

// check nested tags
assert!(file_names.contains("test_tag6"));
assert!(test_data
.temp_dir
.path()
.join("kb")
.join("test_tag6")
.join("test_tag7.md")
.exists());
test_data.clear().await?;
Ok(())
}