Returns the compiled CSS from SCSS input

@param string $scss
@param array $includes (optional)

@return string
350141
public function compile( $scss, $includes = [] ) {

		$scss = $this->prependLocalizedVars( $scss );

		try {
			$css = '/* Silence is golden. */'; // If no SCSS input was passed, prevent file write errors by putting a comment in the CSS output.
			$scssphp = new \Leafo\ScssPhp\Compiler;
			if ( ! empty( $scss ) || ! empty( $this->vars ) ) {
				$scssphp->setVariables( $this->vars );
				$scssphp->setImportPaths( $includes );
				$css = $scssphp->compile( $scss );
				$this->vars = []; // Reset
			}
		} catch ( \Exception $e ) {

			$error_message = print_r( $scssphp->getParsedFiles(), true ); // @codingStandardsIgnoreLine
			$_SESSION['pb_errors'][] = sprintf(
				__( 'There was a problem with SASS. Contact your site administrator. Error: %1$s %2$s', 'pressbooks' ),
				$e->getMessage(),
				"<pre>{$error_message}</pre>"
			);

			$this->logException( $e );

			if ( WP_DEBUG ) {
				$this->debug( "/* {$e->getMessage()} */", $scss, 'last-thrown-exception' );
			}

			return ''; // Return empty string on error
		}

		return $css;
	}
1357707
public function applyOverrides( $scss, $overrides = [] ) {

		if ( ! is_array( $overrides ) ) {
			$overrides = (array) $overrides;
		}
		$overrides = implode( "\n", $overrides );

		if ( $this->isCurrentThemeCompatible( 2 ) ) {
			// Prepend override variables (see: http://sass-lang.com/documentation/file.SASS_REFERENCE.html#variable_defaults_).
			$scss = $overrides . "\n" . $scss;
		} else {
			// Append overrides.
			$scss .= "\n" . $overrides;
		}

		return $scss;
	}
77127
public function stylesheets($inputs = array(), $filters = array(), array $options = array())
    {
        if (!isset($options['output'])) {
            $options['output'] = 'css/*.css';
        }

        return $this->getAssetUrls($inputs, $filters, $options);
    }
60292
protected function forceAbsRelativePathsInCss($css)
    {
        if (!($css = (string) $css)) {
            return $css; // Nothing to do.
        }
        $regex = '/(?:[a-z0-9]+\:)?\/\/'.$this->pregQuote($this->currentUrlHost()).'\//ui';

        return preg_replace($regex, '/', $css); // Absolute relative paths.
    }
931483
protected function maybeFilterCssUrls($css)
    {
        if (!($css = (string) $css)) {
            return $css; // Nothing to do.
        }
        if (!$this->hook_api->hasFilter('css_url()')) {
            return $css; // No reason to do this.
        }
        $import_without_url_regex = '/(?P<import>@(?:\-(?:'.$this->regex_vendor_css_prefixes.')\-)?import\s*)(?P<open_encap>["\'])(?P<url>.+?)(?P<close_encap>\\2)/ui';
        $any_url_regex            = '/(?P<url_>url\s*)(?P<open_bracket>\(\s*)(?P<open_encap>["\']?)(?P<url>.+?)(?P<close_encap>\\3)(?P<close_bracket>\s*\))/ui';

        $css = preg_replace_callback($import_without_url_regex, [$this, 'filterCssUrlImportCb'], $css);
        $css = preg_replace_callback($any_url_regex, [$this, 'filterCssUrlCb'], $css);

        return $css;
    }
680961
public function export($include_headers = true)
    {
        $res = '';
        if ($include_headers) {
            $res .= $this->export_headers();
            $res .= "\n\n";
        }
        $res .= $this->export_entries();

        return $res;
    }
296991
function compileSass() {
  var stream = gulp.src(src.scss)
    .pipe(plugins.sourcemaps.init())
    .pipe(plugins.sass().on('error', plugins.sass.logError))
    .pipe(plugins.autoprefixer({ browsers: ['last 2 versions', 'ie >= 9'] }))
    .pipe(plugins.sourcemaps.write())
    .pipe(gulp.dest(compiled.css))
    .pipe(reload({ stream: true }));
  return stream;
}
900648
public function compileFile($in, $out = null)
    {
        if (! is_readable($in)) {
            throw new ServerException('load error: failed to find ' . $in);
        }

        $pi = pathinfo($in);

        $this->scss->addImportPath($pi['dirname'] . '/');

        $compiled = $this->scss->compile(file_get_contents($in), $in);

        if ($out !== null) {
            return file_put_contents($out, $compiled);
        }

        return $compiled;
    }
1037371
public function css($css) {
        $css = trim($css);
        if (substr($css, -1) !== ';') {
            $css = $css . ';';
        }
        return $this->att(['style' => $css]);
    }
209459
static function scssOverrides( $scss ) {

		$styles = Container::get( 'Styles' );
		$v2_compatible = $styles->isCurrentThemeCompatible( 2 );

		if ( ! $v2_compatible ) {
			$scss .= "/* Theme Options */\n";
		}

		// --------------------------------------------------------------------
		// Global Options

		$options = get_option( 'pressbooks_theme_options_global' );

		// Should we display chapter numbers? True (default) or false.
		if ( ! $options['chapter_numbers'] ) {
			if ( $v2_compatible ) {
				$styles->getSass()->setVariables(
					[
						'chapter-number-display' => 'none',
						'part-number-display' => 'none',
						'toc-left-left-gutter' => '0',
						'toc-chapter-number-display' => 'none',
						'toc-left-chapter-number-display' => 'none',
						'toc-center-chapter-number-display' => 'none',
						'toc-part-number-display' => 'none',
						'toc-left-part-number-display' => 'none',
						'toc-center-part-number-display' => 'none',
					]
				);
			} else {
				$scss .= "div.part-title-wrap > .part-number, div.chapter-title-wrap > .chapter-number, #toc .part a::before, #toc .chapter a::before { display: none !important; } \n";  // TODO: NO
			}
		}

		// Textbox colours.

		if ( $v2_compatible ) {
			foreach ( [
				'edu_textbox_examples_header_color' => 'examples-header-color',
				'edu_textbox_examples_header_background' => 'examples-header-background',
				'edu_textbox_examples_background' => 'examples-background',
				'edu_textbox_exercises_header_color' => 'exercises-header-color',
				'edu_textbox_exercises_header_background' => 'exercises-header-background',
				'edu_textbox_exercises_background' => 'exercises-background',
				'edu_textbox_objectives_header_color' => 'learning-objectives-header-color',
				'edu_textbox_objectives_header_background' => 'learning-objectives-header-background',
				'edu_textbox_objectives_background' => 'learning-objectives-background',
				'edu_textbox_takeaways_header_color' => 'key-takeaways-header-color',
				'edu_textbox_takeaways_header_background' => 'key-takeaways-header-background',
				'edu_textbox_takeaways_background' => 'key-takeaways-background',
			] as $option => $variable ) {
				if ( isset( $options[ $option ] ) ) {
					$styles->getSass()->setVariables(
						[
							"$variable" => $options[ $option ],
						]
					);
				}
			}
		}

		// --------------------------------------------------------------------
		// PDF Options

		$options = get_option( 'pressbooks_theme_options_pdf' );

		// Change body font size
		if ( $v2_compatible && isset( $options['pdf_body_font_size'] ) ) {
			$fontsize = $options['pdf_body_font_size'] . 'pt';
			$styles->getSass()->setVariables(
				[
					'body-font-size' => "(epub: medium, prince: $fontsize, web: 14pt)",
				]
			);
		}

		// Change body line height
		if ( $v2_compatible && isset( $options['pdf_body_line_height'] ) ) {
			$lineheight = $options['pdf_body_line_height'] . 'em';
				$styles->getSass()->setVariables(
					[
						'body-line-height' => "(epub: 1.4em, prince: $lineheight, web: 1.8em)",
					]
				);
		}

		// Page dimensions
		$width = $options['pdf_page_width'];
		$height = $options['pdf_page_height'];

		if ( $v2_compatible ) {
			$styles->getSass()->setVariables(
				[
					'page-width' => $width,
					'page-height' => $height,
				]
			);
		} else {
			$scss .= "@page { size: $width $height; } \n";
		}

		// Margins
		if ( $v2_compatible ) {
			$styles->getSass()->setVariables(
				[
					'page-margin-top' => ( isset( $options['pdf_page_margin_top'] ) ) ? $options['pdf_page_margin_top'] : '2cm',
					'page-margin-inside' => ( isset( $options['pdf_page_margin_inside'] ) ) ? $options['pdf_page_margin_inside'] : '2cm',
					'page-margin-bottom' => ( isset( $options['pdf_page_margin_bottom'] ) ) ? $options['pdf_page_margin_bottom'] : '2cm',
					'page-margin-outside' => ( isset( $options['pdf_page_margin_outside'] ) ) ? $options['pdf_page_margin_outside'] : '2cm',
				]
			);
		}

		// Should we display crop marks? True or false (default).
		if ( 1 === absint( $options['pdf_crop_marks'] ) ) {
			if ( $v2_compatible ) {
				$styles->getSass()->setVariables(
					[
						'page-cropmarks' => 'crop',
					]
				);
			} else {
				$scss .= "@page { marks: crop } \n";
			}
		}

		// Hyphens?
		if ( 1 === absint( $options['pdf_hyphens'] ) ) {
			if ( $v2_compatible ) {
				$styles->getSass()->setVariables(
					[
						'para-hyphens' => 'auto',
					]
				);
			} else {
				$scss .= "p { hyphens: auto; } \n";
			}
		} else {
			if ( $v2_compatible ) {
				$styles->getSass()->setVariables(
					[
						'para-hyphens' => 'manual',
					]
				);
			} else {
				$scss .= "p { hyphens: manual; } \n";
			}
		}

		// Indent paragraphs?
		$paragraph_separation = $options['pdf_paragraph_separation'] ?? 'indent';
		if ( 'skiplines' === $paragraph_separation ) {
			if ( $v2_compatible ) {
				$styles->getSass()->setVariables(
					[
						'para-margin-top' => '1em',
						'para-indent' => '0',
					]
				);
			} else {
				$scss .= "p + p { text-indent: 0em; margin-top: 1em; } \n";
			}
		} elseif ( 'indent' === $paragraph_separation ) {
			if ( $v2_compatible ) {
				$styles->getSass()->setVariables(
					[
						'para-margin-top' => '0',
						'para-indent' => '1em',
					]
				);
			} else {
				$scss .= "p + p { text-indent: 1em; margin-top: 0em; } \n";
			}
		}

		// Include blank pages?
		if ( isset( $options['pdf_sectionopenings'] ) ) {
			if ( 'openright' === $options['pdf_sectionopenings'] ) {
				if ( $v2_compatible ) {
					$styles->getSass()->setVariables(
						[
							'recto-verso-standard-opening' => 'right',
							'recto-verso-first-section-opening' => 'right',
							'recto-verso-section-opening' => 'right',
						]
					);
				} else {
					$scss .= "#title-page, #toc, div.part, div.front-matter, div.front-matter.introduction, div.front-matter + div.front-matter, div.chapter, div.chapter + div.chapter, div.back-matter, div.back-matter + div.back-matter, #half-title-page h1.title:first-of-type  { page-break-before: right; } \n";
					$scss .= "#copyright-page { page-break-before: left; }\n";
				}
			} elseif ( 'remove' === $options['pdf_sectionopenings'] ) {
				if ( $v2_compatible ) {
					$styles->getSass()->setVariables(
						[
							'recto-verso-standard-opening' => 'auto',
							'recto-verso-first-section-opening' => 'auto',
							'recto-verso-section-opening' => 'auto',
							'recto-verso-copyright-page-opening' => 'auto',
						]
					);
				} else {
					$scss .= "#title-page, #copyright-page, #toc, div.part, div.front-matter, div.back-matter, div.chapter, #half-title-page h1.title:first-of-type  { page-break-before: auto; } \n";
				}
			}
		}

		// Should we display the TOC? True (default) or false.
		if ( ! $options['pdf_toc'] ) {
			if ( $v2_compatible ) {
				$styles->getSass()->setVariables(
					[
						'toc-display' => 'none',
					]
				);
			} else {
				$scss .= "#toc { display: none; } \n";
			}
		}

		// Widows
		if ( isset( $options['widows'] ) ) {
			if ( $v2_compatible ) {
				$styles->getSass()->setVariables(
					[
						'widows' => $options['widows'],
					]
				);
			} else {
				$scss .= "p { widows: {$options['widows']}; }\n";
			}
		} else {
			if ( ! $v2_compatible ) {
				$scss .= 'p { widows: 2; }' . "\n";
			}
		}

		// Orphans
		if ( isset( $options['orphans'] ) ) {
			if ( $v2_compatible ) {
				$styles->getSass()->setVariables(
					[
						'orphans' => $options['orphans'],
					]
				);
			} else {
				$scss .= "p { orphans: {$options['orphans']}; }\n";
			}
		} else {
			if ( ! $v2_compatible ) {
				$scss .= 'p { orphans: 1; }' . "\n";
			}
		}

		// Running Content
		if ( $v2_compatible ) {
			$front_matter_running_content_left = ( isset( $options['running_content_front_matter_left'] ) ) ? self::replaceRunningContentTags( $options['running_content_front_matter_left'] ) : 'string(book-title)';
			$front_matter_running_content_right = ( isset( $options['running_content_front_matter_right'] ) ) ? self::replaceRunningContentTags( $options['running_content_front_matter_right'] ) : 'string(section-title)';
			$introduction_running_content_left = ( isset( $options['running_content_introduction_left'] ) ) ? self::replaceRunningContentTags( $options['running_content_introduction_left'] ) : 'string(book-title)';
			$introduction_running_content_right = ( isset( $options['running_content_introduction_right'] ) ) ? self::replaceRunningContentTags( $options['running_content_introduction_right'] ) : 'string(section-title)';
			$part_running_content_left = ( isset( $options['running_content_part_left'] ) ) ? self::replaceRunningContentTags( $options['running_content_part_left'] ) : 'string(book-title)';
			$part_running_content_right = ( isset( $options['running_content_part_right'] ) ) ? self::replaceRunningContentTags( $options['running_content_part_right'] ) : 'string(part-title)';
			$chapter_running_content_left = ( isset( $options['running_content_chapter_left'] ) ) ? self::replaceRunningContentTags( $options['running_content_chapter_left'] ) : 'string(book-title)';
			$chapter_running_content_right = ( isset( $options['running_content_chapter_right'] ) ) ? self::replaceRunningContentTags( $options['running_content_chapter_right'] ) : 'string(section-title)';
			$back_matter_running_content_left = ( isset( $options['running_content_back_matter_left'] ) ) ? self::replaceRunningContentTags( $options['running_content_back_matter_left'] ) : 'string(book-title)';
			$back_matter_running_content_right = ( isset( $options['running_content_back_matter_right'] ) ) ? self::replaceRunningContentTags( $options['running_content_back_matter_right'] ) : 'string(section-title)';
			$styles->getSass()->setVariables(
				[
					'front-matter-running-content-left' => $front_matter_running_content_left,
					'front-matter-running-content-right' => $front_matter_running_content_right,
					'introduction-running-content-left' => $introduction_running_content_left,
					'introduction-running-content-right' => $introduction_running_content_right,
					'part-running-content-left' => $part_running_content_left,
					'part-running-content-right' => $part_running_content_right,
					'chapter-running-content-left' => $chapter_running_content_left,
					'chapter-running-content-right' => $chapter_running_content_right,
					'back-matter-running-content-left' => $back_matter_running_content_left,
					'back-matter-running-content-right' => $back_matter_running_content_right,
				]
			);
		}

		// a11y Font Size
		if ( ! empty( $options['pdf_fontsize'] ) ) {
			if ( ! $v2_compatible ) {
				$scss .= 'body { font-size: 1.3em; line-height: 1.3; }' . "\n";
			}
		}

		return $scss;
	}
1020525
public function cssBlock($css, array $options = [])
    {
        $options = optionsParser($options, ['block' => true]);

        $out = $this->formatTemplate('style', [
            'attrs' => $this->templater()->formatAttributes($options->toArray(), ['block']),
            'content' => $css,
        ]);

        if (!$options->get('block')) {
            return $out;
        }

        if ($options->contains('block', true)) {
            $options->add('block', 'css');
        }

        $this->_View->append($options->get('block'), $out);
    }
762820
public static function compress($css)
    {
        $css = (string) $css;
        try {
            $css_minifier = new static($css);
            $minified_css = $css_minifier->min();
            return $minified_css;
        } catch (\Exception $exception) {
            return $css;
        }
    }
9130
protected function loadCss($css, $options=array())
    {
        $location = (isset($options['location'])) ? $options['location']:'internal';

        //after:file, before:file, first, last
        $position = (isset($options['position'])) ? $options['position']:'last';

        if(!in_array($css,$this->data['css'][$location])){
            if($position=='first' || $position=='last'){
                $key = $position;
                $file='';
            }else{
                list($key,$file) =  explode(':',$position);
            }

            switch($key){
                case 'first':
                    array_unshift($this->data['css'][$location],$css);
                break;

                case 'last':
                    $this->data['css'][$location][]=$css;
                break;

                case 'before':
                case 'after':
                    $varkey = array_keys($this->data['css'][$location],$file);
                    if($varkey){
                        $nextkey = ($key=='after') ? $varkey[0]+1 : $varkey[0];
                        array_splice($this->data['css'][$location],$nextkey,0,$css);
                    }else{
                        $this->data['css'][$location][]=$css;
                    }
                break;
            }
        }
    }
556677
protected function minify($css)
	{
		$css = trim($css, " \n\t;");
		$css = preg_replace('(\\s*([,:;])\\s*)', '$1', $css);
		$css = preg_replace_callback(
			'((?<=[\\s:])#[0-9a-f]{3,6})i',
			function ($m)
			{
				return strtolower($m[0]);
			},
			$css
		);
		$css = preg_replace('((?<=[\\s:])#([0-9a-f])\\1([0-9a-f])\\2([0-9a-f])\\3)', '#$1$2$3', $css);
		$css = preg_replace('((?<=[\\s:])#f00\\b)', 'red', $css);
		$css = preg_replace('((?<=[\\s:])0px\\b)', '0', $css);

		return $css;
	}
503219
protected function handleCssImports($css)
    {
        if ($this->options['bubbleCssImports']) {
            // bubble CSS imports
            preg_match_all('/@import.*?;/', $css, $imports);
            $css = implode('', $imports[0]) . preg_replace('/@import.*?;/', '', $css);

            return $css;
        }

        if ('' === $this->options['importWarning']) {
            return $css;
        }

        // remove comments so we don't mistake { in a comment as a block
        $noCommentCss = preg_replace('@/\\*[\\s\\S]*?\\*/@', '', $css);
        $lastImportPos = strrpos($noCommentCss, '@import');
        $firstBlockPos = strpos($noCommentCss, '{');
        if (false !== $lastImportPos
            && false !== $firstBlockPos
            && $firstBlockPos < $lastImportPos
        ) {
            // { appears before @import : prepend warning
            $css = $this->options['importWarning'] . $css;
        }

        return $css;
    }
8569
protected function maybeCompressCssCode($css)
    {
        if (($benchmark = !empty($this->options['benchmark']) && $this->options['benchmark'] === 'details')) {
            $time = microtime(true);
        }
        $css = (string) $css; // Force string value.

        if (isset($this->options['compress_css_code'])) {
            if (!$this->options['compress_css_code']) {
                $disabled = true; // Disabled flag.
            }
        }
        if (!$css || !empty($disabled)) {
            goto finale; // Nothing to do.
        }
        if (strlen($css) > 1000000) {
            // Exclude VERY large files. Too time-consuming.
            // Should really be compressed ahead-of-time anyway.
            goto finale; // Don't compress HUGE files.
        }
        try { // Catch CSS compression-related exceptions.
            if (!($compressed_css = \WebSharks\CssMinifier\Core::compress($css))) {
                // `E_USER_NOTICE` to avoid a show-stopping problem.
                trigger_error('CSS compression failure.', E_USER_NOTICE);
            } else {
                $css = $this->stripUtf8Bom($compressed_css);
            } // Use compressed CSS file.
        } catch (\Exception $exception) {
            trigger_error($exception->getMessage(), E_USER_NOTICE);
        }
        finale: // Target point; finale/return value.

        if ($css) {
            $css = trim($css);
        }
        if ($benchmark && !empty($time) && $css && empty($disabled)) {
            $this->benchmark->addTime(
                __FUNCTION__,
                $time, // Caller, start time, task performed.
                sprintf('compressing CSS w/ checksum: `%1$s`', md5($css))
            );
        }
        return $css;
    }
847085
public function editor_scss_to_css() {
        $css = '';

        if (!empty($this->editor_scss)) {
            $compiler = new core_scss();

            foreach ($this->editor_scss as $filename) {
                $compiler->set_file("{$this->dir}/scss/{$filename}.scss");

                try {
                    $css .= $compiler->to_css();
                } catch (\Exception $e) {
                    debugging('Error while compiling editor SCSS: ' . $e->getMessage(), DEBUG_DEVELOPER);
                }
            }
        }

        return $css;
    }