<commit_before>define([
    "hr/hr",
    "hr/promise",
    "utils/normalize",
    "utils/loading",
    "utils/dialogs",
    "utils/normalize",
    "models/article",
    "models/book",
    "core/server",
    "core/settings",
    "views/grid",
    "views/summary",
    "views/editor",
    "views/preview"
], function(hr, Q, normalize, loading, dialogs, normalize, Article, Book, server, settings, Grid, Summary, Editor, Preview) {
    var generate = node.require("gitbook").generate,
        normalizeFilename = node.require("normall").filename,
        dirname = node.require("path").dirname;
    var gui = node.gui;

    var BookView = hr.View.extend({
        className: "book",
        defaults: {
            base: null
        },

        initialize: function() {
            BookView.__super__.initialize.apply(this, arguments);

            this.model = this.model || new Book({}, {
                base: this.options.base
            });
            this.editorSettings = settings;

            // Map article path -> content
            this.articles = {};
            this.currentArticle = null;

            this.grid = new Grid({
                columns: 3
            }, this);
            this.grid.appendTo(this);

            // Summary
            this.summary = new Summary({}, this);
            this.summary.update();
            this.grid.addView(this.summary, {width: 20});

            // Editor
            this.editor = new Editor({}, this);
            this.editor.update();
            this.grid.addView(this.editor);

            // Preview
            this.preview = new Preview({}, this);
            this.preview.update();
            this.grid.addView(this.preview);

            // Languages menu
            this.listenTo(this.model, "change:langs", this.updateLanguagesMenu);
            this.listenTo(this.model, "change:lang", function() {
                this.summary.load();
                this.openReadme();
            });
            this.listenTo(this.model, "set:lang", this.updateLanguagesMenu);
            this.updateLanguagesMenu();

            this.openReadme();
        },

        // Update languages menu
        updateLanguagesMenu: function() {
            var that = this;
            var submenu = new gui.Menu();
            var currentLang = this.model.get("lang");

            _.chain(this.model.get("langs"))
            .map(function(lang) {
                return new gui.MenuItem({
                    label: lang.title,
                    type: "checkbox",
                    checked: currentLang.lang == lang.lang,
                    click: function () {
                        that.model.set("lang", lang);
                    }
                });
            })
            .each(submenu.append.bind(submenu));
            this.parent.langsMenu.submenu = submenu;
        },

        // Build the book (website)
        buildBook: function(params, options) {
            var that = this;

            var p = generate.folder(_.extend(params || {}, {
                input: this.model.root()
            }));

            return loading.show(p, "Building website ...");
        },

        // Generate a file (pdf or ebook)
        buildBookFile: function(format, params) {
            var that = this;

            var filename = "book."+format;

            dialogs.saveAs(filename)
            .then(function(_path) {
                var p = generate.file(_.extend(params || {}, {
                    extension: format,
                    input: that.model.root(),
                    output: _path,
                    generator: "ebook"
                }))

                return loading.show(p, "Building ebook ("+format+") ...")
                .then(_.constant(_path));
            })
            .then(function(_path) {
                node.gui.Shell.showItemInFolder(_path);
            }, dialogs.error);
        },

        // Refresh preview
        refreshPreviewServer: function() {
            var that = this;
            console.log("start server on ", this.model.root());

            return server.stop()
            .then(function() {
                return that.buildBook();
            })
            .then(function(options) {
                return server.start(options.output)
            })
            .then(function() {
                server.open();
            }, dialogs.error);<commit_msg>Add loading indicator when preparing website for preview<commit_after>define([
    "hr/hr",
    "hr/promise",
    "utils/normalize",
    "utils/loading",
    "utils/dialogs",
    "utils/normalize",
    "models/article",
    "models/book",
    "core/server",
    "core/settings",
    "views/grid",
    "views/summary",
    "views/editor",
    "views/preview"
], function(hr, Q, normalize, loading, dialogs, normalize, Article, Book, server, settings, Grid, Summary, Editor, Preview) {
    var generate = node.require("gitbook").generate,
        normalizeFilename = node.require("normall").filename,
        dirname = node.require("path").dirname;
    var gui = node.gui;

    var BookView = hr.View.extend({
        className: "book",
        defaults: {
            base: null
        },

        initialize: function() {
            BookView.__super__.initialize.apply(this, arguments);

            this.model = this.model || new Book({}, {
                base: this.options.base
            });
            this.editorSettings = settings;

            // Map article path -> content
            this.articles = {};
            this.currentArticle = null;

            this.grid = new Grid({
                columns: 3
            }, this);
            this.grid.appendTo(this);

            // Summary
            this.summary = new Summary({}, this);
            this.summary.update();
            this.grid.addView(this.summary, {width: 20});

            // Editor
            this.editor = new Editor({}, this);
            this.editor.update();
            this.grid.addView(this.editor);

            // Preview
            this.preview = new Preview({}, this);
            this.preview.update();
            this.grid.addView(this.preview);

            // Languages menu
            this.listenTo(this.model, "change:langs", this.updateLanguagesMenu);
            this.listenTo(this.model, "change:lang", function() {
                this.summary.load();
                this.openReadme();
            });
            this.listenTo(this.model, "set:lang", this.updateLanguagesMenu);
            this.updateLanguagesMenu();

            this.openReadme();
        },

        // Update languages menu
        updateLanguagesMenu: function() {
            var that = this;
            var submenu = new gui.Menu();
            var currentLang = this.model.get("lang");

            _.chain(this.model.get("langs"))
            .map(function(lang) {
                return new gui.MenuItem({
                    label: lang.title,
                    type: "checkbox",
                    checked: currentLang.lang == lang.lang,
                    click: function () {
                        that.model.set("lang", lang);
                    }
                });
            })
            .each(submenu.append.bind(submenu));
            this.parent.langsMenu.submenu = submenu;
        },

        // Build the book (website)
        buildBook: function(params, options) {
            var that = this;

            var p = generate.folder(_.extend(params || {}, {
                input: this.model.root()
            }));

            return loading.show(p, "Building website ...");
        },

        // Generate a file (pdf or ebook)
        buildBookFile: function(format, params) {
            var that = this;

            var filename = "book."+format;

            dialogs.saveAs(filename)
            .then(function(_path) {
                var p = generate.file(_.extend(params || {}, {
                    extension: format,
                    input: that.model.root(),
                    output: _path,
                    generator: "ebook"
                }))

                return loading.show(p, "Building ebook ("+format+") ...")
                .then(_.constant(_path));
            })
            .then(function(_path) {
                node.gui.Shell.showItemInFolder(_path);
            }, dialogs.error);
        },

        // Refresh preview
        refreshPreviewServer: function() {
            var that = this;
            console.log("start server on ", this.model.root());

            return server.stop()
            .then(function() {
                return loading.show(that.buildBook(), "Preparing website for preview ...");
            })
            .then(function(options) {
                return server.start(options.output)
            })
            .then(function() {
                server.open();
            }, dialogs.error);
{'fraction_non_alphanumeric': 0.13110510916047716, 'fraction_numerical': 0.0006752194463200541, 'mean_word_length': 1.4314637482900137, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2178023', 'n_tokens_mistral': 2358, 'n_tokens_neox': 2237, 'n_words': 456}