git.s-ol.nu mmm / 5db27ae
lots of fixes s-ol 2 years ago
34 changed file(s) with 365 addition(s) and 271 deletion(s). Raw diff Collapse all Expand all
3232 \insert "#{dot} "
3333 \insert i @journal
3434 \insert ", volume #{@volume}" if @volume
35 else if @series
36 \insert "#{dot} "
37 \insert i @series
38 \insert ", No. #{@number}" if @number
3539 \insert ", pages #{@pages}" if @pages
3640 \insert "#{dot} #{@publisher}" if @publisher
3741 when 'web', 'online'
1515
1616 find_fileder = (fileder, origin) ->
1717 if 'string' == type fileder
18 if fileder == ''
19 assert origin, "cannot resolve empty path without origin!"
20 return origin
21
1822 if '/' ~= fileder\sub 1, 1
1923 assert origin, "cannot resolve relative path '#{fileder}' without origin!"
2024 fileder = "#{origin.path}/#{fileder}"
2731 else
2832 assert BROWSER and BROWSER.root, "cannot resolve absolute path '#{fileder}' without BROWSER and root set!"
2933 assert (BROWSER.root\walk fileder), "couldn't resolve path '#{fileder}'"
30
3134 else
3235 assert fileder, "no fileder passed."
3336
105108
106109 intext = sup a key, href: "##{id}"
107110
108 print "STYLE IS '#{opts.style}'"
109111 span intext, div {
110112 class: 'sidenote'
111 style: opts.style or 'margin-top: -1rem;'
113 style: opts.style or 'margin-top: -1.25rem;'
112114
113115 div :id, class: 'hook'
114116 b key, class: 'ref'
0 title
01 abstract
12 motivation
23 historical-approaches
67 evaluation
78 conclusion
89 references
10 statement-of-originality
911 ba_log
33
44 =>
55 div {
6 class: 'print-ownpage'
7
68 h1 link_to @, "appendix: project log"
79 table.unpack for post in *@children
810 continue if post\get 'hidden: bool'
66
77 ### publishing and blogging
88 Since mmmfs has grown out of the need for a versatile CMS for a personal publishing website, it is not surprising to
9 to see that it is still up to that job. Nevertheless it is worth taking a look at its strengths and weaknesses in this
9 see that it is still up to that job. Nevertheless it is worth taking a look at its strengths and weaknesses in this
1010 context:
1111
1212 The system has proven itself perfect for publishing small- and medium-size articles and blog posts, especially for its
1414 videos (as in the documentation in the appendix), but also less conventional media such as
1515 interactive diagrams<mmm-embed path="../references/aspect-ratios" wrap="sidenote"></mmm-embed> or twitter postings.
1616
17 On the other hand, the development of the technical framework for this very thesis has posed greater challenges.
17 <!-- @TODO -->
18 On the other hand, the development of the technical framework for this thesis has posed greater challenges.
1819 In particular, the implementation of the reference and sidenote systems are brittle and uninspiring.
1920
2021 This is mostly due to the approach of splitting up the thesis into a multitude of fileders, and the current lack of
2122 mechanisms to re-capture information spread throughout the resulting history effectively.
2223 Another issue is that the system is currently based on the presumption that content can and should be interpreted
23 separate from its parent and context in most cases. This has made the implementation of sidenotes less idiomatic
24 separately from its parent and context in most cases. This has made the implementation of sidenotes less idiomatic
2425 than initially anticipated.
2526
2627 ### pinwall
7071 more general `mmm/dom` type-interface, allowing for a greater variety of types of content to be used as slides.
7172
7273 ## general concerns
73 While the system has proven pretty successfuly and moldable to the different use-cases that it has been tested in,
74 While the system has proven pretty successful and moldable to the different use-cases that it has been tested in,
7475 there are also limitations in the proposed system that have become obvious in developing and working with the system.
7576 Some of these have been anticipated for some time and concrete research directions for solutions are apparent,
7677 while others may be intrinsic limitations in the approach taken.
7778
7879 ### global set of converts
79 In the current system, there exists only a single, global set of *converts* that can be potentially applied
80 to facets anywhere in the system.
80 In the current system, there is only a single, global set of *converts* that can be potentially applied to facets
81 anywhere in the system.
8182 Therefore it is necessary to encode behaviour directly (as code) in facets wherever exceptional behaviour is required.
8283 For example if a fileder conatining multiple images wants to provide custom UI for each image when viewed independently,
8384 this code has to either be attached to every image individually (and redundantly), or added as a global convert.
8485 To make sure this convert does not interfere with images elsewhere in the system, it would be necessary to introduce
85 a new type and change the images to use it, which may present more problems yet and works against the principle of
86 compatibility the system has been constructed for.
86 a new type and change the images to use it, which may present even more problems, and works against the principle of
87 compatibility that the system has been constructed for.
8788
8889 A potential direction of research in the future is to allow specifying *converts* as part of the fileder tree.
8990 Application of *converts* could then be scoped to their fileders' subtrees, such that for any facet only the *converts*
99100 ### code outside of the system
100101 At the moment, a large part of the mmmfs codebase is still separate from the content, and developed outside of mmmfs
101102 itself. This is a result of the development process of mmmfs and was necessary to start the project as the filesystem
102 itself matured, but has become a limitation of the user experience now: Potential users of mmmfs would generally start
103 itself matured, but has now become a limitation of the user experience: potential users of mmmfs would generally start
103104 by becoming familiar with the operation of mmmfs from within the system, as this is the expected (and designated)
104105 experience developed for them. All of the code that lives outside of the mmmfs tree is therefore invisible and opaque
105106 to them, actively limiting their understanding, and thereby the customizability, of the system.
109110
110111 In general however, some portion of code may always have to be left outside of the system.
111112 This also wouldn't necessarily represent a problem, but in this case it is particularily relevant
112 for the global set of *converts* (see above), as well as the layout used to render the web view,
113 both of which are expected to undergo changes as users adapt the system to their own content types and
113 for the global set of *converts* (see above), as well as the layout used to render the web view.
114 Both of these are expected to undergo changes as users adapt the system to their own content types and
114115 domains of interest, as well as their visual identity, respectively.
115116
116117 ### type system
133134 and feeling of ownership of their data by overemphasizing the tools in between,
134135 the automagical coercion of data types introduces distance between the user and
135136 an understanding of the data in the system.
136 This poses a threat to the transparency of the system, and a potential lack of the quality of "Embodiment" (see above).
137 This poses a threat to the transparency of the system, and potentially a lack of the "Embodiment" quality (see above).
137138
138139 Potential solutions could be to communicate the conversion path clearly and explicitly together with the content,
139140 as well as making this display interactive to encourage experimentation with custom conversion queries.
140 Emphasising the conversion process more strongly in this way might be able to turn this feature from an opaque
141 hindrance into a transparent tool using careful UX and UI design.
141 Emphasising the conversion process more strongly in this way might be a way to turn this feature from an opaque
142 hindrance into a transparent tool. This should represent a challenge mostly in terms of UX and UI design.
142143
143144 ### editing
144 Because many *converts* are not necessarily reversible,
145 it is very hard to implement generic ways of editing stored data in the same format it is viewed.
146 For example, the system trivially converts markdown-formatted text sources into viewable HTML markup,
147 but it is hardly possible to propagate changes to the viewable HTML back to the markdown source.
148 This particular instance of the problem might be solvable using a Rich-Text editor, but the general problem
149 worsens when the conversion path becomes more complex:
150 If the markdown source was fetched via HTTP from a remote URL (e.g. if the facet's type was `URL -> text/markdown`),
151 it is not possible to edit the content at all, since the only data owned by the system is the URL string itself,
152 which is not part of the viewable representation at all.
153 Similarily, when viewing output that is generated by code (e.g. `text/moonscript -> mmm/dom`),
154 the code itself is not visible to the user when interacting with the viewable representation,
155 and if the user wishes to change parts of the representation the system is unable to relate these changes to elements
156 of the code or assist the user in doing so.
145 Because many *converts* are not necessarily reversible, it is very hard to implement generic ways of editing stored data
146 in the same format it is viewed. For example, the system trivially converts markdown-formatted text sources into
147 viewable HTML markup, but it is hardly possible to propagate changes to the viewable HTML back to the markdown source.
148 This particular instance of the problem might be solvable using a Rich-Text editor, but the general problem worsens when
149 the conversion path becomes more complex: If the markdown source was fetched via HTTP from a remote URL (e.g. if the
150 facet's type was `URL -> text/markdown`), it is not possible to edit the content at all, since the only data owned by
151 the system is the URL string itself, which is not part of the viewable representation. Similarily, when viewing output
152 that is generated by code (e.g. `text/moonscript -> mmm/dom`), the code itself is not visible to the user, and if the
153 user wishes to change parts of the representation, the system is unable to relate these changes to elements of the code
154 or assist the user in doing so.
157155
158 However even where plain text is used and edited, a shortcoming of the current approach to editing is evident:
159 The content editor is wholly separate from the visible representation, and only facets of the currently viewed
160 fileder can be edited. This means that content cannot be edited in its context, which is particularily annoying
161 due to the fragmentation of content that mmmfs encourages.
156 However, even where plain text is used and edited, a shortcoming of the current approach to editing is evident:
157 The content editor is wholly separate from the visible representation, and only facets of the currently viewed fileder
158 can be edited. This means that content cannot be edited in its context, which is exacerbated by the extreme
159 fragmentation of content that mmmfs encourages.
162160
163 As a result, interacting with the system at large is still a very different experience than editing content (and
161 As a result, interacting with the system at large is still a very different experience from editing content (and
164162 thereby extending the system) in it. This is expected to represent a major hurdle for users getting started with the
165 system, and is a major shortcoming in enabling end-user programming as set as a goal for
166 this project. A future iteration should take care to reconsider how editing can be integrated more holistically
167 with the other core concepts of the design.
163 system, and is a major shortcoming in enabling end-user programming, as set as a goal for this project.
164 A future iteration should carefully reconsider how editing could be integrated more holistically with the other core
165 concepts of the design.
00 language_support
11 image
22 markdown
3 empty
43 gallery
54 pinwall
+0
-1
root/articles/mmmfs/examples/empty/title: text$plain less more
0 Hey I'm an almost empty Fileder.
+0
-7
root/articles/mmmfs/examples/gallery/preview: text$moonscript -> fn -> mmm$dom.moon less more
0 import div, img, br from require 'mmm.dom'
1
2 => div {
3 'the first pic as a little taste:',
4 br!,
5 img src: @children[1]\get 'preview', 'URL -> image/png'
6 }
0 A Gallery of 25 random pictures, come on in!
0 a gallery of images
+0
-5
root/articles/mmmfs/examples/image/preview: text$moonscript -> fn -> mmm$dom.moon less more
0 import img from require 'mmm.dom'
1
2 -- look for main content with 'URL to png' type
3 -- and wrap in an mmm/dom image tag
4 => img src: @gett 'URL -> image/png'
0 Hey I'm like a link to a picture or smth
0 link to a remote image
1515 This makes it suitable for denoting formatted-text titles and other small strings of text.
1616
1717 The problem of embedding other content together with text comfortably is also solved easily,
18 becase Markdown allows embedding arbitrary HTML in the document.
18 because Markdown allows embedding arbitrary HTML in the document.
1919 This made it possible to define a set of pseudo-HTML elements in the Markdown-convert,
2020 `<mmm-embed>` and `<mmm-link>`, which respectively embed and link to other content native to mmm.
2121
2222 ### scientific publishing
23 <div class="sidenote">
23 <div class="sidenote" style="margin-top: 1.25rem">
2424 One of the 'standard' solutions, <a href="https://www.latex-project.org/">LaTeX</a>,
2525 is arguably at least as complex as the mmm system proposed here, but has a much narrower scope,
2626 since it does not support interaction.
2727 </div>
28
2829 Scientific publishing is notoriously complex, involving not only the transclusion of diagrams
2930 and other media, but generally requiring precise and consistent control over formatting and layout.
3031 Some of these complexities are tedious to manage, but present good opportunities for programmatic
4243
4344 For convenience, a convert from the `URL -> cite/acm` type has been provided to `URL -> text/bibtex`,
4445 which generates links to the ACM Digital Library<mmm-embed path="../references/acm-dl" wrap="sidenote"></mmm-embed>
45 API for accessing BibTeX citations for documents in the library.
46 This means that it is enough to store the link to the ACM DL entry in mmmfs,
47 and the reference will automatically be fetched (and track potential remote corrections).
46 API for accessing BibTeX citations for documents in the library. This means that it is enough to store the link to the
47 ACM DL entry in mmmfs, and the reference will automatically be fetched, and therefore stay up to date with potential
48 remote corrections.
4849
4950 ## pinwall
5051 In many situations, in particular for creative work, it is often useful to compile resources of
6162 and outputs the list of containers as DOM elements.
6263
6364 The position and size of each panel are stored in an ad-hoc facet, encoded in the JSON data format:
64 `pinwall_info: text/json`. This facet can then set on each child and accessed whenever the script is called
65 `pinwall_info: text/json`. Such a facet is set on each child and read whenever the script is called
6566 to render the children, plugging the values within the facet into the visual styling of the document.
6667
6768 The script can also set event handlers that react to user input while the document is loaded,
6869 and allow the user to reposition and resize the individual pinwall items by clicking and dragging
6970 on the upper border or lower right-hand corner respectively.
7071 Whenever a change is made the event handler can then update the value in the `pinwall_info` facet,
71 so that the script places the content at the updated position and size next time it is invoked.
72 so that the updated position and size are stored for the next time the pinwall is opened.
7273
7374 ## slideshow
7475 Another common use of digital documents is as aids in a verbal presentation.
8384 of the website that may distract from the presentation, and register an event handler for keyboard accelerators
8485 for moving through the presentation.
8586
86 Finally the script simply embeds the first of its child-fileders into the viewport rect.
87 One the current slide is changed, the next embedded child is simply chosen.
87 Finally the script simply embeds the first of its child-fileders into the viewport rectangle.
88 Once the current slide is changed, the next embedded child is simply chosen.
8889
90 <!--
8991 ## code documentation
9092 /meta/mmm.dom/:%20text/html+interactive
93 -->
+0
-6
root/articles/mmmfs/examples/markdown/preview: text$markdown.md less more
0 See I have like
1
2 - a list of things
3 - (two things)
4
5 and some bold **text** and `code tags` with me.
0 This is a markdown document rendered using [marked][marked] on the client, and [discount][discount] on the server.
1 All Markdown features are supported, for example there is support for lists...
2
3 - a list of things
4 - (two things)
5
6 ...and syntax-highlighted code tags:
7
8 ```
9 print "Hello World"
10 ```
11
12 Since Markdown supports inline HTML, mmmfs shorthands can also be used to embed and reference content from elsewhere in
13 the system. For example, the title of this fileder can be embedded using
14 `<mmm-embed facet="title"></mmm-embed>`:
15
16 <mmm-embed facet="title"></mmm-embed>
17
18 [marked]: https://marked.js.org/
19 [discount]: https://luarocks.org/modules/craigb/discount
0 I'm not even five lines of markdown but i render myself!
0 markdown content
1212 title = child\gett 'title', 'text/plain'
1313
1414 -- get 'preview' as a DOM description (nil if no value or conversion possible)
15 content = child\get 'preview', 'mmm/dom'
15 -- content = child\get 'preview', 'mmm/dom'
1616
1717 -- div {
1818 -- h4 title, style: { margin: 0, cursor: 'pointer' }, onclick: -> BROWSER\navigate child.path
3030
3131 li link_to child
3232
33 content = ul for child in *@children
34 preview child
33 examples = div {
34 style:
35 position: 'relative'
36 'margin-top': '4rem'
3537
36 -- table.insert content, 1, (@gett 'intro: mmm/dom')
37 -- div content
38 div "The online version is available at ", (a "s-ol.nu/ba", href: 'https://s-ol.nu/ba'), ".", class: 'sidenote'
39 "The following examples can be viewed and inspected in the interactive version online:"
40 ul for child in *@children
41 preview child
42 }
3843
39 div (@gett 'intro: mmm/dom'), content
44 div (@gett 'intro: mmm/dom'), examples
2121 use of the tools and general 'passive' use of containing system at large.
2222
2323 These serve as guiding principles for the design and evaluation of computer systems for end-users, but are by nature
24 very abstract. The following properties are therefore derived as more concrete proposals based on some more specific
24 very abstract. The following properties are therefore derived as more concrete proposals based on more specific
2525 constraints: namely the construction of a system for end-users to keep, structure and display personal information and
26 thoughts in.
26 thoughts.
2727
2828 modularity
2929 ----------
3030
3131 The *UNIX Philosophy*<mmm-embed path="../references/unix" wrap="sidenote"></mmm-embed> describes the software design
3232 paradigm pioneered in the creation of the Unix operating system at the AT&T Bell Labs research center in the 1960s. The
33 concepts are considered quite influental and are still notably applied in the Linux community. Many attempts at
33 concepts are considered quite influential and are still notably applied in the Linux community. Many attempts at
3434 summaries exist, but the following includes the pieces that are especially relevant even today:
3535
3636 > Even though the UNIX system introduces a number of innovative programs and techniques, no single program or idea makes
4646 interacting pieces also enables future growth and customization, since pieces may be swapped out with customized or
4747 alternate software at any time.
4848
49 Settling on a specific modular design model, and reifying other components of a system in terms of it also corresponds
49 Settling on a specific modular design model, and reifying other components of a system in terms of it, also corresponds
5050 directly to the concept of *Embodiment* described by Ink & Switch.
5151
5252 content transclusion
5353 --------------------
5454
55 The strengths of modular architectures should similarily also extend into the way the system will be used by users.
55 The strengths of modular architectures should similarily extend also into the way the system will be used by users.
5656 If users are to store their information and customized behaviour in such an architecture, then powerful tools need to be
5757 present in order to assemble more complex solutions out of such parts. Therefore static content should be able to be
5858 linked to (as envisioned for the *Memex*, see above), but also to be <mmm-embed wrap="marginnote"
00 historical approaches
11 =====================
22
3 Two of the earliest wholistic computing systems, the Xerox Alto and Xerox Star, both developed at Xerox PARC and
3 Two of the earliest holistic computing systems, the Xerox Alto and Xerox Star, both developed at Xerox PARC and
44 introduced in the 70s and early 80s, pioneered not only graphical user-interfaces, but also the "Desktop Metaphor".
55 The desktop metaphor presents information as stored in "Documents" that can be organized in folders and on the
66 "Desktop". It invokes a strong analogy to physical tools. One of the differences between the Xerox Star system and
3838 path="../references/memex" wrap="sidenote"></mmm-embed>, the concept predates much of the technology that later was used
3939 to implement many parts of the vision.
4040
41 <!--
4142 While the article extrapolates from existing technology at the time, describing at times
4243 very concrete machinery based on microfilm and mechanical contraptions, many of the conceptual predictions became
4344 true or inspired ....
45 -->
4446
4547 One of the most innovative elements of Bush's predictions is the idea of technologically cross-referenced and
4648 connected information, which would later be known and created as *hypertext*. While hypertext powers the majority of
4749 today's internet, many of the advantages that Bush imagined have not carried over into the personal use of computers.
48 There are very few tools for creating personal, highly-interconnected knowledgebases, even though this is technically
49 feasible, and a proven concept (exemplified for example by the massively successful online encyclopedia
50 There are very few tools for creating personal, highly-interconnected knowledgebases, even though it is technologically
51 feasible and a proven concept (exemplified for example by the massively successful online encyclopedia
5052 *Wikipedia*<mmm-embed path="../references/wikipedia" wrap="sidenote"></mmm-embed>).
5153
5254 While there are little such tools available today, one of the systems that could be said to have come closest to a
53 practical implementation of such a Memex-inspired system for personal use might be Apple's *HyperCard*.
55 practical implementation of a Memex-inspired system for personal use might be Apple's *HyperCard*.
5456
5557 In a live demonstration<mmm-embed path="../references/hypercard" wrap="sidenote"></mmm-embed>, the creators of the
5658 software showcase a system of stacks of cards that together implement, amongst others, a calendar (with yearly and
6163 different card.
6264
6365 Alongside Spreadsheets, *HyperCard* remains one of the most successful implementations of end-user programming, even
64 today. While it's technical abilities have been long matched and surpassed by other software (such as the ubiquitous
65 *Hypertext Markup Language*, HTML), these technical successors have failed the legacy of *HyperCard* as an end-user
66 tool: while it is easier than ever to publish content on the web (through various social media and microblogging
67 services), the benefits of hypermedia as a customizable medium for personal management have nearly vanished.
68 End-users do not create hypertext anymore.
66 today. While its technical abilities have been long matched and surpassed by other software (such as the ubiquitous
67 *Hypertext Markup Language*, HTML and the associated programming language *JavaScript*), these technical successors have
68 failed the legacy of *HyperCard* as an end-user tool: While it is easier than ever to publish content on the web
69 (through various social media and microblogging services), the benefits of hypermedia as a customizable medium for
70 personal management have nearly vanished. End-users do not create hypertext anymore.
1919 <mmm-embed path="tree_mainstream">schematic view of an example tree in a mainstream filesystem</mmm-embed>
2020
2121 In common filesystems, as pictured, data can be organized hierarchically into *folders* (or *directories*),
22 which serve only as containers of *files*, in which data is actually stored.
23 While *directories* are fully transparent to both system and user (they can be created, browser, listed and viewed by both),
24 *files* are, from the system perspective, mostly opaque and inert blocks of data.
22 which serve only as containers of *files*, in which data is actually stored. While *directories* are fully transparent
23 to both system and user (they can be created, browsed, listed and viewed by both), *files* are, from the system
24 perspective, mostly opaque and inert blocks of data.
2525
2626 Some metadata, such as file size and access permissions, is associated with each file,
2727 but notably the type of data is generally not actually stored in the filesystem,
2828 but determined loosely based on multiple heuristics depending on the system and context.
2929 Some notable mechanism are:
3030
31 - Suffixes in the name are often used to indicate what kind of data a file should contain. However there is no standardization
32 - over this, and often a suffix is used for multiple incompatible versions of a file-format.
31 - Suffixes at the end of the filename are often used to indicate which kind of data a file contains. However there is no
32 centralized standardization of suffixes, and often one suffix is used for multiple incompatible versions of a
33 file-formats, or multiple suffixes are used interchangeably for one format.
3334 - Many file-formats specify a specific data-pattern either at the very beginning or very end of a given file.
3435 On unix systems the `libmagic` database and library of these so-called *magic constants* is commonly used to guess
3536 the file-type based on these fragments of data.
4041 It should be clear already from this short list that to mainstream operating systems, as well as the applications
4142 running on them, the format of a file is almost completely unknown and at best educated guesses can be made.
4243
43 Because these various mechanisms are applied at different times by the operating system and applications,
44 it is possible for files to be labelled as or considered as being in different formats at the same time by different
45 components of the system.
46 <mmm-embed path="confusion" wrap="marginnote" style="margin-top: -5rem;"></mmm-embed>
44 <mmm-embed path="confusion" wrap="marginnote" style="margin-top: -3rem;"></mmm-embed>
45 Because these various mechanisms are applied at different times by the operating system and applications, it is possible
46 for files to be labelled or considered as being in different formats at the same time by different components of the
47 system.
48
4749 This leads to confusion about the factual format of data among users, but can also pose a serious security risk:
4850 Under some circumstances it is possible that a file contains maliciously-crafted code and is treated as an executable
4951 by one software component, while a security mechanism meant to detect such code determines the same file to be a
5052 legitimate image<mmm-embed path="../references/poc-or-gtfo" wrap="sidenote"></mmm-embed> (the file may in fact be valid
5153 in both formats).
5254
53 In mmmfs, the example above might look like this instead:
55 In mmmfs, the example above might look like this instead:
5456 <mmm-embed path="tree_mmmfs">schematic view of an example mmmfs tree</mmm-embed>
5557
56 Superficially, this may look quite similar: there is still only two types of nodes (referred to as *fileders* and *facets*),
57 and again one of them, the *fileders* are used only to hierarchically organize *facets*.
58 Unlike *files*, *factes* don't only store a freeform *name*, there is also a dedicated *type* field associated with every *facet*,
59 that is explicitly designed to be understood and used by the system.
58 Superficially, this may look quite similar: there is still only two types of nodes (referred to as *fileders* and
59 *facets*), and again one of them, the *fileders* are used only to hierarchically organize *facets*. Unlike *files*,
60 *factes* don't only store a freeform *name*, there is also a dedicated *type* field associated with every *facet*, that
61 is explicitly designed to be understood and used by the system.
6062
61 Despite the similarities, the semantics of this system are very different:
62 In mainstream filesystems, each *file* stands for itself only;
63 i.e. in a *directory*, no relationship between *files* is assumed by default,
64 and files are most of the time read or used outside of the context they exist in in the filesystem.
63 Despite the similarities, the semantics of this system are very different: In mainstream filesystems, each *file* stands
64 for itself only; i.e. in a *directory*, no relationship between *files* is assumed by default, and files are most of the
65 time read or used outside of the context they exist in in the filesystem.
6566
6667 In mmmfs, a *facet* should only ever be considered an aspect of its *fileder*, and never as separate from it.
67 A *fileder* can contain multiple *facets*, but they are meant to be alternate or equivalent representations of the *fileder* itself.
68 Though for some uses it is required, software in general does not have to be directly aware of the *facets* existing within a *fileder*,
69 rather it assumes the presence of content in the representation that it requires, and simple requests it.
70 The *Type Coercion Engine* (see below) will then attempt to satisfy this request based on the *facets* that are in fact present.
68 A *fileder* can contain multiple *facets*, but they are meant to be alternate or equivalent representations of the
69 *fileder* itself. Though for some uses it is required, software in general does not have to be directly aware of the
70 *facets* existing within a *fileder*, rather it assumes the presence of content in the representation that it requires,
71 and simple requests it. The *Type Coercion Engine* (see below) will then attempt to satisfy this request based on the
72 *facets* that are in fact present.
7173
72 Semantically a *fileder*, like a *directory*, also encompasses all the other *fileders* nested within it (recursively).
73 Since *fileders* are the primary unit of data to be operated upon, *fileder* nesting emerges as a natural way of structuring complex data,
74 both for access by the system and applications, as well as the user themself.
74 Semantically a *fileder*, like a *directory*, also encompasses all the other *fileders* nested within itself
75 (recursively). Since *fileders* are the primary unit of data to be operated upon, *fileder* nesting emerges as a natural
76 way of structuring complex data, both for access by the system and its components, as well as the user themself.
7577
7678 ## the type system & coercion engine
77 As mentioned above, *facets* store data alongside its *type*, and when applications require data from a *fileder*,
78 they specify the *type* (or the list of *types*) that they require the type to be in.
79 As mentioned above, *facets* store data alongside its *type*, and when a component of the system requires data from a
80 *fileder*, it has to specify the *expected type* (or a list of these) that it requires the data to be in. The system
81 then attempts to coerce one of the existing facets into the *expected type*, if possible. This process can involve many
82 steps such as converting between similar file formats, running executable code stored in a facet, or fetching remote
83 content. The component that requested the data is isolated from this process and does not have to deal with any of the
84 details.
7985
80 In the current iteration of the type system, types are simple strings of text and loosely based on MIME-types [TOOD: quote RFC?].
86 In the current iteration of the type system, types are simple strings of text and loosely based on MIME-types<mmm-embed
87 path="../references/mime-types" wrap="sidenote"></mmm-embed>.
8188 MIME types consist of a major- and minor category, and optionally a 'suffix'.
8289 Here are some common MIME-types that are also used in mmmfs:
8390
8693 - `image/png`
8794 - `image/jpeg`
8895
89 While these types allow some amount of specifity, they fall short of describing their content especially in cases where formats overlap:
90 Source code is often distributed in `.tar.gz` archive files (directory-trees that are first bundled into an `application/x-tar` archive,
91 and then compressed into an `application/gzip` archive).
92 Using either of these two types is either incorrect or insufficient information to properly treat and extract the contained data.
96 While these types allow some amount of specifity, they fall short of describing their content especially in cases where
97 formats overlap: Source code for example is often distributed in `.tar.gz` archive files (directory-trees that are first
98 bundled into an `application/x-tar` archive, and then compressed into an `application/gzip` archive). Using either of
99 these two types is respectively incorrect or insufficient information to properly treat and extract the contained data.
93100
94 To mitigate this problem, mmmfs *types* can be nested. This is denoted in mmmfs *type* strings using the `->` symbol, e.g. the mmmfs-types
95 `application/gzip -> application/tar -> dirtree` and `URL -> image/jpeg` describe a tar-gz-compressed directory tree and the URL linking to a JPEG-picture respectively.
101 To mitigate this problem, mmmfs *types* can be nested. This is denoted in mmmfs *type* strings using the `->` symbol,
102 e.g. the mmmfs *types* `application/gzip -> application/tar -> dirtree` and `URL -> image/jpeg` describe a
103 tar-gz-compressed directory tree and the URL linking to a JPEG-encoded picture respectively.
96104
97105 Depending on the outer type this nesting can mean different things:
98106 for URLs the nested type is expected to be found after fetching the URL with HTTP,
99107 compression formats are expected to contain contents of the nested types,
100108 and executable formats are expected to output data of the nested type.
101109
102 It is a lot more important to be able to accurately describe the type of a *facet* in mmmfs than in mainstream operating systems,
103 because while in the latter types are mostly used only associate an application that will then prompt the user about further steps,
104 mmmfs uses the *type* to automatically find one or more programs to execute to convert or transform the data stored in a *facet*
105 into the *type* required by the application.
110 It is a lot more important to be able to accurately describe the type of a *facet* in mmmfs than in mainstream operating
111 systems, because while in the latter types are mostly used only associate an application that will then prompt the user
112 for further steps if necessary, mmmfs uses the *type* to automatically find one or more programs to execute, in order to
113 convert or transform the data stored in a *facet* into the *type* required in the context where it was requested.
106114
107 This process of *type coercion* uses a database of known *converts*, that can be applied to data.
108 Every *convert* consists of a description of the input *types* that it can accept, the output *type* it would produce for a given input type,
109 as well as the code for actually converting a given piece of data.
110 Simple *converts* may simply consist of a fixed in and output type,
111 such as for example this *convert* for rendering Markdown-encoded text to a HTML hypertext fragment:
115 This process of *type coercion* uses a database of known *converts* that can be applied to data. Every *convert*
116 consists of a description of the input *types* that it can accept, the output *type* it would produce for a given input
117 type, as well as the code for actually converting a given piece of data. Simple *converts* may simply consist of a fixed
118 in and output type, such as for example this *convert* for rendering Markdown-encoded text to a HTML hypertext fragment:
112119
113120 {
114121 inp: 'text/markdown'
128135 This convert uses a Lua Pattern to specify that it can accept an URL to any type of image,
129136 and convert it to an HTML fragment.
130137
131 By using the pattern substitution syntax provided by the Lua `string.gsub` function,
132 converts can also make the type they return depend on the input type, as is required often when nested types are unpacked:
138 By using the pattern substitution syntax provided by the Lua `string.gsub` function, converts can also make the type
139 they return depend on the input type, as is required often when nested types are unpacked:
133140
134141 {
135142 inp: 'application/gzip -> (.*)'
138145 -- implementation stripped for brevity
139146 }
140147
141 This *convert* accepts an `application/gzip` *type* wrapping any other *type*, and captures that nested type in a pattern group.
142 It then uses the substituion syntax to specify that nested type as the output of the conversion.
148 This *convert* accepts an `application/gzip` *type* wrapping any other *type*, and captures that nested type in a
149 pattern group. It then uses the substituion syntax to specify that nested type as the output of the conversion.
143150 For an input *type* of `application/gzip -> image/png` this *convert* would therefore generate the type `image/png`.
144151
145 To further demonstrate the flexibility using this approach, consider this last example:
152 This last example further demonstrates the flexibility of this approach:
146153
147154 {
148155 inp: 'text/moonscript -> (.*)'
153160 This *convert* transpiles MoonScript source-code into Lua source-code, while keeping the nested type
154161 (in this case the result expected when executing either script) the same.
155162
156 In addition to the attributes shown above, every *convert* is also rated with a *cost* value.
157 The cost value is meant to roughly estimate both the cost (in terms of computing power) of the conversion,
158 as well as the accuracy or immediacy of the conversion.
159 For example, resizing an image to a lower size should have a high cost, because the process is computationally expensive,
160 but also because a smaller image represents the original image to a lesser degree.
161 Similarily, an URL to a piece of content is a less immediate representation than the content itself,
162 so the cost of a *convert* that simply generates the URL to a piece of data should be high even if the process is very cheap to compute.
163 In addition to the attributes shown above, every *convert* is also rated with a *cost* value. The cost value is meant to
164 roughly estimate both the cost (in terms of computing power) of the conversion, as well as the accuracy or immediacy of
165 the conversion. For example, resizing an image to a lower size should have a high cost, because the process is
166 computationally expensive, but also because a smaller image represents the original image to a lesser degree.
167 Similarily, an URL to a piece of content is a less immediate representation than the content itself, so the cost of a
168 *convert* that simply generates the URL to a piece of data should be high even if the process is very cheap to compute.
163169
164 Cost is defined in this way to make sure that the result of a type-coercion operation reflects the content that was present as accurately as possible.
165 It is also important to prevent some nonsensical results from occuring, such as displaying a link to content instead of the content itself because
166 the link requires less steps to create than completely converting the content does.
170 Cost is defined in this way to make sure that the result of a type-coercion operation reflects the content that was
171 present as accurately as possible. It is also important to prevent some nonsensical results from occuring, such as
172 displaying a link to content instead of the content itself because the link is cheaper to create than completely
173 converting the content does.
167174
168 Type coercion is implemented using a general pathfinding algorithm, similar to A\*.
169 First, the set of given *types* is found by selecting all *facets* of the *fileder* that match the *name* given in the query.
170 The set of given *types* is marked in green in the following example graph.
175 Type coercion is implemented using a general pathfinding algorithm, based on *Dijkstra's Algorithm*<mmm-embed
176 path="../references/dijkstra" wrap="sidenote"></mmm-embed>. First, the set of given *types* is found by selecting all
177 *facets* of the *fileder* that match the *name* given in the query. The set of given *types* is marked in green in the
178 following example graph.
179 From there the algorithm recursively checks whether it can reach other *types* by applying all matching *converts* to
180 the *type* that is the cheapest to reach currently, excluding any *types* that have already been exhaustively-searched
181 in this way. All *types* found that have not yet been inserted into the set of given *types* are then added to the
182 set, so that they may be searched as well.
171183
172 From there the algorithm recursively checks whether it can reach other types by applying all matching *converts* to the type
173 that is cheapest to reach, excluding any types that have already been exhaustively-searched in this way.
174 All types it finds, that have not yet been inserted into the set of given types are then added to the set,
175 so that they may be searched as well.
184 The algorithm doesn't stop immediately after reaching a *type* from the result set, it continues search until it either
185 completely exhausts the result space, or until all non-exhaustively searched paths already have costs higher than the
186 allowed maximum. This ensures that the optimal path is found, even if a more expensive path is found more quickly
187 initially.
176188
177 The algorithm doesn't stop immediately after reaching a type from the result set,
178 it continues search until it either completely exhausts the result space,
179 or until all non-exhaustively searched paths are already higher than the maximum allowed path.
180 This ensures that the optimal path is found, even if a more expensive path is found more quickly initially.
181
182 <mmm-embed path="type_coercion_graph">excerpt of the graph of conversion paths from two starting facets to mmm/dom</mmm-embed>
189 <mmm-embed path="type_coercion_graph">excerpt of the graph of conversion paths from two starting facets to mmm/dom
190 </mmm-embed>
0 While there can be a distinction between *Native Applications* and *Web Applications* or *Cloud Services*, the following
1 arguments apply to all different technicalal implementations of this same concept. The problems associated
2 specifically with Web- and Cloud-based application models will be discussed separately below.
66 The majority of users interact with modern computing systems in the form of smartphones, laptops or desktop PCs,
77 using the mainstream operating systems Apple iOS and Mac OS X, Microsoft Windows or Android.
88
9 <mmm-embed path="app-types" wrap="marginnote"></mmm-embed>
910 All of these operating systems share the concept of *Applications* (or *Apps*) as one of the core pieces of their
1011 interaction model. Functionality and capabilities of the digital devices are bundled in, marketed, sold and distributed
11 as applications.
12 as applications. This focus on applications as the primary unit of systems can be seen as the root cause of multiple problems.
1213
13 <!-- native vs other vs new ?? -->
14 <!-- limitations not mentioned yet -->
15 In addition, a lot of functionality is nowadays delivered in the form of *Web Apps* or *Cloud Services*, which share the
16 limitations of native applications in addition to more specific issues that will be discussed in a separate section
17 below.
18
19 This focus on applications as the primary unit of systems can be seen as the root cause of multiple problems.
20
21 <!-- rephrase vvv -->
22 For one, since applications are the products companies produce, and software represents a market of users,
14 For one, since applications are produced by private companies on the software market,
2315 developers compete on features integrated into their applications. To stay relevant, monlithic software or software
2416 suites tend to accrete features rather then modularise and delegate to other software<mmm-embed wrap="sidenote"
2517 path="../references/appliances"></mmm-embed>. This makes many software packages more complex and unintuitive than
2618 they need to be, and also cripples interoperability between applications and data formats.
2719
28 Because applications are incentivised to keep customers, they make use of network effects to keep customers locked-in.
29 This often means re-implementing services and functionality that is already available to users,
20 Because (private) software developers are incentivised to keep customers, they make use of network effects to keep
21 customers locked-in. This often means re-implementing services and functionality that is already available to users,
3022 and integrating it directly in other applications or as a new product by the same organisation.
31 While this strategy helps big software companies retain customers, it harms the users, who have to navigate a complex
23 While this strategy helps big software companies retain customers, it harms users, who have to navigate a complex
3224 landscape of multiple incompatible, overlapping and competing software ecosystems.
3325 Data of the same kind, a rich-text document for example, can be shared easily within the software systems of a certain
34 manufacturer, and with other users of the same, but sharing with users of a competing system, even if it has almost the
26 manufacturer and with other users of the same, but sharing with users of a competing system, even if it has almost the
3527 exact same capabilities, can often be problematic.
3628
37 Another issue is that due to the technical challenges of building tools in this system, applications are designed and
29 Another issue is that due to the technical challenges of development in the this paradigm, applications are designed and
3830 developed by experts in application development, rather than experts in the domain of the tool. While developers may
39 solicit feedback, advice and ideas from domain experts, communication is a barrier. Additionally, domain experts are
31 solicit feedback, advice, and ideas from domain experts, communication is a barrier. Additionally, domain experts are
4032 generally unfamiliar with the technical possibilities, and may therefore not be able to express feedback that would lead
4133 to more significant advances.
4234 <mmm-embed path="creative" wrap="marginnote"></mmm-embed>
4739 customize or modify the behaviour of apps, intentionally obscuring the inner-workings of applications and
4840 completely cutting users off from this type of ownership over their technology. While the trend seems to be to further
4941 hide the way desktop operating systems work<mmm-embed path="../references/osx-files" wrap="sidenote"></mmm-embed>,
50 mobile systems like Apple's *iOS* already started out as such so-called *walled gardens*.
42 mobile systems like Apple's *iOS* already started out as such *walled gardens*.
5143
5244 cloud computing
5345 ---------------
6759 consequences<mmm-embed path="../references/adobe" wrap="sidenote"></mmm-embed>, especially for professional users, for
6860 whom an inability to access their tools or their cloud-stored data can pose an existential threat.
6961
70 inert data (formats)
71 --------------------
62 inert data (and data formats)
63 -----------------------------
7264
7365 Cragg coins the term "inert data"<mmm-embed path="../references/super-powers" wrap="sidenote"></mmm-embed> for the data
74 created, and left behind, by apps and applications in the computing model that is currently prevalent: Most data today
66 created and left behind by apps and applications in the computing model that is currently prevalent: Most data today
7567 is either intrinsically linked to one specific application, that controls and limits access to the actual information,
76 or even worse, stored in the cloud where users have no direct access at all and depend soley on online tools that
77 require a stable network connection and a modern browser, and that could be modified, removed or otherwise negatively
78 impacted at any moment.
68 or, even worse, stored in the cloud where users have no direct access at all. In the latter case users depend soley on
69 online tools that require a stable network connection and a modern browser and could be modified, removed, or otherwise
70 negatively impacted at any moment.
7971
8072 Aside from being inaccesible to users, the resulting complex proprietary formats are also opaque and useless to other
8173 applications and the operating system, which often is a huge missed opportunity:
9789 applications only ever concern themselves with a single file at a time, independent of the context the file is stored in
9890 in the filesystem.
9991
100 Data rarely really fits this metaphora of individual files very well, and even when it does, it is rarely exposed to
92 Data rarely really fits this concept of individual files very well, and even when it does, it is rarely exposed to
10193 the user that way: The 'Contacts' app on a mobile phone for example does not store each contacts's information in a
102 separate 'file' (as the metaphora may suggest initially), but rather keeps all information in a single database file,
94 separate 'file' (as the word may suggest initially), but rather keeps all information in a single database file,
10395 which is hidden away from the user. Consequently, access to the information contained in the database is only enabled
10496 through the contacts application's graphical interface, and not through other applications that generically operate on
10597 files.
110102 document there. Both *Photoshop* files and *Word* documents are capable of containing texts and images, but when such
111103 content is copied into them from external sources, such as other files on the same computer, or quotes and links from
112104 the internet, these relationships are irrevocably lost. As illustrated above, additionally, it becomes a lot harder to
113 edit the content once it is aggregated as well. To choose an application for this task is a trade-off, because in
114 applications primarily designed for word processing, arranging content visually is harder and image editing and video
115 embedding options are limited, while tools better suited to these tasks lack nuance when working with text.
105 edit the content once it is aggregated. To choose an application for this task is a hard trade-off to make, because in
106 applications primarily designed for word processing, arranging content visually is hard to do, and image editing and
107 video embedding options are limited, while tools better suited to these tasks lack nuance when working with text.
116108
117 Rather than face this dilemma, a more sensible system could leave the task of positioning and aggregating content of
118 different types to one software component, while multiple different software components can be responsible for editing
119 the individual pieces of content, so that the most appropriate one can be chosen for each element.
109 To avoid facing this dilemma, a more sensible system could leave the task of positioning and aggregating content of
110 different types to one software component, while multiple different software components could be responsible for editing
111 the individual pieces of content, so that the most appropriate one can be chosen for each element. While creating the
112 technological interface between these components is certainly a challenge, the resulting system would greatly benefit
113 from the exponentially-growing capabilties resulting from the modular reuse of components across many contexts: A rich
114 text editor component could be used for example not just in a mixed media collection as proposed above, but also for
115 an email editor or the input fields in a browser.
120116
121117 <div style="height: 2rem;"></div>
122118
123 To summarize, for various reasons, the metaphors and interfaces of computing interfaces today prevent users from deeply
124 understanding the software they use and the data they own, from customizing and improving their experience and
119 To summarize, for various reasons, the metaphors and driving concepts of computing interfaces today prevent users from
120 deeply understanding the software they use and the data they own, from customizing and improving their experience and
125121 interactions, and from properly owning, contextualising and connecting their data.
126122
127 Interestingly, these deficits do not appear throughout the history of todays computing systems, but are based in rather
123 Interestingly, these deficits do not appear throughout the history of today's computing systems, but are based in rather
128124 recent developments in the field. In fact the most influental systems in the past aspired to the polar opposites, as i
129125 will show in the next section.
130126
33 -- resolves to a value of type mmm/dom
44 =>
55 html = require 'mmm.dom'
6 import article, h1, h2, h3, section, p, div, a, sup, ol, li, span, code, pre, br from html
6 import article, h1, p, div from html
77 import moon from (require 'mmm.highlighting').languages
88
9 article with _this = class: 'sidenote-container', style: { 'max-width': '640px', 'line-height': '1.5' }
9 article with _this = class: 'sidenote-container spacious', style: { 'max-width': '640px', 'line-height': '1.5' }
1010 append = (a) -> table.insert _this, a
1111
12 footnote, getnotes = do
13 local *
14 notes = {}
12 append div {
13 h1 'Empowered End-User Computing', style: { 'margin-bottom': 0 }
14 p {
15 style:
16 'margin-top': 0
17 'padding-bottom': '0.2em'
18 'border-bottom': '1px solid black'
1519
16 id = (i) -> "footnote-#{i}"
17
18 footnote = (stuff) ->
19 i = #notes + 1
20 notes[i] = stuff
21 sup a "[#{i}]", style: { 'text-decoration': 'none' }, href: '#' .. id i
22
23 footnote, ->
24 args = for i, note in ipairs notes
25 li (span (tostring i), id: id i), ': ', note
26 notes = {}
27 table.insert args, style: { 'list-style': 'none', 'font-size': '0.8em' }
28 ol table.unpack args
29
30 append h1 'Empowered End-User Computing', style: { 'margin-bottom': 0 }
31 append p "A Historical Investigation and Development of a File-System-Based Environment", style: { 'margin-top': 0, 'padding-bottom': '0.2em', 'border-bottom': '1px solid black' }
32
33 -- render a preview block
34 do_section = (child) ->
35 -- get 'title' as 'text/plain' (error if no value or conversion possible)
36 title = (child\get 'title: text/plain') or child\gett 'name: alpha'
37
38 -- get 'preview' as a DOM description (nil if no value or conversion possible)
39 content = (child\get 'preview: mmm/dom') or child\get 'mmm/dom'
40
41 section {
42 h3 title, style: { margin: 0, cursor: 'pointer' }, onclick: -> BROWSER\navigate child.path
43 content or span '(no renderable content)', style: { color: 'red' },
20 "A Historical Investigation and Development of a File-System-Based Environment"
4421 }
22 }
4523
4624 for child in *@children
4725 append (child\get 'print: mmm/dom') or (child\gett 'mmm/dom')
48 -- do_section child
49
50 append getnotes!
1515 aspect-ratios
1616 alternatives-to-trees
1717 transclusion
18 mime-types
19 dijkstra
0 @article{10.1007/BF01386390,
1 author = {Dijkstra, Edsger W.},
2 title = {A Note on Two Problems in Connexion with Graphs},
3 year = {1959},
4 issue_date = {December 1959},
5 publisher = {Springer-Verlag},
6 address = {Berlin, Heidelberg},
7 volume = {1},
8 number = {1},
9 issn = {0029-599X},
10 url = {https://doi.org/10.1007/BF01386390},
11 doi = {10.1007/BF01386390},
12 journal = {Numer. Math.},
13 month = dec,
14 pages = {269–271},
15 numpages = {3}
16 }
0 @article{rfc6838,
1 series = {Request for Comments},
2 number = 6838,
3 howpublished = {RFC 6838},
4 publisher = {Internet Engineering Task Force},
5 doi = {10.17487/RFC6838},
6 url = {https://tools.ietf.org/html/rfc6838},
7 author = {Freed, Ned and Klensin, John C. and Hansen, Tony},
8 title = {Media Type Specifications and Registration Procedures},
9 pagetotal = 32,
10 year = 2013,
11 month = jan,
12 abstract = {This document defines procedures for the specification and registration of media types for use in HTTP, MIME, and other Internet protocols. This memo documents an Internet Best Current Practice.},
13 }
0 <div class="print-only print-ownpage" style="margin: 4cm 0 0;">
1 <h1>Statement of Originality</h1>
2 <p style="margin-top: 5cm">
3 This is to certify that the content of this project, documentation and thesis is my own work. It
4 has not been submitted for any other degree or other purposes. I certify that the intellectual
5 content of my submission is the product of my own work and that all the assistance received in
6 preparing it as well as all sources used have been properly acknowledged.
7 </p>
8
9 <div style="border-top: 1px solid #000; width: 7cm; margin-top: 3cm;">
10 Sol Bekic
11 </div>
12 </div>
33 -- resolves to a value of type mmm/dom
44 =>
55 html = require 'mmm.dom'
6 import article, h1, h2, h3, section, p, div, a, sup, ol, li, span, code, pre, br from html
6 import article, h1, p, div from html
77 import moon from (require 'mmm.highlighting').languages
88
9 article with _this = class: 'sidenote-container', style: { 'max-width': '640px', 'line-height': '1.5' }
9 article with _this = class: 'sidenote-container spacious', style: { 'max-width': '640px', 'line-height': '1.5' }
1010 append = (a) -> table.insert _this, a
1111
12 footnote, getnotes = do
13 local *
14 notes = {}
12 append div {
13 class: 'screen-only'
14 h1 'Empowered End-User Computing', style: { 'margin-bottom': 0 }
15 p {
16 style:
17 'margin-top': 0
18 'padding-bottom': '0.2em'
19 'border-bottom': '1px solid black'
1520
16 id = (i) -> "footnote-#{i}"
17
18 footnote = (stuff) ->
19 i = #notes + 1
20 notes[i] = stuff
21 sup a "[#{i}]", style: { 'text-decoration': 'none' }, href: '#' .. id i
22
23 footnote, ->
24 args = for i, note in ipairs notes
25 li (span (tostring i), id: id i), ': ', note
26 notes = {}
27 table.insert args, style: { 'list-style': 'none', 'font-size': '0.8em' }
28 ol table.unpack args
29
30 append h1 'Empowered End-User Computing', style: { 'margin-bottom': 0 }
31 append p "A Historical Investigation and Development of a File-System-Based Environment", style: { 'margin-top': 0, 'padding-bottom': '0.2em', 'border-bottom': '1px solid black' }
32
33 -- render a preview block
34 do_section = (child) ->
35 -- get 'title' as 'text/plain' (error if no value or conversion possible)
36 title = (child\get 'title: text/plain') or child\gett 'name: alpha'
37
38 -- get 'preview' as a DOM description (nil if no value or conversion possible)
39 content = (child\get 'preview: mmm/dom') or child\get 'mmm/dom'
40
41 section {
42 h3 title, style: { margin: 0, cursor: 'pointer' }, onclick: -> BROWSER\navigate child.path
43 content or span '(no renderable content)', style: { color: 'red' },
21 "A Historical Investigation and Development of a File-System-Based Environment"
4422 }
23 }
4524
4625 for child in *@children
4726 append child\gett 'mmm/dom'
48 -- do_section child
49
50 append getnotes!
0 <div class="print-only print-ownpage" style="font-size: 1.5rem; width: calc(100% + var(--sidenote-width))">
1 <div style="font-size: 2rem; margin-top: 4cm">
2 <h1>Empowered End-User Computing</h1>
3 <span>A Historical Investigation and Development of a File-System-Based Environment</span>
4 </div>
5 <div style="width: 14cm; margin: 4cm auto 0">
6 <p>by</p>
7 <p>
8 Sol Bekic<br />
9 Student ID 11114279<br />
10 sol.bekic+ba@s-ol.nu
11 </p>
12 <p>
13 written in the Winter Term 2019/20<br />
14 for BA Digital Games<br />
15 at Cologne Game Lab / TH Köln
16 </p>
17 <p>supervised by Prof. Dr. Gundolf S. Freyermuth</p>
18 <p>submitted on 2020-01-07</p>
19 </div>
20 </div>
11 img, video {
22 width: inherit;
33 height: inherit;
4 }
5
6 ul, ol {
7 break-before: avoid-page;
8 break-inside: avoid-page;
49 }
510
611 .wide.markdown,
2429 }
2530 }
2631
32 p {
33 orphans: 6;
34 widows: 6;
35 }
36
2737 .markdown,
2838 .markdown > p,
2939 .markdown > p > a {
40
3041 p, a {
3142 max-width: 100%;
3243 }
117128 .well-warning {
118129 border-color: $gray-fail;
119130 }
131
132 .spacious {
133 h1, h2, h3 {
134 margin-top: 1.7em;
135 }
136
137 h1 + h2,
138 h2 + h3 {
139 margin-top: 0;
140 }
141 }
120142 }
99 position: absolute;
1010 display: none;
1111 }
12
1312
1413 color: $gray-bright;
1514 background: $gray-dark;
0 .print-only {
1 display: none;
2
3 @media print {
4 display: block;
5 }
6 }
7
8 .screen-only {
9 @media print {
10 display: none;
11 }
12 }
13
014 @media print {
1 h1, h2, h3 {
15 h1, h2, h3, h4, h5 {
216 break-after: avoid-page;
17
18 + * {
19 break-before: avoid-page;
20 }
321 }
422
523 .view {
24 flex: 1 0 auto;
25
626 .content {
727 flex: 1 0 auto;
828 }
1333 }
1434 }
1535
36 .print-ownpage {
37 break-before: page;
38 break-after: page;
39 }
40
1641 @page {
1742 size: a4;
1843 margin: 2.5cm 0 2.5cm;
00 $sidenote-width: 14rem;
1
2 :root {
3 --sidenote-width: #{$sidenote-width};
4 }
15
26 .sidenote-container {
37 margin-right: $sidenote-width + 1rem;