Modal Extension
This extension has no associated syntax for MooseDown files.
The Modal extension renders modal windows containing code content and generates the anchor elements to trigger them. The tokens may either include a string of content explicitly or the absolute path of a project file to read content from. These tokens spawn from other MooseDocs extensions. For example, an automatic link to a source file creates a modal displaying its complete content, as demonstrated in Example 1.
Example 1: Modal trigger generated by the AutoLink extension.
Currently, the Modal extension is strictly for displaying code content. An extension may still create modals that display other types of content by using the appropriate style classes. For example, the search button at the top of this page triggers a modal created by the Navigation extension.
Configuration
The Modal extension implements a procedure to prevent the display of file contents, which helps to ensure that sensitive or proprietary information is not accidentally revealed to the public, as multiple extensions create these tokens. For example, the !syntax inputs
command from the Application Syntax extension generates a list of MOOSE input files. But toggling the hide_source
option (see Table 1) disables the modal triggers leaving filenames rendered as plain text.
Table 1: Configuration options for the Modal extension.
Key | Default | Description |
---|---|---|
active | True | Toggle for disabling the extension. This only changes the initial active state, use setActive to control at runtime. |
hide_source | False | Disable all modals containing source file content. |
exceptions | [] | A list of shell-style patterns for displaying certain files when the 'hide_source' setting is True. |
The options listed in Table 1 are set via the configuration file. The hide_source
option prevents displaying all source files, not just, e.g., C++ files. Hence, the exceptions
option provides a means for handpicking files deemed safe to reveal, and the configuration below demonstrates its use.
MooseDocs.extensions.modal:
hide_source: True
exceptions:
- '*.C'
- '*.h'
- '*.yml'
- '*.i'
- '*tests'
(contrib/moose/framework/src/kernels/Diffusion.C)
// This file is part of the MOOSE framework
// https://www.mooseframework.org
//
// All rights reserved, see COPYRIGHT for full restrictions
// https://github.com/idaholab/moose/blob/master/COPYRIGHT
//
// Licensed under LGPL 2.1, please see LICENSE for details
// https://www.gnu.org/licenses/lgpl-2.1.html
#include "Diffusion.h"
registerMooseObject("MooseApp", Diffusion);
InputParameters
Diffusion::validParams()
{
InputParameters params = Kernel::validParams();
params.addClassDescription("The Laplacian operator ($-\\nabla \\cdot \\nabla u$), with the weak "
"form of $(\\nabla \\phi_i, \\nabla u_h)$.");
return params;
}
Diffusion::Diffusion(const InputParameters & parameters) : Kernel(parameters) {}
Real
Diffusion::computeQpResidual()
{
return _grad_u[_qp] * _grad_test[_i][_qp];
}
Real
Diffusion::computeQpJacobian()
{
return _grad_phi[_j][_qp] * _grad_test[_i][_qp];
}
(contrib/moose/framework/doc/content/css/moose.css)
:root {
--inl-blue: rgba(0, 88, 151, 1.0);
--inl-blue-light: rgba(0, 104, 179, 1.0);
--dark-blue: rgba(0, 44, 78, 1.0);
--gray: rgba(117, 117, 117, 1.0);
/* darkmode */
--darkmode-navigator: rgba(26, 26, 26, 1.0);
--darkmode-back: rgba(35, 35, 35, 1.0);
--darkmode-card: rgba(20, 20, 20, 1.0);
--darkmode-image-card: rgba(10, 10, 10, 1.0);
--darkmode-fore: rgba(200, 200, 200, 1.0);
--dark-navbar: rgba(39, 63, 99, 1.0);
--darker-highlight: rgba(100, 100, 100, 1.0);
--darker-embossed: rgba(80, 80, 80, 1.0);
--pre-textbox: rgba(10, 10, 10, 1.0);
--links-dark: rgba(119, 177, 250, 1.0);
}
main {
line-height: 1.5;
color: rgba(0,0,0,1.0);
font-size: 15px;
font-weight: 300;
}
/* fallback */
@font-face {
font-family: 'Material Icons';
font-style: normal;
font-weight: 400;
src: url('../contrib/fonts/material-icons/material-icons.woff2') format('woff2');
}
.material-icons {
font-family: 'Material Icons';
font-weight: normal;
font-style: normal;
font-size: 24px;
line-height: 1;
letter-spacing: normal;
text-transform: none;
display: inline-block;
white-space: nowrap;
word-wrap: normal;
direction: ltr;
-webkit-font-feature-settings: 'liga';
-webkit-font-smoothing: antialiased;
}
.material-icons .moose-help{
color:white;
margin-left:5px;
}
.moose-float{
box-shadow:unset;
-webkit-box-shadow:unset;
}
.moose-col-icon{
font-size: 32pt;
display:inline-block;
width:100%;
padding-top: 16pt;
color: var(--inl-blue);
text-align:center;
}
.moose-inline-icon{
vertical-align:bottom;
}
.moose-tight-inline-icon {
font-size:inherit;
line-height:inherit;
}
.tabs .tab a:hover, .tabs .tab a.active {
background-color: transparent;
color: var(--inl-blue);
}
.moose-html-rendered-tab{
background-color:#F5F6CE;
}
a {
color: var(--inl-blue);
font-weight: 400;
font-size: 104%;
}
.tabs .tab a
{
background-color: transparent;
color: var(--inl-blue);
font-size: 110%;
}
.tabs .indicator {
background-color: var(--inl-blue);
height:4px;
}
.card-content img{
width:100%;
}
.card .card-title{
font-weight:100;
font-size:130%;
}
.card .card-content{
padding:0;
}
.moose-exception {
color: red;
}
.modal.bottom-sheet{
max-height:85%;
}
.moose-mega-menu{
color: black;
width:85%;
font-size:70%;
}
li.moose-mega-menu-trigger i{
margin-left:0;
}
.moose-mega-menu-wrapper{
margin:20px;
}
.moose-mega-menu-wrapper h1,
.moose-mega-menu-wrapper h2,
.moose-mega-menu-wrapper h3,
.moose-mega-menu-wrapper h4,
.moose-mega-menu-wrapper h5,
.moose-mega-menu-wrapper h6{
margin:0;
padding:0;
padding-bottom:6px;
font-size:125%;
font-weight:500;
}
.moose-mega-menu-wrapper ol,
.moose-mega-menu-wrapper ul{
margin:0;
margin-bottom:15px;
}
/*
Inline code snippets (using backtics)
*/
div.moose-code-compare pre
{
font-size: 85%;
}
/*
All code blocks (the ones with black backgrounds
*/
code[class*="language-"],
pre[class*="language-"]
{
font-size: 85%;
line-height: 1.15;
}
pre.moose-pre{
max-height:350px;
}
code, kbd, pre, samp {
font-family: monospace, monospace;
font-size: 1em;
/*background-color: #9e9e9e24;*/
}
.moose-disabled{
color:darkviolet;
}
div.moose-modal-button {
position: absolute;
top: -10px;
right: -10px;
}
html, body {
height: 100%;
}
.moose-video-div video.moose-video {
display: block;
}
img.moose-image{
padding:5px;
}
/* TABLE OF CONTENTS */
.table-of-contents *,
.moose-bibliography *{
text-align: left;
}
.table-of-contents
{
height: 95vh;
overflow-y: scroll;
overflow-x: hidden;
}
.table-of-contents a{
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.table-of-contents a.active {
border-left: 2px solid var(--inl-blue);
}
.nav ul:not(.browser-default) li{
list-style-type: none;
}
.page-wrap {
min-height: 100%;
/* equal to footer height */
margin-bottom: -142px;
}
.page-wrap:after {
content: "";
display: block;
}
.page-footer, .page-wrap:after {
height: 142px;
}
h1, h2, h3, h4, h5, h6 {
text-align: left;
margin-top: 12px;
}
/* HEADINGS */
body{
counter-reset:h2count;
}
.section{
padding-bottom:0;
}
h1 {
font-size:200%;
font-weight:500;
margin-top:24px;
margin-bottom: 12px;
}
h1:first-of-type{
margin-top:48px;
}
h2{
font-size:180%;
font-weight:400;
padding-bottom: 0;
margin-bottom: 0;
}
h3 {
font-size:160%;
font-weight:20000;
margin-bottom: 0;
padding-bottom: 0;
}
h4 {
font-size:140%;
font-weight:300;
margin-bottom:6px;
}
h5 {
font-size:120%;
font-weight:100;
margin-bottom:6px;
}
h6 {
font-size:100%;
font-weight:100;
margin-bottom:6px;
}
h1 + p,
h2 + p,
h3 + p,
h4 + p,
h5 + p,
h6 + pg{
margin-top:0;
}
ul {
margin-left:1.5rem;
}
div.moose-pysyntax-class .moose-pysyntax-member-heading,
div.moose-pysyntax-class .moose-pysyntax-member-heading ~ *{
margin-left:40px;
}
/* SEARCH RESULTS */
.moose-search-result{
margin-bottom:1ex;
}
.moose-search-result-title{
font-size: 90%;
font-weight: 400;
margin: 0;
}
.moose-search-result-content{
font-size: 75%;
font-weight: 100;
margin: 0;
}
.modal-content.container.moose-search-modal-content{
padding:0;
}
/* NAME/HOME link */
.moose-logo{
margin-right:30px;
}
/* LAYOUT (ROWS/COLUMNS) */
.moose-row{
display:flex;
}
/* BIBTEX */
.moose-cite-list li,
.moose-citep-list li{
padding-left:1ex;
padding:0px;
display:inline;
}
.moose-bibtex-modal pre{
line-height:1.25;
}
blockquote {
border-left: 5px solid var(--inl-blue);
}
.moose-listing-div p.moose--caption
{
border-bottom-style: solid;
border-width: 3px;
margin-bottom: 0;
}
.moose-table-div p.moose-float-caption
{
border-bottom-style: solid;
border-width: 3px;
margin-bottom: 0;
}
.moose-table-div tr:hover
{
background: beige;
}
.moose-table-div table thead
{
border-bottom-style: solid;
border-width: 1px;
}
.moose-table-div table tbody td, th{
padding-top: 5px;
padding-bottom: 5px;
line-height: 1.25;
}
.moose-listing-div pre
{
margin-top: 0;
margin-bottom: 0;
}
.moose-float-div p.moose-float-caption{
text-align: left;
margin-top: 0;
margin-bottom: 0;
}
.moose-float-div span.moose-float-caption-heading
{
font-weight: 600;
}
.moose-figure-div p.moose-float-caption{
margin-bottom: 30px;
}
.moose-caption{
font-size:100%;
margin:0;
}
.moose-caption-heading{
font-weight: 600;
}
.moose-caption-text{
font-weight: 300;
}
.moose-listing-link{
text-align: right;
data-position: bottom;
}
.moose-site-generated{
text-align: left;
float: left;
}
.moose-edit-markdown{
text-align: right;
}
.moose-copy-button{
box-sizing: padding-box;
position:relative;
bottom: 15px;
left: 15px;
float:right;
padding-left: 6px;
padding-right: 6px;
font-size: small;
opacity: 0.15;
}
.moose-copy-button:hover{
opacity:1;
}
.toc-wrapper {
width:220px;
}
.moose-code-links,
.moose-doxygen-link {
padding: 2px;
font-size:80%;
margin-top:10px;
width:100%;
}
.moose-code-links {
text-transform: none;
text-overflow: ellipsis;
}
a.moose-bad-link,
a.moose-unknown-reference{
color:red;
}
/* Children/Input file lists */
ul.moose-list-children,
ul.moose-list-inputs{
max-height:400px;
overflow-y:scroll;
}
li{
padding-left:15px;
}
.collapsible li{
padding-left:0;
}
.moose-chip{
margin-left: 10px;
bottom: 8px;
position: relative;
}
#logo-container {
height: 57px;
margin-bottom: 32px;
}
.collapsible-header .row{
margin:0;
}
.collapsible-body{
padding:0px;
padding-left: 30px;
padding-top: 5px;
padding-bottom: 15px;
padding-right: 30px;
}
.collapsible-header .moose-parameter-name{
font-weight:600;
}
.moose-parameter-name{
color:var(--inl-blue);
}
.collapsible-header .moose-parameter-header-default{
color:var(--gray);
font-weight:100;
}
.collapsible-header .moose-parameter-header-description{
white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;
color:var(--gray);
}
.moose-parameter-header-default{
white-space:nowrap;
padding-left:10px;
font-weight:400;
}
.moose-parameter-header-description{
padding-left:10px;
font-size:85%;
font-weight:400;
}
.moose-parameter-header-default::before{
content:"(";
}
.moose-parameter-header-default::after{
content:")";
}
.moose-parameter-description span,
.moose-parameter-description-default span,
.moose-parameter-description-cpptype span,
.moose-parameter-description-doc-unit span,
.moose-parameter-description-options span,
.moose-parameter-description-controllable span{
padding-right:10px;
font-weight:100;
}
li.active .collapsible-header .moose-collection-description,
li.active .collapsible-header .moose-parameter-header-description,
li.active .collapsible-header .moose-parameter-header-default{
display:none;
}
li.active .collapsible-header .moose-collection-name,
li.active .collapsible-header .moose-parameter-name{
overflow:unset;
}
nav,
.btn,
.btn-small,
.btn-large,
footer.page-footer{
background-color:var(--inl-blue);
}
.side-nav .collapsible li.active a.active,
.side-nav.fixed .collapsible li.active a.active {
background-color:#e8e8e8;
}
.side-nav .collapsible ul:last-child a.active:last-child,
.side-nav.fixed .collapsible ul:last-child a.active:last-child{
background-color:var(--inl-blue);
color:#fff;
font-weight:500;
}
footer.page-footer {
padding-top:0px;
}
.container{
width:80%;
max-width: 1280px;
}
.side-nav .collapsible li,
.side-nav.fixed .collapsible li{
color:var(--gray);
font-family: sans-serif;
font-weight:300;
}
.side-nav .collapsible li{
padding-left:10px;
}
.side-nav .collapsible li.active a,
.side-nav.fixed .collapsible li.active a
{
color:var(--gray);
font-family: sans-serif;
font-weight:300;
}
.breadcrumb-nav{
margin-top: 24px;
padding-left: 12px;
background-color: transparent;
}
a.breadcrumb{
text-decoration:underline
}
.breadcrumb{
color:var(--gray);
font-family: sans-serif;
font-weight:300;
}
.breadcrumb:before{
color:var(--gray);
}
.breadcrumb:last-child{
color:var(--gray);
font-family: sans-serif;
font-weight:500;
}
.page-title{
font-size:x-large;
}
.github-mark, .github-logo{
filter: invert(100%);
height: 36px;
vertical-align: middle;
padding-bottom: 4px;
padding-right: 4px;
}
.gitlab-logo{
height: 3em;
vertical-align: middle;
padding-bottom: 4px;
padding-right: 4px;
}
input[type="search"] {
height: 64px !important; /* or height of nav */
}
.dropdown-trigger .material-icons{
margin-left:0;
}
@media only screen and (max-width : 992px) {
header, main, footer {
padding-left: 0;
}
}
/* Class for when element is above threshold */
.pin-top {
width:220px;
position: relative;
}
/* Class for when element is below threshold */
.pin-bottom {
width:220px;
position: relative;
}
/* Class for when element is pinned */
.pinned {
width:220px;
position: fixed !important;
}
.button-collapse {
color: white;
padding-right: 8px;
}
.parallax-container {
min-height: 380px;
line-height: 0;
height: auto;
color: rgba(255,255,255,.9);
}
.parallax-container .section {
width: 100%;
}
@media only screen and (max-width : 992px) {
.parallax-container .section {
position: absolute;
top: 40%;
}
#index-banner .section {
top: 10%;
}
}
@media only screen and (max-width : 600px) {
#index-banner .section {
top: 0;
}
}
.icon-block {
padding: 0 15px;
}
.icon-block .material-icons {
font-size: inherit;
}
footer.page-footer {
margin: 0;
}
.moose-caption {
padding: 5px;
}
.collection-header a
{
color:white;
}
/* MOOSE SYNTAX LISTS */
.collection.with-header .collection-header {
color:white;
background-color: var(--inl-blue);
font-size:larger;
font-weight:100;
}
.moose-syntax-list li{
white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;
}
.moose-syntax-list li a{
margin-right:1ex;
}
.moose-syntax-item-description{
padding-left:10px;
font-weight:100;
color:var(--gray);
}
.collapsible-header{
padding: 10px;
}
.collapsible-header .moose-collection-description{
white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;
color:var(--gray);
}
.collapsible-header .material-icons{
opacity: 0.5;
margin-left: 0;
margin-right: 5px;
}
/* Slideshows with white backgrounds and captions, need a black drop text shadow */
.carousel-caption {
text-shadow: 1px 1px 9px rgba(0, 0, 0, 1);
}
li p {
margin-top: 0;
margin-bottom: 0;
}
.moose-error,
.moose-katex-error{
color: red;
}
/*https://coderwall.com/p/ovxeha/fit-to-container-video-image-in-css-aspect-ratio-friendly*/
.moose-card div.card-image,
.moose-card div.card-image div.moose-video-div{
height:420px;
text-align:center;
}
.moose-card div.card-image div.moose-video-div:before{
content:"";
width:1px;
height:100%;
display:inline-block;
vertical-align:middle;
margin-left:-1px;
}
.moose-card div.card-image div.moose-video-div video.moose-video,
.moose-card div.card-image div.material-placeholder{
max-width:100%;
max-height:100%;
display:inline-block;
vertical-align:middle;
}
span.badge.new{
float:none;
padding: 4px 8px 4px 8px;
}
.moose-collection-description span.moose-page-status{
float:right;
}
span.badge.new.info{
background-color: #528452;
}
span.badge.new.note{
background-color: #3a7296;
}
span.badge.new.important{
background-color: #b100b0;
}
span.badge.new.warning{
background-color: #968b2b;
}
span.badge.new.danger{
background-color: #b14d00;
}
span.badge.new.error{
background-color: #940000;
}
span.badge.new.pass{
background-color: #148a00;
}
.moose-status-container{
margin-top: 0;
margin-bottom: 0;
float: right;
}
/* MOOSE Build status CSS */
.boxed_job_status_Passed {
vertical-align: middle;
text-align: center;
width: 60px;
background-color:#A9F5A9;
box-shadow: 2px 2px 3px #888888;
display: inline-block
}
.boxed_job_status_Failed {
vertical-align: middle;
text-align: center;
width: 60px;
background-color:#F5A9A9;
box-shadow: 2px 2px 3px #888888;
display: inline-block
}
.boxed_job_status_Running {
vertical-align: middle;
text-align: center;
width: 60px;
background-color:#F2F5A9;
box-shadow: 2px 2px 3px #888888;
display: inline-block
}
.boxed_job_status_Failed_OK {
vertical-align: middle;
text-align: center;
width: 60px;
background-color:#FAAC58;
box-shadow: 2px 2px 3px #888888;
display: inline-block
}
.boxed_job_status_Not_Started {
vertical-align: middle;
text-align: center;
width: 60px;
background-color:#FFFFFF;
box-shadow: 2px 2px 3px #888888;
display: inline-block;
}
.boxed_job_status_Canceled {
vertical-align: middle;
text-align: center;
width: 60px;
background-color:#CCCCCC;
box-shadow: 2px 2px 3px #888888;
display: inline-block;
}
#moose-markdown-content li {
list-style-type: disc;
padding-left: 0;
margin-left: 15px;
}
#moose-markdown-content strong {
font-weight: bold;
}
#moose-markdown-content ul.collapsible li {
list-style-type: none;
}
/* COLLAPSIBLE SECTIONS */
summary {
display: block;
}
summary::-webkit-details-marker {
display: none;
}
.moose-section-icon::before {
font-family: Material Icons;
content: 'keyboard_arrow_right';
vertical-align: middle;
color: #bdbdbd;
}
details[open] > summary .moose-section-icon::before{
content: 'keyboard_arrow_down';
}
details[open] hr{
display: none;
}
details[open] .moose-section-content {
animation: sweep 0.2s ease-in-out;
@keyframes sweep {
0% {opacity: 0; margin-top: 0px}
100% {opacity: 1; margin-left: 0px}
}
}
/* Dropdown Menu Text Color */
.dropdown-content li > a, .dropdown-content li > span {
color: var(--inl-blue);
font-weight:400;
}
/* MEGA MENU: Dropdown content (hidden by default) */
div.moose-mega-menu-content{
display: none;
position: absolute;
background-color: white;
width: 90%;
margin-left:5%;
padding-left: 30px;
padding-right: 30px;
left: 0;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
/* Text and background color for dark mode */
@media (prefers-color-scheme: dark), (prefers-dark-interface) {
body, table, li.list-group-item, .navbar, ol.breadcrumb, div.row, .well, .form-control, .sidenav, .sidenav > li a {
background: var(--darkmode-back);
color: var(--darkmode-fore);
}
.dropdown-content, .dropdown-content li > a, .dropdown-content li > span {
background-color: var(--darkmode-navigator);
color: var(--darkmode-fore);
}
.dropdown-content li > a:hover {
background-color: var(--darker-highlight);
color: var(--darkmode-fore);
}
/* Google Custom Search (CSE) */
.cse .gsc-control-cse, .gsc-control-cse {
background-color: var(--darkmode-back) !important;
border: 0px !important;
}
.gsc-search-box tbody tr {
border-bottom: 0px solid !important;
}
.gsc-input-box {
border: 0px !important;
background: var(--darkmode-back) !important;
}
.gsc-result-info, .gsc-orderby-label {
color: var(--darkmode-fore) !important;
}
.cse .gsc-webResult.gsc-result:hover, .gsc-webResult.gsc-result:hover, .gsc-webResult.gsc-result.gsc-promotion:hover, .gsc-results .gsc-imageResult-classic:hover, .gsc-results .gsc-imageResult-column:hover {
border: 0px solid !important;
}
.gsc-webResult.gsc-result, .gsc-above-wrapper-area {
border: 0px solid !important;
}
.gs-result .gs-title, .gs-result .gs-title * {
color: var(--links-dark) !important;
font-size: 110% !important;
}
.gsc-preview-reviews, .gsc-control-cse .gs-snippet, .gsc-control-cse .gs-promotion em, .gsc-control-cse .gs-snippet, .gsc-control-cse .gs-promotion em {
color: var(--darkmode-fore) !important;
font-size: 95% !important;
}
.gs-spelling {
color: var(--darkmode-fore) !important;
}
.gs-spelling a {
color: var(--links-dark) !important;
}
/* Order is important for the next set */
.gsc-results .gsc-cursor-box .gsc-cursor-page {
color: var(--darker-embossed) !important;
}
.gsc-results .gsc-cursor-box .gsc-cursor-current-page {
color: var(--links-dark) !important;
}
.gsc-results .gsc-cursor-box .gsc-cursor-page:hover {
color: white !important;
}
/* End Order is important */
.gcsc-find-more-on-google, .gcsc-find-more-on-google-magnifier {
color: var(--links-dark) !important;
fill: var(--links-dark) !important;
}
/* End CSE */
.modal {
background-color: var(--darkmode-back);
}
.modal .modal-footer {
background-color: var(--darkmode-back);
}
.modal.modal-fixed-footer {
background-color: var(--darkmode-back);
}
.modal.modal-fixed-footer .modal-footer {
border-top: 1px solid rgba(166, 166, 166, 0.1);
}
.btn-flat {
color: var(--darkmode-fore);
}
nav ul a:hover {
background-color: rgba(0, 0, 0, 0.33);
}
.grey-text.text-darken-4 {
color: #eaeaea !important;
}
div.moose-mega-menu-content {
background-color: var(--darkmode-back);
}
.card {
background-color: transparent;
}
.card .card-reveal {
background-color: var(--darkmode-card);
color: var(--darkmode-fore);
}
.moose-card div.card-image{
background-color:var(--darkmode-image-card);
}
.collection.with-header .collection-header {
color: white;
background-color: var(--dark-navbar);
}
.collection.with-header .collection-header {
border-bottom: 1px solid #000;
}
.collection {
border: 1px solid #000;
}
.collection .collection-item {
background-color: var(--darkmode-back);
border-bottom: 1px solid #000;
}
.collapsible-header {
background-color: var(--darkmode-back);
border-bottom: 1px solid #000;
}
.collapsible {
border-top: 1px solid #000;
border-right: 1px solid #000;
border-left: 1px solid #000;
}
.collapsible-body {
border-bottom: 1px solid #000;
}
span.badge {
color: white;
}
a {
color: var(--links-dark);
font-weight: 100;
font-size: 100%;
}
.moose-caption-heading {
font-weight: 900;
}
.moose-table-div tr:hover {
background: #42423b;
}
tr {
border-bottom: 1px solid rgba(0, 0, 0, 0.82);
}
.table-of-contents a {
color: var(--darker-highlight);
}
.breadcrumb {
color: var(--darker-embossed);
}
.breadcrumb:last-child {
color: var(--darker-highlight);
}
nav, .btn, .btn-small, .btn-large, footer.page-footer {
background-color: var(--dark-navbar);
}
pre.moose-pre {
background-color: var(--pre-textbox);
}
h1, h2, h3, h4, h5, h6 {
color: white;
}
code {
color: white;
}
#moose-search-box{
color: white;
}
#gsc-i-id1{
padding:8px !important;
background:var(--darkmode-card) !important;
color:white;
}
.tabs{
background-color:var(--dark-navbar);
}
.tabs .tab a:hover,
.tabs .tab a.active,
.tabs .tab a {
background-color: transparent;
color: white;
}
}
div.moose-algorithm-line {
display: flex;
justify-content: space-between;
}
div.moose-algorithm {
border-left: solid 10px gray;
border-right: solid 2px black;
border-top: solid 2px black;
border-bottom: solid 2px black;
padding-left:10px;
padding-right:10px;
line-height:15px;
}
/* Portrait Mobile Devices */
@media only screen
and (min-device-width: 320px)
and (max-device-width: 480px)
and (-webkit-min-device-pixel-ratio: 2)
and (orientation: portrait) {
header, main, footer {
font-size: 38px;
}
a {
font-size: 38px;
}
.moose-content-next {
margin-top: 8px;
}
.material-icons {
font-size: 60px !important;
}
.github-mark, .github-logo {
height: 76px;
}
nav, nav .nav-wrapper i, nav a.sidenav-trigger, nav a.sidenav-trigger i {
height: 86px;
line-height: 86px;
padding-right: 30px;
}
.sidenav li > a {
font-size: 50px;
/*padding: 30px;*/
/*height: 60px;*/
}
.sidenav {
width: 80%;
/*margin-top: 86px;*/
}
.sidenav li > a > i, .sidenav li > a > [class^="mdi-"], .sidenav li > a li > a > [class*="mdi-"], .sidenav li > a > i.material-icons {
/*margin: -57px 824px 0px 0px;*/
color: white;
}
.sidenav > li {
padding-bottom: 25px;
}
.sidenav > li > ul > li {
padding-bottom: 40px;
}
.row .col.m4 {
width: 100%;
}
.row .col.m8 {
width: 100%;
}
.card .card-title {
font-weight: 100;
font-size: 90%;
}
.container {
width: 100%;
}
.btn, .btn-large, .btn-small, .btn-flat {
height: 50px;
line-height: 50px;
font-size: 35px;
}
.btn-floating {
font-size: 20px;
}
.moose-content-next, .moose-content-previous {
font-size: 36px !important;
}
}
/* Landscape Mode Mobile Devices */
@media only screen
and (min-device-width: 320px)
and (max-device-width: 1000px)
and (orientation: landscape)
and (-webkit-min-device-pixel-ratio: 2) {
header, main, footer {
font-size: 20px;
}
a {
font-size: 20px;
}
.moose-content-next {
margin-top: 0px;
}
.material-icons {
font-size: 40px !important;
}
.github-mark, .github-logo {
height: 40px;
}
nav, nav .nav-wrapper i, nav a.sidenav-trigger, nav a.sidenav-trigger i {
height: 60px;
line-height: 60px;
padding-right: 30px;
}
.sidenav li > a {
font-size: 40px;
}
.sidenav {
width: 80%;
}
.sidenav li > a > i, .sidenav li > a > [class^="mdi-"], .sidenav li > a li > a > [class*="mdi-"], .sidenav li > a > i.material-icons {
/*margin: -57px 824px 0px 0px;*/
color: white;
}
.sidenav > li {
padding-bottom: 25px;
}
.sidenav > li > ul > li {
padding-bottom: 30px;
}
.sidenav > li > ul > li > a {
margin-left: 10px;
}
.dropdown-content {
width: 80% !important;
}
.dropdown-content > li {
margin-left: 30px !important;
}
.row .col.m4 {
width: 33%;
}
.row .col.m8 {
width: 33%;
}
.card .card-title {
font-weight: 100;
font-size: 90%;
}
.container {
width: 100%;
}
.drag-target {
width: 100px;
}
}
(contrib/moose/python/MooseDocs/extensions/navigation.py)
#* This file is part of the MOOSE framework
#* https://www.mooseframework.org
#*
#* All rights reserved, see COPYRIGHT for full restrictions
#* https://github.com/idaholab/moose/blob/master/COPYRIGHT
#*
#* Licensed under LGPL 2.1, please see LICENSE for details
#* https://www.gnu.org/licenses/lgpl-2.1.html
import os
import uuid
import logging
import json
import moosetree
from . import common
from ..base import components, renderers, Extension
from ..common import exceptions, write
from ..tree import html, pages, tokens
from . import core, heading
LOG = logging.getLogger(__name__)
def make_extension(**kwargs):
return NavigationExtension(**kwargs)
class NavigationExtension(Extension):
"""
Extension for navigation items.
"""
@staticmethod
def defaultConfig():
config = Extension.defaultConfig()
config['menu'] = (dict(), "Navigation items, this can either be a *.menu.md file or dict. "\
"The former creates a 'mega men' and the later uses dropdowns.")
config['google-cse'] = (None, "Enable Google search by supplying the Google 'search engine ID'.")
config['search'] = (True, "Enable/disable the search bar.")
config['home'] = ('/index.md', "The homepage for the website.")
config['repo'] = (None, "The source code repository.")
config['name'] = (None, "The name of the website (e.g., MOOSE)")
config['long-name'] = (None, "A long version of the page name that is used in the title, 'name' by default.")
config['breadcrumbs'] = (True, "Toggle for the breadcrumb links at the top of page.")
config['sections'] = (True, "Group heading content into <section> tags.")
config['scrollspy'] = (True, "Enable/disable the scrolling table of contents.")
config['collapsible-sections'] = ([None, None, None, None, None, None],
"Collapsible setting for the six heading level " \
"sections, possible values include None, 'open', and " \
"'close'. Each indicates if the associated section " \
"should be collapsible, if so should it be open or " \
"closed initially. The 'sections' setting must be " \
"True for this to operate.")
return config
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.__menu_cache = dict()
def extend(self, reader, renderer):
self.requires(core, heading)
menu = self.get('menu')
if (not menu) and (renderer.get('navigation', None) is not None):
msg = "The navigation setting in the MaterializeRenderer is deprecated, " \
"please update your code to use the 'menu' setting within the " \
"MooseDocs.extensions.navigation extension."
LOG.warning(msg)
self.update(menu=renderer.get('navigation'))
if isinstance(renderer, renderers.MaterializeRenderer):
renderer.addJavaScript('nav', 'js/navigation.js')
cx = self.get('google-cse', None)
if cx is not None:
renderer.addJavaScript("google_cse", "https://cse.google.com/cse.js?cx={}".format(cx))
elif self.get('search', False):
renderer.addJavaScript('fuse', "contrib/fuse/fuse.min.js")
renderer.addJavaScript('fuse_index', "js/search_index.js")
def initPage(self, page):
"""Initialize page with Extension settings."""
self.initConfig(page, 'google-cse',
'search',
'name',
'breadcrumbs',
'sections',
'scrollspy',
'collapsible-sections')
if page.local.endswith('.menu.md'):
self.setConfig(page, 'breadcrumbs', False)
page['search'] = list()
def postRender(self, page, result):
"""Called after rendering is complete."""
if not isinstance(self.translator.renderer, renderers.MaterializeRenderer):
return
root = result.root
header = moosetree.find(root, lambda n: n.name == 'header')
nav = html.Tag(html.Tag(header, 'nav'), 'div', class_='nav-wrapper container')
container = moosetree.find(root, lambda n: n.name == 'main').children[0]
row = container(0)
col = container(0)(0)
self._addTopNavigation(nav, page)
self._addSideNavigation(nav, page)
if self.getConfig(page, 'breadcrumbs'):
self._addBreadcrumbs(container, page)
if self.getConfig(page, 'sections'):
self._addSections(col, page)
if self.getConfig(page, 'scrollspy'):
col.addClass('col', 's12', 'm12', 'l10')
toc = html.Tag(row, 'div', class_="col hide-on-med-and-down l2")
self._addContents(toc, col, page)
else:
col.addClass('col', 's12', 'm12', 'l12')
if (self.getConfig(page, 'google-cse') is not None) or self.getConfig(page, 'search'):
self._addSearch(nav, page)
repo = self.get('repo', None)
if repo is not None:
self._addRepo(nav, page)
head = moosetree.find(root, lambda n: n.name == 'head')
self._addTitle(head, root, page)
self._addName(nav, page)
def postTokenize(self, page, ast):
index = []
title = None
for head in moosetree.findall(ast, lambda n: n.name == 'Heading'):
if (head['level'] == 1) and (title is None):
title = head.text()
id_ = head.get('id')
if id_ == '':
id_ = head.text('-').lower()
index.append(dict(title=title, text=head.text(), bookmark=id_))
page['search'].extend(index)
def postExecute(self):
"""Build the JSON file containing the index data for 'search' option.
The 'search' option is used by internal apps that require a search.
"""
dest = self.translator.get('destination')
iname = os.path.join(dest, 'js', 'search_index.js')
items = []
# TODO: Remove the ability to use a URL for 'home'
home_param = self.get('home')
home = self.translator.findPage(home_param.lstrip('/'),
exact=home_param.startswith('/'),
throw_on_zero=False)
if home is None:
LOG.warning("The use of a URL in the 'home' option is deprecated. By default the home " \
"page is set to '/index.md', which is the 'index.md' at the root content " \
"directory of the website. If this is correct for your website then " \
"remove this option from the config.yml, otherwise set the value to " \
"the desired markdown page, use a leading '/' for exact match.")
home = self.get('home')
for page in self.translator.getPages():
if isinstance(home, pages.Page):
location = page.relativeDestination(home)
else:
location = page.destination.replace(dest, home)
for data in page.get('search', list()):
url = '{}#{}'.format(location, data['bookmark'])
items.append(dict(title=data['title'], text=data['text'], location=url))
if not os.path.isdir(os.path.dirname(iname)):
os.makedirs(os.path.dirname(iname))
write(iname, 'var index_data = {};'.format(json.dumps(items)))
def _addName(self, nav, page):
"""
Add the page name to the left-hand side of the top bar.
Inputs:
nav[html.Tag]: The <div> containing the navigation for the page being generated.
page[page.PageNodeBase]: The current page being converted.
"""
name = self.getConfig(page, 'name')
# TODO: Remove the ability to use a URL for 'home' (see `postExecute`)
home_param = self.get('home')
home = self.translator.findPage(home_param.lstrip('/'),
exact=home_param.startswith('/'),
throw_on_zero=False)
if home is not None:
href = home.relativeDestination(page)
else:
href = str(self.get('home', '#!'))
if name is not None:
a = html.Tag(None, 'a', class_='left moose-logo hide-on-med-and-down',
href=href,
string=str(name),
id_='home-button')
nav.insert(0, a)
def _addRepo(self, nav, page):
"""
Add the repository link to the navigation bar.
Inputs:
nav[html.Tag]: The <div> containing the navigation for the page being generated.
page[page.PageNodeBase]: The current page being converted.
"""
repo = self.get('repo')
a = html.Tag(None, 'a', href=repo, class_='right')
if 'github' in repo:
img0 = self.translator.findPage('github-logo.png')
img1 = self.translator.findPage('github-mark.png')
html.Tag(a, 'img', src=img0.relativeDestination(page), class_='github-mark')
html.Tag(a, 'img', src=img1.relativeDestination(page), class_='github-logo')
elif 'gitlab' in repo:
img = self.translator.findPage('gitlab-logo.png')
html.Tag(a, 'img', src=img.relativeDestination(page), class_='gitlab-logo')
nav.insert(0, a)
def _addTitle(self, head, root, page):
"""
Add content to <title> tag.
Inputs:
head[html.Tag]: The <head> tag for the page being generated.
ast[tokens.Token]: The root node for the AST.
page[page.PageNodeBase]: The current page being converted.
"""
# Locate h1 heading, if it is found extract the rendered text
h = heading.find_heading(page)
page_name = page.name
long_name = self.get('long-name')
name = self.get('name')
if h is not None:
html.Tag(head, 'title', string='{} | {}'.format(h.text(), name))
elif long_name is not None:
html.Tag(head, 'title', string=long_name)
elif name is not None:
html.Tag(head, 'title', string='{} | {}'.format(page_name, name))
else:
html.Tag(head, 'title', string=str(page_name))
def _addSearch(self, parent, page):
# Search button
btn = html.Tag(parent, 'a', class_="modal-trigger", href="#moose-search")
html.Tag(btn, 'i', string='search', class_="material-icons")
# Search modal
div = html.Tag(moosetree.find(parent.root, lambda n: n.name == 'header'), 'div',
id_="moose-search",
class_="modal modal-fixed-footer moose-search-modal")
container = html.Tag(div, 'div',
class_="modal-content container moose-search-modal-content")
cx = self.get('google-cse', None)
if cx is not None:
html.Tag(container, 'div', class_='gcse-search')
elif self.get('search', False):
row = html.Tag(container, 'div', class_="row")
col = html.Tag(row, 'div', class_="col l12")
box_div = html.Tag(col, 'div', class_="input-field")
html.Tag(box_div, 'input',
type_='text',
id_="moose-search-box",
onkeyup="mooseSearch()",
placeholder=self.get('home'))
result_wrapper = html.Tag(row, 'div')
html.Tag(result_wrapper, 'div', id_="moose-search-results", class_="col s12")
footer = html.Tag(div, 'div', class_="modal-footer")
html.Tag(footer, 'a', href='#!', class_="modal-close btn-flat", string=u'Close')
def _addTopNavigation(self, parent, page):
"""Create navigation in the top bar."""
ul = html.Tag(parent, 'ul', class_="right hide-on-med-and-down")
self._createNavigation(ul, page)
def _addSideNavigation(self, parent, page):
"""Adds the hamburgers menu for small screens."""
id_ = uuid.uuid4()
a = html.Tag(parent, 'a', href='#', class_='sidenav-trigger')
a['data-target'] = id_
html.Tag(a, 'i', class_="material-icons", string=u'menu')
ul = html.Tag(parent, 'ul', class_="sidenav", id_=id_)
self._createNavigation(ul, page, mega=False)
def _addBreadcrumbs(self, container, page):
"""
Inserts breadcrumb links at the top of the page.
Inputs:
root[tree.html.Tag]: The tag to which the breadcrumbs should be inserted.
TODO: This is relying on hard-coded .md/.html extensions, that should not be the case.
"""
row = html.Tag(None, 'div', class_="row")
col = html.Tag(row, 'div', class_="col hide-on-med-and-down l12")
nav = html.Tag(col, 'nav', class_="breadcrumb-nav")
div = html.Tag(nav, 'div', class_="nav-wrapper")
container.insert(0, row)
parts = page.local.split(os.sep)
for i in range(1, len(parts)):
current = self.translator.findPage(lambda p: p.local == os.path.join(*parts[:i]))
if isinstance(current, pages.Directory):
idx = self.translator.findPages(os.path.join(current.local, 'index.md'), exact=True)
if idx:
url = os.path.relpath(current.local,
os.path.dirname(page.local)).replace('.md', '.html')
a = html.Tag(div, 'a', href=url,
class_="breadcrumb",
string=current.name)
else:
span = html.Tag(div, 'span', class_="breadcrumb")
html.String(span, content=current.name)
elif isinstance(current, pages.File) and current.name != 'index.md':
url = os.path.relpath(current.local,
os.path.dirname(page.local)).replace('.md', '.html')
a = html.Tag(div, 'a', href=url, class_="breadcrumb")
html.String(a, content=os.path.splitext(current.name)[0])
if not page.local.endswith('index.md'):
html.Tag(div, 'a', href='#', class_="breadcrumb",
string=os.path.splitext(page.name)[0])
def _addSections(self, container, page):
"""
Group content into <section> tags based on the heading tag.
Inputs:
root[tree.html.Tag]: The root tree.html node tree to add sections.read
collapsible[list]: A list with six entries indicating the sections to create as
collapsible.
"""
collapsible = self.getConfig(page, 'collapsible-sections')
if isinstance(collapsible, str):
collapsible = eval(collapsible)
section = container
for child in section.children:
if child.name in ('h1', 'h2', 'h3', 'h4', 'h5', 'h6'):
level = int(child.name[-1])
current = section.get("data-section-level", 0) # get the current section level
if level == current:
section = html.Tag(section.parent, 'section')
elif level > current:
section = html.Tag(section, 'section')
elif level < current:
section = html.Tag(section.parent.parent, 'section')
section['data-section-level'] = level
section['data-section-text'] = child.text()
section['id'] = uuid.uuid4()
if 'data-details-open' in child:
section['data-details-open'] = child['data-details-open']
child.parent = section
for node in moosetree.iterate(container, lambda n: n.name == 'section'):
if 'data-details-open' in node:
status = node['data-details-open']
else:
status = collapsible[node['data-section-level']-1]
if status:
summary = html.Tag(None, 'summary')
node(0).parent = summary
details = html.Tag(None, 'details', class_="moose-section-content")
if status.lower() == 'open':
details['open'] = 'open'
details.children = node.children
summary.parent = details
details.parent = node
icon = html.Tag(None, 'span', class_='moose-section-icon')
summary(0).children = [icon] + list(summary(0).children)
def _addContents(self, toc, content, page):
"""
Add the table of contents right-side bar that used scrollspy.
Inputs:
toc[html.Tag]: Table-of-contents <div> tag.
content[html.Tag]: The complete html content that the TOC is going to reference.
page[page.PageNodeBase]: The current page being converted.
"""
div = html.Tag(toc, 'div', class_='toc-wrapper pin-top')
ul = html.Tag(div, 'ul', class_='section table-of-contents')
for node in moosetree.iterate(content):
if node.get('data-section-level', None) == 2:
node.addClass('scrollspy')
li = html.Tag(ul, 'li')
a = html.Tag(li, 'a',
href='#{}'.format(node['id']),
string=node.get('data-section-text', 'Unknown...'),
class_='tooltipped')
a['data-position'] = 'left'
a['data-tooltip'] = node['data-section-text']
def _createNavigation(self, ul, page, mega=True):
"""Helper for creating navigation lists."""
for key, value in self.get('menu', dict()).items():
li = html.Tag(ul, 'li')
if isinstance(value, str) and value.endswith('menu.md') and mega:
li['class'] = 'moose-mega-menu-trigger'
a = html.Tag(li, 'a', string=key)
html.Tag(a, 'i', class_='material-icons right', string='arrow_drop_down')
self._addMegaMenu(li, value, page)
elif isinstance(value, str):
href = value if value.startswith('http') else self._findPath(page, value)
html.Tag(li, 'a', href=href, string=key)
elif isinstance(value, dict):
id_ = uuid.uuid4()
a = html.Tag(li, 'a', class_='dropdown-trigger', href='#!', string=str(key))
a['data-target'] = id_
a['data-constrainWidth'] = 'false'
html.Tag(a, 'i', class_='material-icons right', string='arrow_drop_down')
self._buildDropdown(ul.parent.parent, page, id_, value)
else:
msg = 'Top-level navigation items must be string or dict.'
LOG.error(msg)
raise exceptions.MooseDocsException(msg)
def _addMegaMenu(self, parent, filename, page):
"""Create a "mega menu" by parsing the *.menu.md file."""
id_ = uuid.uuid4()
header = moosetree.find(parent.root, lambda n: n.name == 'header')
div = html.Tag(header, 'div', id_=id_)
div.addClass('moose-mega-menu-content')
parent['data-target'] = id_
node = self.translator.findPage(filename)
# The "mega" menus appear on every page so the results of the rendered the mega menu
# page(s) and cache the results. When the CIVET/SQA extensions are
# enabled 7000+ pages are generated, thus this cache becomes very important.
key = (os.path.dirname(page.local), node.local) # cache on current directory and menu name
if key not in self.__menu_cache:
wrap = html.Tag(div, 'div', class_='moose-mega-menu-wrapper')
ast = tokens.Token(None)
content = self.translator.reader.read(node)
self.translator.reader.tokenize(ast, content, page)
self.translator.renderer.render(wrap, ast, page)
self.__menu_cache[key] = wrap.copy()
else:
wrap = self.__menu_cache[key].copy()
wrap.parent = div
def _buildDropdown(self, parent, page, tag_id, items):
"""Creates sublist for dropdown navigation."""
ul = html.Tag(parent, 'ul', id_=tag_id, class_='dropdown-content')
for key, value in items.items():
li = html.Tag(ul, 'li')
href = value if value.startswith('http') else self._findPath(page, value)
html.Tag(li, 'a', href=href, string=str(key))
def _findPath(self, page, path):
"""Locates page based on supplied path."""
node = self.translator.findPage(path.lstrip('/'), exact=path.startswith('/'))
if node is None:
msg = 'Failed to locate navigation item: {}.'.format(path)
LOG.error(msg)
raise exceptions.MooseDocsException(msg)
return node.relativeDestination(page)
(contrib/moose/python/MooseDocs/test/config.yml)
Content:
framework:
root_dir: framework/doc/content
content:
- large_media/testing/*
- media/framework/under-construction.gif
- media/framework/github-logo.png
- media/framework/github-mark.png
- large_media/level_set/vortex_out.mp4
- bib/*
- contrib/**
- css/*
- js/*
test:
root_dir: python/MooseDocs/test/content
content:
- "**"
- ~/extensions/external.md
external:
root_dir: python/MooseDocs/test/content
external: True
content:
- extensions/external.md
Renderer:
type: MooseDocs.base.MaterializeRenderer
Extensions:
disable_defaults: True
MooseDocs.extensions.config: default
MooseDocs.extensions.core: default
MooseDocs.extensions.special: default
MooseDocs.extensions.floats: default
MooseDocs.extensions.style: default
MooseDocs.extensions.command: default
MooseDocs.extensions.include: default
MooseDocs.extensions.media: default
MooseDocs.extensions.listing: default
MooseDocs.extensions.autolink: default
MooseDocs.extensions.table: default
MooseDocs.extensions.devel: default
MooseDocs.extensions.package: default
MooseDocs.extensions.alert: default
MooseDocs.extensions.katex:
macros:
\RR: \mathbb{R}
\pf: "\\frac{\\partial #1}{\\partial #2}"
MooseDocs.extensions.bibtex: default
MooseDocs.extensions.materialicon: default
MooseDocs.extensions.layout: default
MooseDocs.extensions.content: default
MooseDocs.extensions.graph: default
MooseDocs.extensions.heading: default
MooseDocs.extensions.shortcut: default
MooseDocs.extensions.gallery: default
MooseDocs.extensions.pdf: default
MooseDocs.extensions.pysyntax: default
MooseDocs.extensions.modal:
hide_source: True
exceptions:
- '*.C'
- '*.h'
- '*.yml'
- '*.i'
- '*tests'
MooseDocs.extensions.datetime: default
MooseDocs.extensions.gitutils: default
MooseDocs.extensions.template:
active: True
MooseDocs.extensions.sqa:
active: True
categories:
MooseDocs:
directories:
- python/MooseDocs/test
chigger:
directories:
- python/chigger/tests
demo:
directories:
- python/MooseDocs/test
specs:
- demo
MooseDocs.extensions.civet:
active: False
test_results_cache: '/tmp/civet/jobs'
remotes:
moose:
url: https://civet.inl.gov
repo: idaholab/moose
MooseDocs.extensions.navigation:
active: True
name: MOOSEDocs
repo: https://github.com/idaholab/moose
home: /index.md
search: False
menu:
Direct: core.md
Mega: mega.menu.md
Dict:
Core: core.md
AutoLink: autolink.md
MooseDocs.extensions.acronym:
active: True
acronyms:
INL: Idaho National Laboratory
MTU: Michigan Technological University
UNH: University of New Hampshire
MooseDocs.extensions.common:
active: True
shortcuts:
MOOSE: https:://mooseframework.org
libMesh: https://libmesh.github.io/
MooseDocs.extensions.appsyntax:
active: True
executable: ${MOOSE_DIR}/test
remove: !include framework/doc/remove.yml
includes:
- framework/include
- test/include
MooseDocs.extensions.ifelse:
active: True
MooseDocs.extensions.algorithm: default
MooseDocs.extensions.analytics:
active: True
google_measurement_id: G-RH7BY5XXNW
MooseDocs.extensions.tagging:
active: True
js_file: tagging.js
allowed_keys:
- application
- foo
- simulation_type
- fiscal_year
Translator:
type: MooseDocs.base.Translator
destination: ${MOOSE_DIR}/python/MooseDocs/test/output/materialize