Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only allow page break on a blank line #352

Open
GitMew opened this issue Jan 28, 2023 · 2 comments
Open

Only allow page break on a blank line #352

GitMew opened this issue Jan 28, 2023 · 2 comments

Comments

@GitMew
Copy link

GitMew commented Jan 28, 2023

minted handles long code files given to \inputminted by adding a page break when the page is full. However, for languages like Scheme, it can be hard for the reader to know the relative indentation of the next statement w.r.t. the previous line (take this file as example), and hence a page break makes the code hard to follow.

Is there a way of only inserting a page break on blank lines -- or, by lack of them, at least prefer breaking on blank lines? There is only one post about this on the internet as far as I know, and all it does for me is add the word BLANK to blank lines in the code listing, without causing breaks. I tried changing that to \newpage, but to no avail.

My preamble is fairly plain:

\usepackage{minted}
\usemintedstyle{autumn}

\usepackage{xhfill}
\usepackage{titlesec}
\usepackage{fancyhdr}

\setminted{breaklines,linenos}
\renewcommand{\theFancyVerbLine}{\textcolor[rgb]{0.85,0.85,0.85}{\footnotesize\arabic{FancyVerbLine}}}
@muzimuzhi
Copy link
Contributor

muzimuzhi commented Jan 28, 2023

[...], and all it does for me is add the word BLANK to blank lines in the code listing, without causing breaks. I tried changing that to \newpage, but to no avail.

Could you provide a reproducible example?

Update: Ah, I guess that's because a longly BLANK is not considered an error in Scheme but was an error in JSON, which was the case in mentioned tex-sx answer. A more general solution is required.

@GitMew
Copy link
Author

GitMew commented Jan 29, 2023

Could you provide a reproducible example?

@muzimuzhi Here's the full example using the code cited above. It reproduces the behaviour with pdfLaTeX 2022. Beware: embedding the code within TeX using \begin{minted} instead of \inputminted causes the inserted occurrences of BLANK to get a red colouring instead of being black. That shows that proposed solutions may behave differently depending on how the code is included.

\documentclass{article}

\usepackage[margin=0.75in]{geometry}
\usepackage[utf8]{inputenc}

% Section titles
\usepackage{xhfill}
\usepackage{titlesec}
\titleformat{name=\section,numberless}
    {\filcenter\Large\bfseries}
    {}
    {.5em}
    {\hrule}
    [\hrule]

% Minted
\usepackage{minted}
\usemintedstyle{autumn}

% - Change the colour of the line numbers to gray.
\renewcommand{\theFancyVerbLine}{\textcolor[rgb]{0.85,0.85,0.85}{\footnotesize\arabic{FancyVerbLine}}}

% Page numbers
\usepackage{fancyhdr}
\pagestyle{fancyplain}
\fancyhf{}
\fancyhead[R]{\thepage}
\renewcommand{\headrulewidth}{0pt}
\setlength{\headheight}{2em}


% --- Failed attempt at causing \newpage on blank lines ---
\makeatletter
%\showoutput

\def\@wasblank{\PYG {err}{BLANK}}
\def\foo{\aftergroup\ffoo}
\def\ffoo{\goodbreak}% or \clearpage or whatever
\let\zzzz\FV@PreProcessLine
\def\FV@PreProcessLine{%
    \ifx\FV@Line\@empty
        \def\FV@Line{BLANK}%
    \fi
    \ifx\FV@Line\@wasblank
        \def\FV@Line{\aftergroup\aftergroup\aftergroup\foo}%
    \fi
\zzzz}
% --- ---

\begin{document}

\section*{EXAMPLE}
\begin{minted}[breaklines,linenos]{scheme}
(module interp (lib "eopl.ss" "eopl")
  
  (require "drscheme-init.scm")

  (require "lang.scm")
  (require "data-structures.scm")
  (require "environments.scm")
  (require "store.scm")
  (require "classes.scm")
  
  (provide value-of-program value-of instrument-let instrument-newref)

;;;;;;;;;;;;;;;; switches for instrument-let ;;;;;;;;;;;;;;;;

  (define instrument-let (make-parameter #f))

  ;; say (instrument-let #t) to turn instrumentation on.
  ;;     (instrument-let #f) to turn it off again.

;;;;;;;;;;;;;;;; the interpreter ;;;;;;;;;;;;;;;;

  ;; value-of-program : Program -> ExpVal
  ;; Page: 336
  (define value-of-program 
    (lambda (pgm)
      (initialize-store!)             
      (cases program pgm
        (a-program (class-decls body)
          (initialize-class-env! class-decls)
          (value-of body (init-env))))))

  ;; value-of : Exp * Env -> ExpVal
  ;; Page: 336 and 337
  (define value-of
    (lambda (exp env)
      (cases expression exp

        (const-exp (num) (num-val num))

        (var-exp (var) (deref (apply-env env var)))

        (diff-exp (exp1 exp2)
          (let ((val1
		  (expval->num
		    (value-of exp1 env)))
                (val2
		  (expval->num
		    (value-of exp2 env))))
            (num-val
	      (- val1 val2))))
        
        (sum-exp (exp1 exp2)
          (let ((val1
		  (expval->num
		    (value-of exp1 env)))
                (val2
		  (expval->num
		    (value-of exp2 env))))
            (num-val
	      (+ val1 val2))))

        (zero?-exp (exp1)
	  (let ((val1 (expval->num (value-of exp1 env))))
	    (if (zero? val1)
	      (bool-val #t)
	      (bool-val #f))))

        (if-exp (exp0 exp1 exp2) 
          (if (expval->bool (value-of exp0 env))
            (value-of exp1 env)
            (value-of exp2 env)))

        (let-exp (vars exps body)       
	  (when (instrument-let)
	    (eopl:printf "entering let ~s~%" vars))
          (let ((new-env 
                  (extend-env 
                    vars
                    (map newref (values-of-exps exps env))
                    env)))
	      (when (instrument-let)
		(begin
		  (eopl:printf "entering body of let ~s with env =~%" vars)
		  (pretty-print (env->list new-env))
		  (eopl:printf "store =~%")
		  (pretty-print (store->readable (get-store-as-list)))
		  (eopl:printf "~%")
		  ))
	      (value-of body new-env)))

        (proc-exp (bvars body)
	  (proc-val
	    (procedure bvars body env)))

        (call-exp (rator rands)          
          (let ((proc (expval->proc (value-of rator env)))
                (args (values-of-exps rands env)))
	    (apply-procedure proc args)))

        (letrec-exp (p-names b-varss p-bodies letrec-body)
          (value-of letrec-body
            (extend-env-rec** p-names b-varss p-bodies env)))

        (begin-exp (exp1 exps)
          (letrec 
            ((value-of-begins
               (lambda (e1 es)
                 (let ((v1 (value-of e1 env)))
                   (if (null? es)
                     v1
                     (value-of-begins (car es) (cdr es)))))))
            (value-of-begins exp1 exps)))

        (assign-exp (x e)
          (begin
            (setref!
              (apply-env env x)
              (value-of e env))
            (num-val 27)))


        (list-exp (exps)
          (list-val
            (values-of-exps exps env)))

        ;; new cases for CLASSES language

        (new-object-exp (class-name rands)
          (let ((args (values-of-exps rands env))
                (obj (new-object class-name)))
            (apply-method
              (find-method class-name 'initialize)
              obj
              args)
            obj))

        (self-exp ()
          (apply-env env '%self))

        (method-call-exp (obj-exp method-name rands)
          (let ((args (values-of-exps rands env))
                (obj (value-of obj-exp env)))
            (apply-method
              (find-method (object->class-name obj) method-name)
              obj
              args)))
      
        (super-call-exp (method-name rands)
          (let ((args (values-of-exps rands env))
                (obj (apply-env env '%self)))
            (apply-method
              (find-method (apply-env env '%super) method-name)
              obj
              args)))        
        )))

  ;; apply-procedure : Proc * Listof(ExpVal) -> ExpVal
  (define apply-procedure
    (lambda (proc1 args)
      (cases proc proc1
        (procedure (vars body saved-env)
          (let ((new-env
                  (extend-env
                    vars
                    (map newref args)
                    saved-env)))
            (when (instrument-let)
              (begin
                (eopl:printf
                  "entering body of proc ~s with env =~%"
                  vars)
                (pretty-print (env->list new-env)) 
                (eopl:printf "store =~%")
                (pretty-print (store->readable (get-store-as-list)))
                (eopl:printf "~%")))
            (value-of body new-env))))))

  
  ;; apply-method : Method * Obj * Listof(ExpVal) -> ExpVal
  (define apply-method                    
    (lambda (m self args)
      (cases method m
        (a-method (vars body super-name field-names)
          (value-of body
            (extend-env vars (map newref args)
              (extend-env-with-self-and-super
                self super-name
                (extend-env field-names (object->fields self)
                  (empty-env)))))))))

  (define values-of-exps
    (lambda (exps env)
      (map
        (lambda (exp) (value-of exp env))
        exps)))

  ;; store->readable : Listof(List(Ref,Expval)) 
  ;;                    -> Listof(List(Ref,Something-Readable))
  (define store->readable
    (lambda (l)
      (map
        (lambda (p)
          (cons
            (car p)
            (expval->printable (cadr p))))
        l)))

  )
\end{minted}

% \inputminted[breaklines,linenos]{scheme}{./rkt/test.rkt}

\end{document}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants