mirror of
				https://github.com/pocketpy/pocketpy
				synced 2025-10-30 16:30:16 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			432 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			432 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /***************************************************************************
 | |
|  * 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
 |