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

change --json to --output json #128

Merged
merged 4 commits into from
Jul 16, 2024
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
28 changes: 2 additions & 26 deletions src/fmt_md.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use crate::fmt_md_inlines::{MdInlinesWriter, MdInlinesWriterOptions};
use clap::ValueEnum;
use std::borrow::Borrow;
use std::cmp::max;
use std::fmt::Alignment;
use std::ops::Deref;

use crate::link_transform::{LinkLabel, LinkTransform};
use crate::link_transform::LinkLabel;
use crate::output::{Block, Output, SimpleWrite};
use crate::str_utils::{pad_to, standard_align, CountingWriter};
use crate::tree::*;
Expand Down Expand Up @@ -85,26 +84,6 @@ where
writer_state.write_definitions(out, DefinitionsToWrite::Both, nodes_count > 1);
}

pub fn write_md_inlines<'a, I, W>(out: &mut Output<W>, nodes: I, inlines_writer: &mut MdInlinesWriter<'a>)
where
I: Iterator<Item = MdElemRef<'a>>,
W: SimpleWrite,
{
let mut writer_state = MdWriterState {
opts: &MdOptions {
link_reference_placement: ReferencePlacement::Doc, // but we won't actually write them
footnote_reference_placement: ReferencePlacement::Doc, // ditto
inline_options: MdInlinesWriterOptions {
link_format: LinkTransform::Keep, // unused here, but removing it is more refactoring than it's worth
Comment on lines -95 to -98
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fact that I had all these unused options should have keyed me into the fact that something weird was going on! The link_format one I had even noted as a TODO to clean up earlier, but I decided it wasn't worth it in 329d1e4. I guess now it's done right!

},
},
prev_was_thematic_break: false,
inlines_writer,
};
// This will write everything but the references; we'll keep those in the inlines_writer
writer_state.write_md(out, nodes, true);
}

struct MdWriterState<'s, 'a> {
opts: &'a MdOptions,
prev_was_thematic_break: bool,
Expand Down Expand Up @@ -450,10 +429,7 @@ impl<'s, 'a> MdWriterState<'s, 'a> {
});
}

fn line_to_string<E>(&mut self, line: &'a [E]) -> String
where
E: Borrow<Inline>,
{
fn line_to_string(&mut self, line: &'a Line) -> String {
let mut out = Output::new(String::with_capacity(line.len() * 10)); // rough guess
self.inlines_writer.write_line(&mut out, line);
out.take_underlying().unwrap()
Expand Down
10 changes: 5 additions & 5 deletions src/fmt_md_inlines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::tree::{
TextVariant,
};
use serde::Serialize;
use std::borrow::{Borrow, Cow};
use std::borrow::Cow;
use std::collections::{HashMap, HashSet};

#[derive(Debug, Copy, Clone)]
Expand Down Expand Up @@ -102,13 +102,13 @@ impl<'a> MdInlinesWriter<'a> {
self.pending_references.footnotes.drain().collect()
}

pub fn write_line<E, W>(&mut self, out: &mut Output<W>, elems: &'a [E])
pub fn write_line<I, W>(&mut self, out: &mut Output<W>, elems: I)
where
E: Borrow<Inline>,
I: IntoIterator<Item = &'a Inline>,
W: SimpleWrite,
{
for elem in elems {
self.write_inline_element(out, elem.borrow());
self.write_inline_element(out, elem);
}
}

Expand Down Expand Up @@ -174,7 +174,7 @@ impl<'a> MdInlinesWriter<'a> {
out.write_char('[');
match &label {
LinkLabel::Text(text) => out.write_str(text),
LinkLabel::Inline(text) => self.write_line(out, text),
LinkLabel::Inline(text) => self.write_line(out, *text),
}
out.write_char(']');

Expand Down
43 changes: 35 additions & 8 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use clap::Parser;
use clap::{Parser, ValueEnum};
use output::Output;
use std::borrow::Cow;
use std::fmt::{Display, Formatter};
use std::io;
use std::io::{stdin, Read, Write};

Expand Down Expand Up @@ -48,8 +49,8 @@ pub struct Cli {
pub(crate) link_format: LinkTransform,

/// Output the results as a JSON object, instead of as markdown.
#[arg(long, short, default_value_t = false)]
pub(crate) json: bool, // TODO this should really be output=<json|md>
#[arg(long, short, default_value_t = OutputFormat::Markdown)]
pub(crate) output: OutputFormat,

#[arg(
short = ' ',
Expand All @@ -64,6 +65,29 @@ pub struct Cli {
pub(crate) selectors: Option<String>,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
pub enum OutputFormat {
/// Output results as Markdown.
Markdown,

/// Alias for markdown
Md,

/// Output results as JSON. Spans of inline elements (like within a single paragraph) will be rendered as a single string of
/// Markdown, not as separate JSON elements.
Json,
}

impl Display for OutputFormat {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let self_str = match self {
OutputFormat::Markdown | OutputFormat::Md => "markdown",
OutputFormat::Json => "json",
};
f.write_str(self_str)
}
}

impl Cli {
fn selector_string(&self) -> Cow<String> {
match &self.selectors {
Expand Down Expand Up @@ -127,11 +151,14 @@ where
};

let mut stdout = get_out();
if cli.json {
serde_json::to_writer(&mut stdout, &SerdeDoc::new(&pipeline_nodes, md_options.inline_options)).unwrap();
} else {
let mut out = Output::new(Stream(&mut stdout));
fmt_md::write_md(&md_options, &mut out, pipeline_nodes.into_iter());
match cli.output {
OutputFormat::Markdown | OutputFormat::Md => {
let mut out = Output::new(Stream(&mut stdout));
fmt_md::write_md(&md_options, &mut out, pipeline_nodes.into_iter());
}
OutputFormat::Json => {
serde_json::to_writer(&mut stdout, &SerdeDoc::new(&pipeline_nodes, md_options.inline_options)).unwrap();
}
}

true
Expand Down
4 changes: 1 addition & 3 deletions src/tree_ref_serde.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::fmt_md;
use crate::fmt_md_inlines::{MdInlinesWriter, MdInlinesWriterOptions, UrlAndTitle};
use crate::link_transform::LinkLabel;
use crate::output::Output;
Expand Down Expand Up @@ -287,9 +286,8 @@ fn inlines_to_string<'a, I>(inlines: I, writer: &mut MdInlinesWriter<'a>) -> Str
where
I: IntoIterator<Item = &'a Inline>,
{
let md: Vec<_> = inlines.into_iter().map(|inline| MdElemRef::Inline(inline)).collect();
let mut output = Output::new(String::with_capacity(16)); // guess
fmt_md::write_md_inlines(&mut output, md.into_iter().map(|e| e), writer);
writer.write_line(&mut output, inlines);
output.take_underlying().unwrap()
}

Expand Down
39 changes: 39 additions & 0 deletions tests/md_cases/output_format.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
[given]
md = '''
Test _one_ [two][1] three.

[1]: https://example.com/1
'''


[expect."default"]
cli_args = []
output = '''
Test _one_ [two][1] three.

[1]: https://example.com/1
'''


[expect."md"]
cli_args = ['-o', 'md']
output = '''
Test _one_ [two][1] three.

[1]: https://example.com/1
'''


[expect."markdown"]
cli_args = ['--output', 'markdown']
output = '''
Test _one_ [two][1] three.

[1]: https://example.com/1
'''


[expect."json"]
cli_args = ['--output', 'json']
output = '''
{"items":[{"document":[{"paragraph":"Test _one_ [two][1] three."}]}],"links":{"1":{"url":"https://example.com/1"}}}'''