mdbook-plotly 0.2.0

An mdbook preprocessor that renders plot code blocks (e.g., ```plot) into interactive or static charts during book build.
Documentation
use super::until::{Color, Map, must_translate};
use crate::{translate, translate_enum};
use anyhow::Result;
use plotly::Surface;

pub fn parse_surface_data(
    sf_obj: &mut serde_json::Value,
    map: &Map,
) -> Result<Box<Surface<f64, f64, f64>>> {
    let z: Vec<Vec<f64>> = must_translate(sf_obj, map, "z")?;
    let surface = Surface::new(z);

    let surface = translate! {
        surface,
        sf_obj,
        map,
        (x, Vec<f64>),
        (y, Vec<f64>),
        (name, String),
        (opacity, f64),
        (text, String),
        (text_array, Vec<String>),
        (hover_text, String),
        (hover_text_array, Vec<String>),
        (hover_template, String),
        (hover_template_array, Vec<String>),
        (show_legend, bool),
        (legend_group, String),
        (connect_gaps, bool),
        (hide_surface, bool),
        (surface_color, Vec<Color>),
        (auto_color_scale, bool),
        (reverse_scale, bool),
        (show_scale, bool),
        (cauto, bool),
        (cmax, f64),
        (cmin, f64),
        (cmid, f64),
    }?;

    use plotly::common::HoverInfo;
    let surface = translate_enum! {
        surface,
        sf_obj,
        map,
        (hover_info, {
            "all" => HoverInfo::All,
            "x" => HoverInfo::X,
            "y" => HoverInfo::Y,
            "z" => HoverInfo::Z,
            "x+y" => HoverInfo::XAndY,
            "x+z" => HoverInfo::XAndZ,
            "y+z" => HoverInfo::YAndZ,
            "x+y+z" => HoverInfo::XAndYAndZ,
            "text" => HoverInfo::Text,
            "name" => HoverInfo::Name,
            "none" => HoverInfo::None,
            "skip" => HoverInfo::Skip,
        }),
    }?;

    let surface = if let Some(color_bar_obj) = sf_obj.get_mut("color_bar")
        && color_bar_obj.is_object()
    {
        use plotly::common::ColorBar;
        let color_bar = translate! {
            ColorBar::new(),
            color_bar_obj,
            map,
            (thickness, usize),
            (len, usize),
            (x, f64),
            (y, f64),
            (title, String),
        }?;
        surface.color_bar(color_bar)
    } else {
        surface
    };

    let surface = if sf_obj.get("color_scale").is_some() {
        use plotly::common::{ColorScale, ColorScalePalette};
        let color_scale_str: String = must_translate(sf_obj, map, "color_scale")?;
        let palette = match color_scale_str.to_lowercase().as_str() {
            "greys" => ColorScalePalette::Greys,
            "ylgnbu" => ColorScalePalette::YlGnBu,
            "greens" => ColorScalePalette::Greens,
            "ylorrd" => ColorScalePalette::YlOrRd,
            "bluered" => ColorScalePalette::Bluered,
            "rdbu" => ColorScalePalette::RdBu,
            "reds" => ColorScalePalette::Reds,
            "blues" => ColorScalePalette::Blues,
            "picnic" => ColorScalePalette::Picnic,
            "rainbow" => ColorScalePalette::Rainbow,
            "portland" => ColorScalePalette::Portland,
            "jet" => ColorScalePalette::Jet,
            "hot" => ColorScalePalette::Hot,
            "blackbody" => ColorScalePalette::Blackbody,
            "earth" => ColorScalePalette::Earth,
            "electric" => ColorScalePalette::Electric,
            "viridis" => ColorScalePalette::Viridis,
            "cividis" => ColorScalePalette::Cividis,
            _ => return Err(anyhow::anyhow!("unknown color_scale: {}", color_scale_str)),
        };
        surface.color_scale(ColorScale::Palette(palette))
    } else {
        surface
    };

    let surface = if let Some(lighting_obj) = sf_obj.get_mut("lighting")
        && lighting_obj.is_object()
    {
        use plotly::traces::surface::Lighting;
        let lighting = translate! {
            Lighting::new(),
            lighting_obj,
            map,
            (ambient, f64),
            (diffuse, f64),
            (specular, f64),
            (roughness, f64),
            (fresnel, f64),
        }?;
        surface.lighting(lighting)
    } else {
        surface
    };

    let surface = if let Some(light_pos_obj) = sf_obj.get_mut("light_position")
        && light_pos_obj.is_object()
    {
        use plotly::traces::surface::Position;
        let x: i32 = must_translate(light_pos_obj, map, "x")?;
        let y: i32 = must_translate(light_pos_obj, map, "y")?;
        let z: i32 = must_translate(light_pos_obj, map, "z")?;
        surface.light_position(Position::new(x, y, z))
    } else {
        surface
    };

    Ok(surface)
}