author | wenzelm |
Sun, 19 May 2024 18:43:45 +0200 | |
changeset 80181 | aa92c0f96036 |
parent 77202 | 064566bc1f35 |
permissions | -rw-r--r-- |
76606 | 1 |
/* Title: Pure/PIDE/document_editor.scala |
2 |
Author: Makarius |
|
3 |
||
76730 | 4 |
Central resources and configuration for interactive document preparation. |
76606 | 5 |
*/ |
6 |
||
7 |
package isabelle |
|
8 |
||
9 |
||
77197
a541da01ba67
clarified signature selection: SortedSet[String], which fits better to stored json and works properly on Windows (NB: document theories have an authentic session-theory name);
wenzelm
parents:
77195
diff
changeset
|
10 |
import scala.collection.immutable.SortedSet |
a541da01ba67
clarified signature selection: SortedSet[String], which fits better to stored json and works properly on Windows (NB: document theories have an authentic session-theory name);
wenzelm
parents:
77195
diff
changeset
|
11 |
|
a541da01ba67
clarified signature selection: SortedSet[String], which fits better to stored json and works properly on Windows (NB: document theories have an authentic session-theory name);
wenzelm
parents:
77195
diff
changeset
|
12 |
|
76606 | 13 |
object Document_Editor { |
14 |
/* document output */ |
|
15 |
||
16 |
def document_name: String = "document" |
|
17 |
def document_output_dir(): Path = Path.explode("$ISABELLE_HOME_USER/document_output") |
|
77185 | 18 |
def document_output(name: String): Path = document_output_dir() + Path.basic(name) |
19 |
||
77202
064566bc1f35
clarified signature: follow terminology of isabelle.Sessions and isabelle.Build;
wenzelm
parents:
77197
diff
changeset
|
20 |
object Meta_Info { |
064566bc1f35
clarified signature: follow terminology of isabelle.Sessions and isabelle.Build;
wenzelm
parents:
77197
diff
changeset
|
21 |
def read(name: String = document_name): Option[Meta_Info] = { |
77185 | 22 |
val json_path = document_output(name).json |
23 |
if (json_path.is_file) { |
|
24 |
val json = JSON.parse(File.read(json_path)) |
|
25 |
for { |
|
26 |
selection <- JSON.list(json, "selection", JSON.Value.String.unapply) |
|
27 |
sources <- JSON.string(json, "sources") |
|
28 |
log <- JSON.string(json, "log") |
|
29 |
pdf <- JSON.string(json, "pdf") |
|
30 |
} yield { |
|
77202
064566bc1f35
clarified signature: follow terminology of isabelle.Sessions and isabelle.Build;
wenzelm
parents:
77197
diff
changeset
|
31 |
Meta_Info(name, |
77197
a541da01ba67
clarified signature selection: SortedSet[String], which fits better to stored json and works properly on Windows (NB: document theories have an authentic session-theory name);
wenzelm
parents:
77195
diff
changeset
|
32 |
SortedSet.from(selection), |
77185 | 33 |
SHA1.fake_digest(sources), |
34 |
SHA1.fake_digest(log), |
|
35 |
SHA1.fake_digest(pdf)) |
|
36 |
} |
|
37 |
} |
|
38 |
else None |
|
39 |
} |
|
76606 | 40 |
|
77185 | 41 |
def write( |
77197
a541da01ba67
clarified signature selection: SortedSet[String], which fits better to stored json and works properly on Windows (NB: document theories have an authentic session-theory name);
wenzelm
parents:
77195
diff
changeset
|
42 |
selection: SortedSet[String], |
77185 | 43 |
doc: Document_Build.Document_Output, |
44 |
name: String = document_name |
|
45 |
): Unit = { |
|
46 |
val json = |
|
47 |
JSON.Object( |
|
77197
a541da01ba67
clarified signature selection: SortedSet[String], which fits better to stored json and works properly on Windows (NB: document theories have an authentic session-theory name);
wenzelm
parents:
77195
diff
changeset
|
48 |
"selection" -> selection.toList, |
77185 | 49 |
"sources" -> doc.sources.toString, |
50 |
"log" -> SHA1.digest(doc.log).toString, |
|
51 |
"pdf" -> SHA1.digest(doc.pdf).toString) |
|
52 |
File.write(document_output(name).json, JSON.Format.pretty_print(json)) |
|
53 |
} |
|
54 |
} |
|
55 |
||
77202
064566bc1f35
clarified signature: follow terminology of isabelle.Sessions and isabelle.Build;
wenzelm
parents:
77197
diff
changeset
|
56 |
sealed case class Meta_Info( |
77185 | 57 |
name: String, |
77197
a541da01ba67
clarified signature selection: SortedSet[String], which fits better to stored json and works properly on Windows (NB: document theories have an authentic session-theory name);
wenzelm
parents:
77195
diff
changeset
|
58 |
selection: SortedSet[String], |
77185 | 59 |
sources: SHA1.Digest, |
60 |
log: SHA1.Digest, |
|
61 |
pdf: SHA1.Digest |
|
62 |
) { |
|
63 |
def check_files(): Boolean = { |
|
64 |
val path = document_output(name) |
|
65 |
path.log.is_file && |
|
66 |
path.pdf.is_file && |
|
67 |
log == SHA1.digest(File.read(path.log)) && |
|
68 |
pdf == SHA1.digest(path.pdf) |
|
69 |
} |
|
70 |
} |
|
71 |
||
72 |
def write_document( |
|
77197
a541da01ba67
clarified signature selection: SortedSet[String], which fits better to stored json and works properly on Windows (NB: document theories have an authentic session-theory name);
wenzelm
parents:
77195
diff
changeset
|
73 |
selection: SortedSet[String], |
77185 | 74 |
doc: Document_Build.Document_Output, |
75 |
name: String = document_name |
|
76 |
): Unit = { |
|
77 |
val output = document_output(name) |
|
77184 | 78 |
File.write(output.log, doc.log) |
79 |
Bytes.write(output.pdf, doc.pdf) |
|
77202
064566bc1f35
clarified signature: follow terminology of isabelle.Sessions and isabelle.Build;
wenzelm
parents:
77197
diff
changeset
|
80 |
Meta_Info.write(selection, doc, name = name) |
77184 | 81 |
} |
82 |
||
77185 | 83 |
def view_document(name: String = document_name): Unit = { |
84 |
val path = document_output(name).pdf |
|
76606 | 85 |
if (path.is_file) Isabelle_System.pdf_viewer(path) |
86 |
} |
|
87 |
||
88 |
||
76730 | 89 |
/* configuration state */ |
76609
cc9ddf373bd2
maintain global state of document editor views, notably for is_active operation;
wenzelm
parents:
76606
diff
changeset
|
90 |
|
77144
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
wenzelm
parents:
76994
diff
changeset
|
91 |
sealed case class Session( |
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
wenzelm
parents:
76994
diff
changeset
|
92 |
background: Option[Sessions.Background], |
77197
a541da01ba67
clarified signature selection: SortedSet[String], which fits better to stored json and works properly on Windows (NB: document theories have an authentic session-theory name);
wenzelm
parents:
77195
diff
changeset
|
93 |
selection: SortedSet[String], |
77144
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
wenzelm
parents:
76994
diff
changeset
|
94 |
snapshot: Option[Document.Snapshot] |
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
wenzelm
parents:
76994
diff
changeset
|
95 |
) { |
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
wenzelm
parents:
76994
diff
changeset
|
96 |
def is_vacuous: Boolean = background.isEmpty |
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
wenzelm
parents:
76994
diff
changeset
|
97 |
def is_pending: Boolean = snapshot.isEmpty |
77149
3991a35cd740
automatically build document when selected theories are finished;
wenzelm
parents:
77147
diff
changeset
|
98 |
def is_ready: Boolean = background.isDefined && snapshot.isDefined |
77144
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
wenzelm
parents:
76994
diff
changeset
|
99 |
|
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
wenzelm
parents:
76994
diff
changeset
|
100 |
def get_background: Sessions.Background = background.get |
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
wenzelm
parents:
76994
diff
changeset
|
101 |
def get_variant: Document_Build.Document_Variant = get_background.info.documents.head |
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
wenzelm
parents:
76994
diff
changeset
|
102 |
def get_snapshot: Document.Snapshot = snapshot.get |
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
wenzelm
parents:
76994
diff
changeset
|
103 |
} |
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
wenzelm
parents:
76994
diff
changeset
|
104 |
|
76609
cc9ddf373bd2
maintain global state of document editor views, notably for is_active operation;
wenzelm
parents:
76606
diff
changeset
|
105 |
sealed case class State( |
76678 | 106 |
session_background: Option[Sessions.Background] = None, |
77197
a541da01ba67
clarified signature selection: SortedSet[String], which fits better to stored json and works properly on Windows (NB: document theories have an authentic session-theory name);
wenzelm
parents:
77195
diff
changeset
|
107 |
selection: SortedSet[String] = SortedSet.empty, |
76609
cc9ddf373bd2
maintain global state of document editor views, notably for is_active operation;
wenzelm
parents:
76606
diff
changeset
|
108 |
views: Set[AnyRef] = Set.empty, |
cc9ddf373bd2
maintain global state of document editor views, notably for is_active operation;
wenzelm
parents:
76606
diff
changeset
|
109 |
) { |
76678 | 110 |
def is_active: Boolean = session_background.isDefined && views.nonEmpty |
76609
cc9ddf373bd2
maintain global state of document editor views, notably for is_active operation;
wenzelm
parents:
76606
diff
changeset
|
111 |
|
76715
bf5ff407f32f
clarified state of document model vs. document editor selection (again, see also a9d52d02bd83);
wenzelm
parents:
76678
diff
changeset
|
112 |
def all_document_theories: List[Document.Node.Name] = |
bf5ff407f32f
clarified state of document model vs. document editor selection (again, see also a9d52d02bd83);
wenzelm
parents:
76678
diff
changeset
|
113 |
session_background match { |
bf5ff407f32f
clarified state of document model vs. document editor selection (again, see also a9d52d02bd83);
wenzelm
parents:
76678
diff
changeset
|
114 |
case Some(background) => background.base.all_document_theories |
bf5ff407f32f
clarified state of document model vs. document editor selection (again, see also a9d52d02bd83);
wenzelm
parents:
76678
diff
changeset
|
115 |
case None => Nil |
bf5ff407f32f
clarified state of document model vs. document editor selection (again, see also a9d52d02bd83);
wenzelm
parents:
76678
diff
changeset
|
116 |
} |
bf5ff407f32f
clarified state of document model vs. document editor selection (again, see also a9d52d02bd83);
wenzelm
parents:
76678
diff
changeset
|
117 |
|
76716
a7602257a825
clarified state document nodes for Theories_Status / Document_Dockable;
wenzelm
parents:
76715
diff
changeset
|
118 |
def active_document_theories: List[Document.Node.Name] = |
a7602257a825
clarified state document nodes for Theories_Status / Document_Dockable;
wenzelm
parents:
76715
diff
changeset
|
119 |
if (is_active) all_document_theories else Nil |
a7602257a825
clarified state document nodes for Theories_Status / Document_Dockable;
wenzelm
parents:
76715
diff
changeset
|
120 |
|
76715
bf5ff407f32f
clarified state of document model vs. document editor selection (again, see also a9d52d02bd83);
wenzelm
parents:
76678
diff
changeset
|
121 |
def select( |
77197
a541da01ba67
clarified signature selection: SortedSet[String], which fits better to stored json and works properly on Windows (NB: document theories have an authentic session-theory name);
wenzelm
parents:
77195
diff
changeset
|
122 |
theories: Iterable[String], |
76715
bf5ff407f32f
clarified state of document model vs. document editor selection (again, see also a9d52d02bd83);
wenzelm
parents:
76678
diff
changeset
|
123 |
set: Boolean = false, |
bf5ff407f32f
clarified state of document model vs. document editor selection (again, see also a9d52d02bd83);
wenzelm
parents:
76678
diff
changeset
|
124 |
toggle: Boolean = false |
bf5ff407f32f
clarified state of document model vs. document editor selection (again, see also a9d52d02bd83);
wenzelm
parents:
76678
diff
changeset
|
125 |
): State = { |
bf5ff407f32f
clarified state of document model vs. document editor selection (again, see also a9d52d02bd83);
wenzelm
parents:
76678
diff
changeset
|
126 |
copy(selection = |
77197
a541da01ba67
clarified signature selection: SortedSet[String], which fits better to stored json and works properly on Windows (NB: document theories have an authentic session-theory name);
wenzelm
parents:
77195
diff
changeset
|
127 |
theories.foldLeft(selection) { |
a541da01ba67
clarified signature selection: SortedSet[String], which fits better to stored json and works properly on Windows (NB: document theories have an authentic session-theory name);
wenzelm
parents:
77195
diff
changeset
|
128 |
case (sel, theory) => |
a541da01ba67
clarified signature selection: SortedSet[String], which fits better to stored json and works properly on Windows (NB: document theories have an authentic session-theory name);
wenzelm
parents:
77195
diff
changeset
|
129 |
val b = if (toggle) !selection(theory) else set |
a541da01ba67
clarified signature selection: SortedSet[String], which fits better to stored json and works properly on Windows (NB: document theories have an authentic session-theory name);
wenzelm
parents:
77195
diff
changeset
|
130 |
if (b) sel + theory else sel - theory |
76715
bf5ff407f32f
clarified state of document model vs. document editor selection (again, see also a9d52d02bd83);
wenzelm
parents:
76678
diff
changeset
|
131 |
}) |
bf5ff407f32f
clarified state of document model vs. document editor selection (again, see also a9d52d02bd83);
wenzelm
parents:
76678
diff
changeset
|
132 |
} |
bf5ff407f32f
clarified state of document model vs. document editor selection (again, see also a9d52d02bd83);
wenzelm
parents:
76678
diff
changeset
|
133 |
|
76609
cc9ddf373bd2
maintain global state of document editor views, notably for is_active operation;
wenzelm
parents:
76606
diff
changeset
|
134 |
def register_view(id: AnyRef): State = copy(views = views + id) |
cc9ddf373bd2
maintain global state of document editor views, notably for is_active operation;
wenzelm
parents:
76606
diff
changeset
|
135 |
def unregister_view(id: AnyRef): State = copy(views = views - id) |
77144
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
wenzelm
parents:
76994
diff
changeset
|
136 |
|
77161
913c781ff6ba
support document preparation from already loaded theories;
wenzelm
parents:
77149
diff
changeset
|
137 |
def session(pide_session: isabelle.Session): Session = { |
77144
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
wenzelm
parents:
76994
diff
changeset
|
138 |
val background = session_background.filter(_.info.documents.nonEmpty) |
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
wenzelm
parents:
76994
diff
changeset
|
139 |
val snapshot = |
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
wenzelm
parents:
76994
diff
changeset
|
140 |
if (background.isEmpty) None |
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
wenzelm
parents:
76994
diff
changeset
|
141 |
else { |
77161
913c781ff6ba
support document preparation from already loaded theories;
wenzelm
parents:
77149
diff
changeset
|
142 |
val snapshot = pide_session.snapshot() |
77197
a541da01ba67
clarified signature selection: SortedSet[String], which fits better to stored json and works properly on Windows (NB: document theories have an authentic session-theory name);
wenzelm
parents:
77195
diff
changeset
|
143 |
def document_ready(theory: String): Boolean = |
a541da01ba67
clarified signature selection: SortedSet[String], which fits better to stored json and works properly on Windows (NB: document theories have an authentic session-theory name);
wenzelm
parents:
77195
diff
changeset
|
144 |
pide_session.resources.session_base.loaded_theory(theory) || |
a541da01ba67
clarified signature selection: SortedSet[String], which fits better to stored json and works properly on Windows (NB: document theories have an authentic session-theory name);
wenzelm
parents:
77195
diff
changeset
|
145 |
snapshot.theory_consolidated(theory) |
77161
913c781ff6ba
support document preparation from already loaded theories;
wenzelm
parents:
77149
diff
changeset
|
146 |
if (snapshot.is_outdated || !selection.forall(document_ready)) None |
77147 | 147 |
else Some(snapshot) |
77144
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
wenzelm
parents:
76994
diff
changeset
|
148 |
} |
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
wenzelm
parents:
76994
diff
changeset
|
149 |
Session(background, selection, snapshot) |
42c3970e1ac1
clarified Document_Editor.Session: more explicit types, more robust operations;
wenzelm
parents:
76994
diff
changeset
|
150 |
} |
76609
cc9ddf373bd2
maintain global state of document editor views, notably for is_active operation;
wenzelm
parents:
76606
diff
changeset
|
151 |
} |
77195 | 152 |
|
153 |
||
154 |
/* build */ |
|
155 |
||
156 |
def build( |
|
157 |
session_context: Export.Session_Context, |
|
158 |
document_session: Document_Editor.Session, |
|
159 |
progress: Progress |
|
160 |
): Unit = { |
|
161 |
val session_background = document_session.get_background |
|
162 |
val context = |
|
163 |
Document_Build.context(session_context, |
|
164 |
document_session = Some(session_background.base), |
|
165 |
document_selection = document_session.selection, |
|
166 |
progress = progress) |
|
167 |
||
168 |
Isabelle_System.make_directory(document_output_dir()) |
|
169 |
Isabelle_System.with_tmp_dir("document") { tmp_dir => |
|
170 |
val engine = context.get_engine() |
|
171 |
val variant = document_session.get_variant |
|
172 |
val directory = engine.prepare_directory(context, tmp_dir, variant, verbose = true) |
|
173 |
val ok = |
|
77202
064566bc1f35
clarified signature: follow terminology of isabelle.Sessions and isabelle.Build;
wenzelm
parents:
77197
diff
changeset
|
174 |
Meta_Info.read() match { |
064566bc1f35
clarified signature: follow terminology of isabelle.Sessions and isabelle.Build;
wenzelm
parents:
77197
diff
changeset
|
175 |
case Some(meta_info) => |
064566bc1f35
clarified signature: follow terminology of isabelle.Sessions and isabelle.Build;
wenzelm
parents:
77197
diff
changeset
|
176 |
meta_info.check_files() && meta_info.sources == directory.sources |
77195 | 177 |
case None => false |
178 |
} |
|
179 |
if (!ok) { |
|
180 |
write_document(document_session.selection, |
|
181 |
engine.build_document(context, directory, verbose = true)) |
|
182 |
} |
|
183 |
} |
|
184 |
} |
|
76606 | 185 |
} |