mirror of
https://github.com/CatalaLang/catala.git
synced 2024-11-08 07:51:43 +03:00
abc5a00c2f
This is a hack, but not a dirty one: a new command `catala pygmentize` is added, which is just a wrapper around `pygmentize` that calls it with the proper lexers defined. The point is that this needs no installation, just a stock `pygmentize` installation and the `catala` binary.
152 lines
5.4 KiB
OCaml
152 lines
5.4 KiB
OCaml
(* This file is part of the Catala compiler, a specification language for tax
|
|
and social benefits computation rules. Copyright (C) 2020 Inria, contributor:
|
|
Emile Rolley <emile.rolley@tuta.io>
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
|
use this file except in compliance with the License. You may obtain a copy of
|
|
the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
License for the specific language governing permissions and limitations under
|
|
the License. *)
|
|
|
|
open Catala_utils
|
|
open Cli
|
|
|
|
let literal_title = function
|
|
| En -> "Legislative text implementation"
|
|
| Fr -> "Implémentation de texte législatif"
|
|
| Pl -> "Implementacja tekstów legislacyjnych"
|
|
|
|
let literal_generated_by = function
|
|
| En -> "Document generated by"
|
|
| Fr -> "Document généré par"
|
|
| Pl -> "Dokument wygenerowany przez"
|
|
|
|
let literal_source_files = function
|
|
| En -> "Source files weaved in this document"
|
|
| Fr -> "Fichiers sources tissés dans ce document"
|
|
| Pl -> "Pliki źródłowe w tym dokumencie"
|
|
|
|
let literal_disclaimer_and_link = function
|
|
| En ->
|
|
"This document was produced from a set of source files written in the \
|
|
Catala programming language, mixing together the legislative text and the \
|
|
computer code that translates it. For more information about the \
|
|
methodology and how to read the code, please visit \
|
|
[https://catala-lang.org](https://catala-lang.org)."
|
|
| Fr ->
|
|
"Ce document a été produit à partir d'un ensemble de fichiers sources \
|
|
écrits dans le langage de programmation Catala, mêlant le texte \
|
|
législatif et le code informatique qui le traduit. Pour plus \
|
|
d'informations sur la méthodologie et sur la façon de lire le code, \
|
|
veuillez consulter le site \
|
|
[https://catala-lang.org](https://catala-lang.org)."
|
|
| Pl ->
|
|
"Niniejszy dokument został opracowany na podstawie zestawu plików \
|
|
źródłowych napisanych w języku programowania Catala, łączących tekst \
|
|
legislacyjny z kodem komputerowym, który go tłumaczy. Więcej informacji \
|
|
na temat metodologii i sposobu odczytywania kodu można znaleźć na stronie \
|
|
[https://catala-lang.org](https://catala-lang.org)"
|
|
|
|
let literal_last_modification = function
|
|
| En -> "last modification"
|
|
| Fr -> "dernière modification le"
|
|
| Pl -> "ostatnia modyfikacja"
|
|
|
|
let get_language_extension = function
|
|
| Fr -> "catala_fr"
|
|
| En -> "catala_en"
|
|
| Pl -> "catala_pl"
|
|
|
|
let raise_failed_pandoc (command : string) (error_code : int) : 'a =
|
|
Errors.raise_error
|
|
"Weaving failed: pandoc command \"%s\" returned with error code %d" command
|
|
error_code
|
|
|
|
let run_pandoc (s : string) (backend : [ `Html | `Latex ]) : string =
|
|
let pandoc = "pandoc" in
|
|
let tmp_file_in = Filename.temp_file "catala_pandoc" "in" in
|
|
let tmp_file_out = Filename.temp_file "catala_pandoc" "out" in
|
|
let oc = open_out tmp_file_in in
|
|
output_string oc s;
|
|
close_out oc;
|
|
let pandoc_args =
|
|
[|
|
|
"-f";
|
|
"markdown+multiline_tables+tex_math_dollars";
|
|
"--mathjax";
|
|
"-t";
|
|
(match backend with `Html -> "html" | `Latex -> "latex");
|
|
"-o";
|
|
tmp_file_out;
|
|
|]
|
|
in
|
|
let cmd =
|
|
Format.sprintf "%s %s %s" pandoc
|
|
(String.concat " " (Array.to_list pandoc_args))
|
|
tmp_file_in
|
|
in
|
|
let return_code = Sys.command cmd in
|
|
if return_code <> 0 then raise_failed_pandoc cmd return_code;
|
|
let oc = open_in tmp_file_out in
|
|
let tmp_file_as_string = really_input_string oc (in_channel_length oc) in
|
|
close_in oc;
|
|
Sys.remove tmp_file_in;
|
|
Sys.remove tmp_file_out;
|
|
tmp_file_as_string
|
|
|
|
let check_exceeding_lines
|
|
?(max_len = 80)
|
|
(start_line : int)
|
|
(filename : string)
|
|
(content : string) =
|
|
content
|
|
|> String.split_on_char '\n'
|
|
|> List.iteri (fun i s ->
|
|
let len_s =
|
|
Uutf.String.fold_utf_8 (fun (acc : int) _ _ -> acc + 1) 0 s
|
|
in
|
|
if len_s > max_len then (
|
|
Cli.warning_print "The line %s in %s is exceeding %s characters:"
|
|
(Cli.with_style
|
|
ANSITerminal.[Bold; yellow]
|
|
"%d"
|
|
(start_line + i + 1))
|
|
(Cli.with_style ANSITerminal.[Bold; magenta] "%s" filename)
|
|
(Cli.with_style ANSITerminal.[Bold; red] "%d" max_len);
|
|
Cli.warning_print "%s%s" (String.sub s 0 max_len)
|
|
(Cli.with_style
|
|
ANSITerminal.[red]
|
|
"%s"
|
|
String.(sub s max_len (len_s - max_len)))))
|
|
|
|
let with_pygmentize_lexer lang f =
|
|
let lexer_py =
|
|
let lexer_fname = "lexer_" ^ Cli.language_code lang ^ ".py" in
|
|
match Pygment_lexers.read lexer_fname with
|
|
| None -> failwith "Pygments lexer not found for this language"
|
|
| Some lexer -> lexer
|
|
in
|
|
File.with_temp_file "pygments_lexer_" ".py" ~contents:lexer_py
|
|
@@ fun pyg_lexer -> f ["-l"; pyg_lexer; "-x"]
|
|
|
|
let call_pygmentize ?lang args =
|
|
let cmd = "pygmentize" in
|
|
let check_exit n =
|
|
if n <> 0 then
|
|
Errors.raise_error
|
|
"Weaving failed: pygmentize command %S returned with error code %d"
|
|
(String.concat " " (cmd :: args))
|
|
n
|
|
in
|
|
match lang with
|
|
| None -> File.process_out ~check_exit cmd args
|
|
| Some lang ->
|
|
with_pygmentize_lexer lang
|
|
@@ fun lex_args -> File.process_out ~check_exit cmd (lex_args @ args)
|