| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431 |
- /***************************************************************************
- * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht *
- * Copyright (c) QuantStack *
- * *
- * Distributed under the terms of the BSD 3-Clause License. *
- * *
- * The full license is in the file LICENSE, distributed with this software. *
- ****************************************************************************/
- #ifndef XTENSOR_MIME_HPP
- #define XTENSOR_MIME_HPP
- #include <cstddef>
- #include <sstream>
- #include <string>
- #include <vector>
- #include <nlohmann/json.hpp>
- #include "xio.hpp"
- namespace xt
- {
- template <class P, class T>
- void compute_0d_table(std::stringstream& out, P& /*printer*/, const T& expr)
- {
- out << "<table style='border-style:solid;border-width:1px;'><tbody>";
- out << "<tr><td style='font-family:monospace;'><pre>";
- out << expr();
- out << "</pre></td></tr>";
- out << "</tbody></table>";
- }
- template <class P>
- void compute_1d_row(std::stringstream& out, P& printer, const std::size_t& row_idx)
- {
- out << "<tr><td style='font-family:monospace;' title='" << row_idx << "'><pre>";
- printer.print_next(out);
- out << "</pre></td></tr>";
- }
- template <class P, class T>
- void compute_1d_table(std::stringstream& out, P& printer, const T& expr, const std::size_t& edgeitems)
- {
- const auto& dim = expr.shape()[0];
- out << "<table style='border-style:solid;border-width:1px;'><tbody>";
- if (edgeitems == 0 || 2 * edgeitems >= dim)
- {
- for (std::size_t row_idx = 0; row_idx < dim; ++row_idx)
- {
- compute_1d_row(out, printer, row_idx);
- }
- }
- else
- {
- for (std::size_t row_idx = 0; row_idx < edgeitems; ++row_idx)
- {
- compute_1d_row(out, printer, row_idx);
- }
- out << "<tr><td><center>\u22ee</center></td></tr>";
- for (std::size_t row_idx = dim - edgeitems; row_idx < dim; ++row_idx)
- {
- compute_1d_row(out, printer, row_idx);
- }
- }
- out << "</tbody></table>";
- }
- template <class P>
- void compute_2d_element(
- std::stringstream& out,
- P& printer,
- const std::string& idx_str,
- const std::size_t& row_idx,
- const std::size_t& column_idx
- )
- {
- out << "<td style='font-family:monospace;' title='(" << idx_str << row_idx << ", " << column_idx
- << ")'><pre>";
- printer.print_next(out);
- out << "</pre></td>";
- }
- template <class P, class T>
- void compute_2d_row(
- std::stringstream& out,
- P& printer,
- const T& expr,
- const std::size_t& edgeitems,
- const std::string& idx_str,
- const std::size_t& row_idx
- )
- {
- const auto& dim = expr.shape()[expr.dimension() - 1];
- out << "<tr>";
- if (edgeitems == 0 || 2 * edgeitems >= dim)
- {
- for (std::size_t column_idx = 0; column_idx < dim; ++column_idx)
- {
- compute_2d_element(out, printer, idx_str, row_idx, column_idx);
- }
- }
- else
- {
- for (std::size_t column_idx = 0; column_idx < edgeitems; ++column_idx)
- {
- compute_2d_element(out, printer, idx_str, row_idx, column_idx);
- }
- out << "<td><center>\u22ef</center></td>";
- for (std::size_t column_idx = dim - edgeitems; column_idx < dim; ++column_idx)
- {
- compute_2d_element(out, printer, idx_str, row_idx, column_idx);
- }
- }
- out << "</tr>";
- }
- template <class P, class T, class I>
- void compute_2d_table(
- std::stringstream& out,
- P& printer,
- const T& expr,
- const std::size_t& edgeitems,
- const std::vector<I>& idx
- )
- {
- const auto& dim = expr.shape()[expr.dimension() - 2];
- const auto& last_dim = expr.shape()[expr.dimension() - 1];
- std::string idx_str;
- std::for_each(
- idx.cbegin(),
- idx.cend(),
- [&idx_str](const auto& i)
- {
- idx_str += std::to_string(i) + ", ";
- }
- );
- std::size_t nb_ellipsis = 2 * edgeitems + 1;
- if (last_dim <= 2 * edgeitems + 1)
- {
- nb_ellipsis = last_dim;
- }
- out << "<table style='border-style:solid;border-width:1px;'><tbody>";
- if (edgeitems == 0 || 2 * edgeitems >= dim)
- {
- for (std::size_t row_idx = 0; row_idx < dim; ++row_idx)
- {
- compute_2d_row(out, printer, expr, edgeitems, idx_str, row_idx);
- }
- }
- else
- {
- for (std::size_t row_idx = 0; row_idx < edgeitems; ++row_idx)
- {
- compute_2d_row(out, printer, expr, edgeitems, idx_str, row_idx);
- }
- out << "<tr>";
- for (std::size_t column_idx = 0; column_idx < nb_ellipsis; ++column_idx)
- {
- if (column_idx == edgeitems && nb_ellipsis != last_dim)
- {
- out << "<td><center>\u22f1</center></td>";
- }
- else
- {
- out << "<td><center>\u22ee</center></td>";
- }
- }
- out << "</tr>";
- for (std::size_t row_idx = dim - edgeitems; row_idx < dim; ++row_idx)
- {
- compute_2d_row(out, printer, expr, edgeitems, idx_str, row_idx);
- }
- }
- out << "</tbody></table>";
- }
- template <class P, class T, class I>
- void compute_nd_row(
- std::stringstream& out,
- P& printer,
- const T& expr,
- const std::size_t& edgeitems,
- const std::vector<I>& idx
- )
- {
- out << "<tr><td>";
- compute_nd_table_impl(out, printer, expr, edgeitems, idx);
- out << "</td></tr>";
- }
- template <class P, class T, class I>
- void compute_nd_table_impl(
- std::stringstream& out,
- P& printer,
- const T& expr,
- const std::size_t& edgeitems,
- const std::vector<I>& idx
- )
- {
- const auto& displayed_dimension = idx.size();
- const auto& expr_dim = expr.dimension();
- const auto& dim = expr.shape()[displayed_dimension];
- if (expr_dim - displayed_dimension == 2)
- {
- return compute_2d_table(out, printer, expr, edgeitems, idx);
- }
- std::vector<I> idx2 = idx;
- idx2.resize(displayed_dimension + 1);
- out << "<table style='border-style:solid;border-width:1px;'>";
- if (edgeitems == 0 || 2 * edgeitems >= dim)
- {
- for (std::size_t i = 0; i < dim; ++i)
- {
- idx2[displayed_dimension] = i;
- compute_nd_row(out, printer, expr, edgeitems, idx2);
- }
- }
- else
- {
- for (std::size_t i = 0; i < edgeitems; ++i)
- {
- idx2[displayed_dimension] = i;
- compute_nd_row(out, printer, expr, edgeitems, idx2);
- }
- out << "<tr><td><center>\u22ef</center></td></tr>";
- for (std::size_t i = dim - edgeitems; i < dim; ++i)
- {
- idx2[displayed_dimension] = i;
- compute_nd_row(out, printer, expr, edgeitems, idx2);
- }
- }
- out << "</table>";
- }
- template <class P, class T>
- void compute_nd_table(std::stringstream& out, P& printer, const T& expr, const std::size_t& edgeitems)
- {
- if (expr.dimension() == 0)
- {
- compute_0d_table(out, printer, expr);
- }
- else if (expr.dimension() == 1)
- {
- compute_1d_table(out, printer, expr, edgeitems);
- }
- else
- {
- std::vector<std::size_t> empty_vector;
- compute_nd_table_impl(out, printer, expr, edgeitems, empty_vector);
- }
- }
- template <class E>
- nlohmann::json mime_bundle_repr_impl(const E& expr)
- {
- std::stringstream out;
- std::size_t edgeitems = 0;
- std::size_t size = compute_size(expr.shape());
- if (size > static_cast<std::size_t>(print_options::print_options().threshold))
- {
- edgeitems = static_cast<std::size_t>(print_options::print_options().edge_items);
- }
- if (print_options::print_options().precision != -1)
- {
- out.precision(print_options::print_options().precision);
- }
- detail::printer<E> printer(out.precision());
- xstrided_slice_vector slice_vector;
- detail::recurser_run(printer, expr, slice_vector, edgeitems);
- printer.init();
- compute_nd_table(out, printer, expr, edgeitems);
- auto bundle = nlohmann::json::object();
- bundle["text/html"] = out.str();
- return bundle;
- }
- template <class F, class CT>
- class xfunctor_view;
- template <class F, class CT>
- nlohmann::json mime_bundle_repr(const xfunctor_view<F, CT>& expr)
- {
- return mime_bundle_repr_impl(expr);
- }
- template <class F, class... CT>
- class xfunction;
- template <class F, class... CT>
- nlohmann::json mime_bundle_repr(const xfunction<F, CT...>& expr)
- {
- return mime_bundle_repr_impl(expr);
- }
- template <class EC, layout_type L, class SC, class Tag>
- class xarray_container;
- template <class EC, layout_type L, class SC, class Tag>
- nlohmann::json mime_bundle_repr(const xarray_container<EC, L, SC, Tag>& expr)
- {
- return mime_bundle_repr_impl(expr);
- }
- template <class EC, std::size_t N, layout_type L, class Tag>
- class xtensor_container;
- template <class EC, std::size_t N, layout_type L, class Tag>
- nlohmann::json mime_bundle_repr(const xtensor_container<EC, N, L, Tag>& expr)
- {
- return mime_bundle_repr_impl(expr);
- }
- template <class ET, class S, layout_type L, bool SH, class Tag>
- class xfixed_container;
- template <class ET, class S, layout_type L, bool SH, class Tag>
- nlohmann::json mime_bundle_repr(const xfixed_container<ET, S, L, SH, Tag>& expr)
- {
- return mime_bundle_repr_impl(expr);
- }
- template <class F, class CT, class X, class O>
- class xreducer;
- template <class F, class CT, class X, class O>
- nlohmann::json mime_bundle_repr(const xreducer<F, CT, X, O>& expr)
- {
- return mime_bundle_repr_impl(expr);
- }
- template <class VE, class FE>
- class xoptional_assembly;
- template <class VE, class FE>
- nlohmann::json mime_bundle_repr(const xoptional_assembly<VE, FE>& expr)
- {
- return mime_bundle_repr_impl(expr);
- }
- template <class VEC, class FEC>
- class xoptional_assembly_adaptor;
- template <class VEC, class FEC>
- nlohmann::json mime_bundle_repr(const xoptional_assembly_adaptor<VEC, FEC>& expr)
- {
- return mime_bundle_repr_impl(expr);
- }
- template <class CT>
- class xscalar;
- template <class CT>
- nlohmann::json mime_bundle_repr(const xscalar<CT>& expr)
- {
- return mime_bundle_repr_impl(expr);
- }
- template <class CT, class X>
- class xbroadcast;
- template <class CT, class X>
- nlohmann::json mime_bundle_repr(const xbroadcast<CT, X>& expr)
- {
- return mime_bundle_repr_impl(expr);
- }
- template <class F, class R, class S>
- class xgenerator;
- template <class F, class R, class S>
- nlohmann::json mime_bundle_repr(const xgenerator<F, R, S>& expr)
- {
- return mime_bundle_repr_impl(expr);
- }
- template <class CT, class... S>
- class xview;
- template <class CT, class... S>
- nlohmann::json mime_bundle_repr(const xview<CT, S...>& expr)
- {
- return mime_bundle_repr_impl(expr);
- }
- template <class CT, class S, layout_type L, class FST>
- class xstrided_view;
- template <class CT, class S, layout_type L, class FST>
- nlohmann::json mime_bundle_repr(const xstrided_view<CT, S, L, FST>& expr)
- {
- return mime_bundle_repr_impl(expr);
- }
- template <class CTD, class CTM>
- class xmasked_view;
- template <class CTD, class CTM>
- nlohmann::json mime_bundle_repr(const xmasked_view<CTD, CTM>& expr)
- {
- return mime_bundle_repr_impl(expr);
- }
- template <class T, class B>
- class xmasked_value;
- template <class T, class B>
- nlohmann::json mime_bundle_repr(const xmasked_value<T, B>& v)
- {
- auto bundle = nlohmann::json::object();
- std::stringstream tmp;
- tmp << v;
- bundle["text/plain"] = tmp.str();
- return bundle;
- }
- }
- #endif
|