Skip to content

Commit

Permalink
change --json to --output json
Browse files Browse the repository at this point in the history
Default is `--output markdown`.

This way is more flexible in the future, if I want more output formats
for whatever reason.

Also fix an unrelated bug in the JSON output, which I found when I added
an integ test for it.

Resolves a TODO, in service of #11.
  • Loading branch information
yshavit authored Jul 16, 2024
1 parent 4ce05dc commit 4348f46
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 42 deletions.
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
},
},
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"}}}'''

0 comments on commit 4348f46

Please sign in to comment.