Skip to content

Commit

Permalink
Support zine new --article (#216)
Browse files Browse the repository at this point in the history
  • Loading branch information
Folyd authored Apr 23, 2023
1 parent ccdbea4 commit 606537a
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 12 deletions.
4 changes: 4 additions & 0 deletions src/entity/zine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ impl Zine {
Ok(())
}

pub fn get_issue_by_number(&self, number: u32) -> Option<&Issue> {
self.issues.iter().find(|issue| issue.number == number)
}

// Get the article metadata list by author id, sorted by descending order of publishing date.
fn get_articles_by_author(&self, author_id: &str) -> Vec<ArticleRef> {
let mut items = self
Expand Down
19 changes: 16 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use anyhow::Result;
use anyhow::{bail, Result};
use clap::{Parser, Subcommand};
use zine::build::watch_build;
use zine::new::{new_zine_issue, new_zine_project};
use zine::new::{new_article, new_zine_issue, new_zine_project};
use zine::serve::run_serve;
use zine::{lint, Mode};

Expand Down Expand Up @@ -43,6 +43,9 @@ enum Commands {
/// New issue.
#[arg(short, long)]
issue: bool,
/// New article.
#[arg(short, long)]
article: bool,
},
/// Lint Zine project.
Lint {
Expand Down Expand Up @@ -73,9 +76,19 @@ async fn main() -> Result<()> {
zine::set_current_mode(Mode::Serve);
run_serve(source.as_deref().unwrap_or("."), port, open).await?;
}
Commands::New { name, issue } => {
Commands::New {
name,
issue,
article,
} => {
if issue && article {
bail!("Can't create both issue and article at the same time.")
}

if issue {
new_zine_issue()?;
} else if article {
new_article()?;
} else {
new_zine_project(name)?
}
Expand Down
74 changes: 65 additions & 9 deletions src/new.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
use std::{borrow::Cow, env, fs, path::PathBuf};
use std::{borrow::Cow, env, fs, io::Write, path::PathBuf};

use anyhow::{Context as _, Result};
use anyhow::{Context as _, Ok, Result};
use minijinja::render;
use promptly::prompt_default;
use time::{format_description, OffsetDateTime};
use time::OffsetDateTime;

use crate::{helpers::run_command, ZINE_FILE};
use crate::{
entity::Zine,
helpers::{self, run_command},
ZINE_FILE,
};

static TEMPLATE_PROJECT_FILE: &str = r#"
[site]
Expand Down Expand Up @@ -34,6 +38,18 @@ publish = true
featured = true
"#;

static TEMPLATE_ARTICLE: &str = r#"
[[article]]
file = "{{ file }}"
title = "{{ title }}"
author = "{{ author | lower }}"
cover = ""
pub_date = "{{ pub_date }}"
publish = true
featured = true
"#;

struct ZineScaffold {
source: PathBuf,
author: String,
Expand Down Expand Up @@ -62,8 +78,6 @@ impl ZineScaffold {
.join(crate::ZINE_CONTENT_DIR)
.join(self.issue_dir.as_ref());
fs::create_dir_all(&issue_dir)?;
let format = format_description::parse("[year]-[month]-[day]")?;
let today = OffsetDateTime::now_utc().format(&format)?;

fs::write(
issue_dir.join(ZINE_FILE),
Expand All @@ -72,7 +86,7 @@ impl ZineScaffold {
slug => self.issue_dir,
number => self.issue_number,
title => self.issue_title,
pub_date => today,
pub_date => helpers::format_date(&OffsetDateTime::now_utc().date()),
author => self.author
),
)?;
Expand Down Expand Up @@ -117,13 +131,16 @@ pub fn new_zine_project(name: Option<String>) -> Result<()> {
Ok(())
}

pub fn new_zine_issue() -> Result<()> {
fn load_zine_project() -> Result<(PathBuf, Zine)> {
// Use zine.toml to find root path
let (source, mut zine) = crate::locate_root_zine_folder(env::current_dir()?)?
.with_context(|| "Failed to find the root zine.toml file".to_string())?;
zine.parse_issue_from_dir(&source)?;
Ok((source, zine))
}

let author = git_user_name();
pub fn new_zine_issue() -> Result<()> {
let (source, zine) = load_zine_project()?;
let next_issue_number = zine.issues.len() + 1;
let issue_dir = prompt_default(
"What is your issue directory name?",
Expand All @@ -135,6 +152,7 @@ pub fn new_zine_issue() -> Result<()> {
format!("Issue {next_issue_number}"),
)?;

let author = git_user_name();
let scaffold = ZineScaffold {
source,
author,
Expand All @@ -146,6 +164,44 @@ pub fn new_zine_issue() -> Result<()> {
Ok(())
}

pub fn new_article() -> Result<()> {
let (source, zine) = load_zine_project()?;
let latest_issue_number = zine.issues.len();
let issue_number = prompt_default(
"Which Issue do you want create a new article?",
latest_issue_number,
)?;
if let Some(issue) = zine.get_issue_by_number(issue_number as u32) {
let article_file = prompt_default(
"What is your article file name?",
"new-article.md".to_owned(),
)?;
let title = prompt_default("What is your article title?", "New Article".to_owned())?;
let author = git_user_name();

let issue_dir = source.join(crate::ZINE_CONTENT_DIR).join(&issue.dir);
// Write article file
fs::write(issue_dir.join(&article_file), "Hello Zine")?;

// Append article to issue zine.toml
let article_content = render!(
TEMPLATE_ARTICLE,
title,
author,
file => article_file,
pub_date => helpers::format_date(&OffsetDateTime::now_utc().date()),
);
let mut issue_file = fs::OpenOptions::new()
.append(true)
.open(issue_dir.join(ZINE_FILE))?;
issue_file.write_all(article_content.as_bytes())?;
} else {
println!("Issue {} not found", issue_number);
}

Ok(())
}

fn git_user_name() -> String {
run_command("git", &["config", "user.name"])
.ok()
Expand Down

0 comments on commit 606537a

Please sign in to comment.