🏡 index : github.com/captn3m0/codechef.git

author Nemo <me@captnemo.in> 2018-06-15 9:02:21.0 +05:30:00
committer Nemo <me@captnemo.in> 2018-06-15 9:02:21.0 +05:30:00
commit
3173cfde7448e7ba97a271b9043b3df3e2dadcfd [patch]
tree
897a1228ffb739c1f87327cccbabd457820ce371
parent
acf3d0a76630a416ce764983158977aef2ea642d
download
3173cfde7448e7ba97a271b9043b3df3e2dadcfd.tar.gz

Adds support for a EPUB version



Diff

 .gitignore             |   2 ++
 Pandoc.php             | 285 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 RoboFile.php           |  45 +++++++++++++++++++++++++++++++++++++++------
 cover.png              |   0 
 metadata.xml           |   3 +++
 template.tex           | 284 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 _problems/school/H1.md |  15 ++++++++-------
 7 files changed, 619 insertions(+), 15 deletions(-)

diff --git a/.gitignore b/.gitignore
index e018de7..721365f 100644
--- a/.gitignore
+++ a/.gitignore
@@ -1,5 +1,7 @@
vendor/
.jekyll-metadata
_site/
*.zip
book.md
*.epub
*.html
diff --git a/Pandoc.php b/Pandoc.php
new file mode 100644
index 0000000..79a2ced 100644
--- /dev/null
+++ a/Pandoc.php
@@ -1,0 +1,285 @@
<?php
/**
 * Pandoc PHP
 *
 * Copyright (c) Ryan Kadwell <ryan@riaka.ca>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

/**
 * Naive wrapper for haskell's pandoc utility
 *
 * @author Ryan Kadwell <ryan@riaka.ca>
 */
class Pandoc
{
    /**
     * Where is the executable located
     * @var string
     */
    private $executable;
    /**
     * Where to take the content for pandoc from
     * @var string
     */
    private $tmpFile;
    /**
     * Directory to store temporary files
     * @var string
     */
    private $tmpDir;
    /**
     * List of valid input types
     * @var array
     */
    private $inputFormats = array(
        "native",
        "json",
        "markdown",
        "markdown_strict",
        "markdown_phpextra",
        "markdown_github",
        "markdown_mmd",
        "rst",
        "mediawiki",
        "docbook",
        "docx",
        "textile",
        "html",
        "latex"
    );
    /**
     * List of valid output types
     * @var array
     */
    private $outputFormats = array(
        "native",
        "json",
        "docx",
        "odt",
        "epub",
        "epub3",
        "fb2",
        "html",
        "html5",
        "s5",
        "slidy",
        "slideous",
        "dzslides",
        "docbook",
        "opendocument",
        "latex",
        "beamer",
        "context",
        "texinfo",
        "man",
        "markdown",
        "markdown_strict",
        "markdown_phpextra",
        "markdown_github",
        "markdown_mmd",
        "plain",
        "rst",
        "mediawiki",
        "textile",
        "rtf",
        "org",
        "asciidoc"
    );
    /**
     * Setup path to the pandoc binary
     *
     * @param string $executable Path to the pandoc executable
     * @param string $tmpDir     Path to where we want to store temporary files
     */
    public function __construct($executable = null, $tmpDir = null)
    {
        if ( ! $tmpDir) {
            $tmpDir = sys_get_temp_dir();
        }
        if ( ! file_exists($tmpDir)) {
            throw new Exception(
                sprintf('The directory %s does not exist!', $tmpDir)
            );
        }
        if ( ! is_writable($tmpDir)) {
            throw new Exception(
                sprintf('Unable to write to the directory %s!', $tmpDir)
            );
        }
        $this->tmpDir = $tmpDir;
        $this->tmpFile = sprintf("%s/%s", $this->tmpDir, uniqid("pandoc"));
        // Since we can not validate that the command that they give us is
        // *really* pandoc we will just check that its something.
        // If the provide no path to pandoc we will try to find it on our own
        if ( ! $executable) {
            exec('which pandoc', $output, $returnVar);
            if ($returnVar === 0) {
                $this->executable = $output[0];
            } else {
                throw new Exception('Unable to locate pandoc');
            }
        } else {
            $this->executable = $executable;
        }
        if ( ! is_executable($this->executable)) {
            throw new Exception('Pandoc executable is not executable');
        }
    }
    /**
     * Run the conversion from one type to another
     *
     * @param string $from The type we are converting from
     * @param string $to   The type we want to convert the document to
     *
     * @return string
     */
    public function convert($content, $from, $to)
    {
        if ( ! in_array($from, $this->inputFormats)) {
            throw new Exception(
                sprintf('%s is not a valid input format for pandoc', $from)
            );
        }
        if ( ! in_array($to, $this->outputFormats)) {
            throw new Exception(
                sprintf('%s is not a valid output format for pandoc', $to)
            );
        }
        file_put_contents($this->tmpFile, $content);
        $command = sprintf(
            '%s --from=%s --to=%s %s',
            $this->executable,
            $from,
            $to,
            $this->tmpFile
        );
        exec(escapeshellcmd($command), $output);
        return implode("\n", $output);
    }

    /**
     * Run the pandoc command with specific options.
     *
     * Provides more control over what happens. You simply pass an array of
     * key value pairs of the command options omitting the -- from the start.
     * If you want to pass a command that takes no argument you set its value
     * to null.
     *
     * @param string $content The content to run the command on
     * @param array  $options The options to use
     *
     * @return string The returned content
     */
    public function runWith($content, $options)
    {
        $commandOptions = array();
        $extFilesFormat = array(
            'docx',
            'odt',
            'epub',
            'fb2',
            'pdf'
        );
        $extFilesHtmlSlide = array(
            's5',
            'slidy',
            'dzslides',
            'slideous'
        );
        foreach ($options as $key => $value) {
            if ($key == 'to' && in_array($value, $extFilesFormat)) {
                $commandOptions[] = '-s -o '.$this->tmpFile.'.'.$value;
                $format = $value;
                continue;
            } else if ($key == 'to' && in_array($value, $extFilesHtmlSlide)) {
                $commandOptions[] = '-s -t '.$value.'+smart -o '.$this->tmpFile.'.html';
                $format = 'html';
                continue;
            } else if ($key == 'to' && $value == 'epub3') {
                $commandOptions[] = '-t epub+smart -o '.$this->tmpFile.'.epub';
                $format = 'epub';
                continue;
            } else if ($key == 'to' && $value == 'beamer') {
                $commandOptions[] = '-s -t beamer+smart -o '.$this->tmpFile.'.pdf';
                $format = 'pdf';
                continue;
            } else if ($key == 'to' && $value == 'latex') {
                $commandOptions[] = '-s -o '.$this->tmpFile.'.tex';
                $format = 'tex';
                continue;
            } else if ($key == 'to' && $value == 'rst') {
                $commandOptions[] = '-s -t rst --toc -o '.$this->tmpFile.'.text';
                $format = 'text';
                continue;
            } else if ($key == 'to' && $value == 'rtf') {
                $commandOptions[] = '-s -o '.$this->tmpFile.'.'.$value;
                $format = $value;
                continue;
            } else if ($key == 'to' && $value == 'docbook') {
                $commandOptions[] = '-s -t docbook+smart -o '.$this->tmpFile.'.db';
                $format = 'db';
                continue;
            } else if ($key == 'to' && $value == 'context') {
                $commandOptions[] = '-s -t context+smart -o '.$this->tmpFile.'.tex';
                $format = 'tex';
                continue;
            } else if ($key == 'to' && $value == 'asciidoc') {
                $commandOptions[] = '-s -t asciidoc+smart -o '.$this->tmpFile.'.txt';
                $format = 'txt';
                continue;
            }
            if (null === $value) {
                $commandOptions[] = "--$key";
                continue;
            }
            $commandOptions[] = "--$key=$value";
        }
        file_put_contents($this->tmpFile, $content);
        chmod($this->tmpFile, 0777);
        $command = sprintf(
            "%s %s %s",
            $this->executable,
            implode(' ', $commandOptions),
            $this->tmpFile
        );
        exec(escapeshellcmd($command), $output, $returnval);
        if($returnval === 0)
        {
            if (isset($format)) {
                return file_get_contents($this->tmpFile.'.'.$format);
            } else {
                return implode("\n", $output);
            }
        }else
        {
            throw new Exception(
                sprintf('Pandoc could not convert successfully, error code: %s. Tried to run the following command: %s', $returnval, $command)
            );
        }
    }

    /**
     * Remove the temporary files that were created
     */
    public function __destruct()
    {
        if (file_exists($this->tmpFile)) {
            @unlink($this->tmpFile);
        }
        foreach (glob($this->tmpFile.'*') as $filename) {
            @unlink($filename);
        }
    }

    /**
     * Return that path where we are storing temporary files
     * @return string
     */
    public function getTmpDir()
    {
        return $this->tmpDir;
    }
}
diff --git a/RoboFile.php b/RoboFile.php
index 161d81e..caa2507 100644
--- a/RoboFile.php
+++ a/RoboFile.php
@@ -5,6 +5,8 @@
use KzykHys\FrontMatter\FrontMatter;
use League\HTMLToMarkdown\HtmlConverter;

require ('Pandoc.php');

class RoboFile extends \Robo\Tasks
{
    const ALL = 'all';
@@ -142,26 +144,53 @@
        return false;
    }

    public function generateBook() {
        $bookContent = "# CodeChef Problem\n";
    private function _generateSingleHtmlFile() {
        $bookContent = "<html><head><title>CodeChef Problem</title><base href='https://www.codechef.com'></head>\n";
        $categories = $this->setCategories(self::ALL);

        foreach ($categories as $category) {
            $bookContent .= "## Category: $category\n";
            $bookContent .= "<h1>Category: $category</h1>";

            $problems = json_decode(file_get_contents("_data/$category.json"));
            foreach ($problems as $problem) {
                $file = "_problems/$category/$problem.md";
                $file = "_problems/$category/$problem.json";
                if (file_exists($file)) {
                    $document = FrontMatter::parse(file_get_contents($file));
                    $content = $document->getContent();
                    $document = json_decode(file_get_contents($file), true);
                    $content = $document['body'];

                    $bookContent .= $content . "\n\\newpage";
                    $bookContent .= "<h2>" . $document['problem_code'] . "</h2>";
                    $content = strip_tags($content, '<p><a><b><i><br><h2><h3><h1><h4><pre>');

                    $bookContent .= $content;
                }
            }
        }

        return $bookContent;
    }

        file_put_contents("book.md", $bookContent);
    private function _runPandocEPUB($html) {
        $pandoc = new Pandoc();
        $options = [
            "from"  => "html",
            "to"    => "epub",
            // "css"   => "/assets/css/documents.css",
            "toc"   => null,
            "toc-depth" => 2,
            "epub-metadata" => "metadata.xml",
            "epub-cover-image" => "cover.png",
            "variable" => 'title:"CodeChef - The Problems"'
        ];

        return $pandoc->runWith($html, $options);
    }

    public function generateBook() {
        $html = $this->_generateSingleHtmlFile();
        $this->say("HTML generated");

        $epub = $this->_runPandocEPUB($html);
        file_put_contents('codechef.epub', $epub);
    }

    public function generateCollection($category = self::ALL) {
diff --git a/cover.png b/cover.png
new file mode 100644
index 0000000000000000000000000000000000000000..3d0f3cd0f553a63b2936b0ddb06710a746c29327 100644
Binary files /dev/null and a/cover.png differdiff --git a/metadata.xml b/metadata.xml
new file mode 100644
index 0000000..28506d4 100644
--- /dev/null
+++ a/metadata.xml
@@ -1,0 +1,3 @@
<dc:language>en-US</dc:language>
<dc:title id="epub-title-1">CodeChef: The Problems</dc:title>
<dc:date>2018-06-15</dc:date>
diff --git a/template.tex b/template.tex
new file mode 100644
index 0000000..e5d9310 100644
--- /dev/null
+++ a/template.tex
@@ -1,0 +1,284 @@
\documentclass[$if(fontsize)$$fontsize$,$endif$$if(lang)$$babel-lang$,$endif$$if(papersize)$$papersize$,$endif$$for(classoption)$$classoption$$sep$,$endfor$]{$documentclass$}

% Removes the "Chapter.." from chapter titles.
% \usepackage{titlesec}
% \titleformat{\chapter}[display]
%   {\normalfont\bfseries}{}{0pt}{\Huge}

$if(fontfamily)$
  \usepackage[$fontfamilyoptions$]{$fontfamily$}
$else$
  \usepackage{lmodern}
$endif$

$if(linestretch)$
  \usepackage{setspace}
  \setstretch{$linestretch$}
$endif$

\usepackage{amssymb,amsmath}
\usepackage{ifxetex,ifluatex}
\usepackage{fixltx2e} % provides \textsubscript

\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
  \usepackage[$if(fontenc)$$fontenc$$else$T1$endif$]{fontenc}
  \usepackage[utf8]{inputenc}
  $if(euro)$
    \usepackage{eurosym}
  $endif$
\else % if luatex or xelatex
  \ifxetex
    \usepackage{mathspec}
  \else
    \usepackage{fontspec}
  \fi
  \defaultfontfeatures{Ligatures=TeX,Scale=MatchLowercase}
  \newcommand{\euro}{}

  $if(mainfont)$
    \setmainfont[$mainfontoptions$]{$mainfont$}
  $endif$
  $if(sansfont)$
    \setsansfont[$sansfontoptions$]{$sansfont$}
  $endif$
  $if(monofont)$
    \setmonofont[Mapping=tex-ansi$if(monofontoptions)$,$monofontoptions$$endif$]{$monofont$}
  $endif$
  $if(mathfont)$
    \setmathfont(Digits,Latin,Greek)[$mathfontoptions$]{$mathfont$}
  $endif$
  $if(CJKmainfont)$
    \usepackage{xeCJK}
    \setCJKmainfont[$CJKoptions$]{$CJKmainfont$}
  $endif$
\fi

% use upquote if available, for straight quotes in verbatim environments
\IfFileExists{upquote.sty}{\usepackage{upquote}}{}
% use microtype if available
\IfFileExists{microtype.sty}{%
\usepackage{microtype}
\UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts
}{}
$if(geometry)$
\usepackage[$for(geometry)$$geometry$$sep$,$endfor$]{geometry}
$endif$
\usepackage{hyperref}
\PassOptionsToPackage{usenames,dvipsnames}{color} % color is loaded by hyperref
\hypersetup{breaklinks=true,
            unicode=true,
            $if(title-meta)$
              pdftitle={$title-meta$},
            $endif$
            $if(author-meta)$
              pdfauthor={$author-meta$},
            $endif$
            $if(subtitle)$
              pdfsubject={$subtitle$},
            $endif$
            $if(keywords)$
              pdfkeywords={$keywords$},
            $endif$
            pagebackref,
            bookmarksopen,
            bookmarksnumbered,
            colorlinks=true,
            citecolor=$if(citecolor)$$citecolor$$else$black$endif$,
            urlcolor=$if(urlcolor)$$urlcolor$$else$black$endif$,
            linkcolor=$if(linkcolor)$$linkcolor$$else$black$endif$,
            pdfborder={0 0 0}
            $if(hidelinks)$,hidelinks$endif$}

\urlstyle{same}  % don't use monospace font for urls

$if(lang)$
  \ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
    \usepackage[shorthands=off,$for(babel-otherlangs)$$babel-otherlangs$$sep$,$endfor$,main=$babel-lang$]{babel}
    $babel-newcommands$
  \else
    \usepackage{polyglossia}
    \setmainlanguage[$polyglossia-lang.options$]{$polyglossia-lang.name$}
    $for(polyglossia-otherlangs)$
      \setotherlanguage[$polyglossia-otherlangs.options$]{$polyglossia-otherlangs.name$}
    $endfor$
  \fi
$endif$

$if(natbib)$
  \usepackage{natbib}
  \bibliographystyle{$if(biblio-style)$$biblio-style$$else$plainnat$endif$}
$endif$

$if(biblatex)$
  \usepackage{biblatex}
  $for(bibliography)$
    \addbibresource{$bibliography$}
  $endfor$
$endif$

$if(listings)$
  \usepackage{listings}
$endif$

$if(lhs)$
  \lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{}
$endif$

$if(highlighting-macros)$
  $highlighting-macros$
$endif$

$if(verbatim-in-note)$
  \usepackage{fancyvrb}
  \VerbatimFootnotes % allows verbatim text in footnotes
$endif$

$if(tables)$
  \usepackage{longtable,booktabs}
$endif$

$if(graphics)$
  \usepackage{graphicx,grffile}
  \makeatletter
  \def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth\else\Gin@nat@width\fi}
  \def\maxheight{\ifdim\Gin@nat@height>\textheight\textheight\else\Gin@nat@height\fi}
  \makeatother
  % Scale images if necessary, so that they will not overflow the page
  % margins by default, and it is still possible to overwrite the defaults
  % using explicit options in \includegraphics[width, height, ...]{}
  \setkeys{Gin}{width=\maxwidth,height=\maxheight,keepaspectratio}
$endif$

$if(links-as-notes)$
  % Make links footnotes instead of hotlinks:
  \renewcommand{\href}[2]{#2\footnote{\url{#1}}}
$endif$

$if(strikeout)$
  \usepackage[normalem]{ulem}
  % avoid problems with \sout in headers with hyperref:
  \pdfstringdefDisableCommands{\renewcommand{\sout}{}}
$endif$

$if(indent)$
$else$
  \setlength{\parindent}{0pt}
  \setlength{\parskip}{6pt plus 2pt minus 1pt}
$endif$

\setlength{\emergencystretch}{3em}  % prevent overfull lines
\providecommand{\tightlist}{%
  \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}

$if(numbersections)$
  \setcounter{secnumdepth}{5}
$else$
  \setcounter{secnumdepth}{0}
$endif$

$if(dir)$
  \ifxetex
    % load bidi as late as possible as it modifies e.g. graphicx
    $if(latex-dir-rtl)$
    \usepackage[RTLdocument]{bidi}
    $else$
    \usepackage{bidi}
    $endif$
  \fi
  \ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
    \TeXXeTstate=1
    \newcommand{\RL}[1]{\beginR #1\endR}
    \newcommand{\LR}[1]{\beginL #1\endL}
    \newenvironment{RTL}{\beginR}{\endR}
    \newenvironment{LTR}{\beginL}{\endL}
  \fi
$endif$

$if(title)$
  \title{$title$$if(subtitle)$\\\vspace{0.5em}{\large $subtitle$}$endif$}
$endif$

$if(author)$
  \author{$for(author)$$author$$sep$ \and $endfor$}
$endif$

\date{$date$}

$for(header-includes)$
  $header-includes$
$endfor$

$if(subparagraph)$
$else$
  % Redefines (sub)paragraphs to behave more like sections
  \ifx\paragraph\undefined\else
    \let\oldparagraph\paragraph
    \renewcommand{\paragraph}[1]{\oldparagraph{#1}\mbox{}}
  \fi

  \ifx\subparagraph\undefined\else
    \let\oldsubparagraph\subparagraph
    \renewcommand{\subparagraph}[1]{\oldsubparagraph{#1}\mbox{}}
  \fi
$endif$

\begin{document}
  $if(title)$
  \maketitle
  $endif$

  $if(abstract)$
    \begin{abstract}
      $abstract$
    \end{abstract}
  $endif$

  $for(include-before)$
    $include-before$
  $endfor$

  $if(toc)$
  {
    \hypersetup{linkcolor=$if(toccolor)$$toccolor$$else$black$endif$}
    \setcounter{tocdepth}{$toc-depth$}

    % Add an entry for Contents themselves.
    \addtocontents{toc}{\protect{\pdfbookmark[0]{\contentsname}{toc}}}

    \tableofcontents
  }
  $endif$

  $if(lot)$
    \listoftables
  $endif$

  $if(lof)$
    \listoffigures
  $endif$

  $body$

  $if(natbib)$
    $if(bibliography)$
      $if(biblio-title)$
        $if(book-class)$
          \renewcommand\bibname{$biblio-title$}
        $else$
          \renewcommand\refname{$biblio-title$}
        $endif$
      $endif$

      \bibliography{$for(bibliography)$$bibliography$$sep$,$endfor$}
    $endif$
  $endif$

  $if(biblatex)$
    \printbibliography$if(biblio-title)$[title=$biblio-title$]$endif$
  $endif$

  $for(include-after)$
    $include-after$
  $endfor$

\end{document}
diff --git a/_problems/school/H1.md b/_problems/school/H1.md
index 753b7d7..ad47131 100644
--- a/_problems/school/H1.md
+++ a/_problems/school/H1.md
@@ -64,6 +64,7 @@
is_direct_submittable: false
layout: problem
---


All submissions for this problem are available.Johnny has some difficulty memorizing the small prime numbers. So, his computer science teacher has asked him to play with the following puzzle game frequently.

The puzzle is a 3x3 board consisting of numbers from 1 to 9. The objective of the puzzle is to swap the tiles until the following final state is reached:
@@ -92,13 +93,13 @@
<b>Input:</b>
2

7 3 2 
4 1 5 
6 8 9 
7 3 2
4 1 5
6 8 9

9 8 5 
2 4 1 
3 7 6  
9 8 5
2 4 1
3 7 6

<b>Output:</b>
6
@@ -106,5 +107,5 @@
</pre>### Output details

The possible 6 steps in the first test case are described in the following figure:


![](https://campus.codechef.com/images/problems/h1.png)