This repository contains the source code files of the PML Companion (PMLC), written in Java.
For more information about PML please visit its website.
Java source code of the 'PML Companion (PMLC)'
Home Page: https://www.pml-lang.dev
License: GNU General Public License v2.0
This repository contains the source code files of the PML Companion (PMLC), written in Java.
For more information about PML please visit its website.
In PML 3.0.0, with the resources directory being written to ~/.config/PML_Companion/
, this happens even when you run non-action commands such as pml -version
.
INFO: Creating shared data directory ?/.config/PML_Companion/3_0
PMLC 3.0.0 2022-08-19
I can maybe see why you might desire contextual information on the resources (including overrides) available for the help messages, but I can't imagine you would need the resources directory for getting the version. In scripting, version checking is often a smoke test for checking a command-line tool is runnable, so the result here is that the check is not read-only.
When I run PMLC 3.0.0 inside a Docker container on Linux, the resources directory gets written to ?/.config
. It may be something in how the resources directory string determines home or wherever, when it is inside the container context.
# Dockerfile
FROM alpine:latest
RUN wget "https://github.com/pml-lang/pml-companion/releases/download/v3.0.0/pmlc" && chmod +x pmlc
RUN pmlc -version
# or
ENTRYPOINT ["/pmlc", "-version"]
docker build --tag "pmlc" - < Dockerfile
docker run "pmlc" -version
INFO: Creating shared data directory ?/.config/PML_Companion/3_0
PMLC 3.0.0 2022-08-19
The ?
folder appears to be created relative to the current directory. As a side effect, if you mount the current directory to the container and WORKDIR
into it inside the Dockerfile, the ?
folder with the .config/PML
resources subdirectory will be generated inside the current directory, with root:root
as the owner.
I was doing some preparation work to enhance Sublime PML build system so that it would parse error logs and extract info to enable to navigate through the various errors in their source files (see: tajmone/Sublime-PML#16).
While doing some tests, I've encountered a problem with pmlc
error reports pertaining incorrect positional information being reported for errors that are located after a line-continuation \
.
The following snippet from the beginning of a PML source:
[doc title = Malformed Document (standalone) \
authors = tajmone \
date = YYYY-MM-DD
is reported as:
Error: 'YYYY-MM-DD' is an invalid value for parameter 'date'. Reason:
'YYYY-MM-DD' is not a valid ISO date.
[ >>> doc title = Malformed Document (standalone) \
line 1, column 2
X:\<obscured path>\standalone.pml
the positional info line 1, column 2
is incorrect — should be line 3, column 12
.
To be on the safe side, I've tested this first using Tab indentation (one Tab) and then converting each Tab to 4 spaces, but the result didn't change.
It seems that the problem here is the line continuation \
, which is not being accounted for when reporting the error position, because other tests that don't use line-continuation were reporting error positions correctly.
I've noticed that in the PML User Manual, section Anatomy of a PML Document » Attributes, the line code for the escape character is forced to contain a trailing space (\
) — in the source file 05_anatomy.pml
:
must be terminated by a backslash ([c \\ ]),
The problem here is that using [c \\]
instead of [c \\ ]
won't work because it would be parsed as [c
+\
+\]
, i.e. the second slash is being interpreted as escaping the closing bracket.
To avoid similar problems (which are typical edge cases found on all lightweight syntaxes) I suggest adding some extra special characters:
[empty
or [blank
— replaced by nothing (empty string), post-parsing. It's sole role is to feed a token separator to the parser.[wj
— word-joiner character (⁠
); a code point in Unicode that prevents a line break at its position.(obviously, no closing bracket required for either)
The above example from the PML User Manual could then be fixed via:
must be terminated by a backslash ([c \\[empty]),
Both of these are useful hacks to handle edge-cases where the PML parser could be faced with ambiguities like the above example, and they would be the equivalents of Asciidoctor's predefined characters-substitutions attributes {empty}
/{blank}
and {wj}
, which are extremely useful to handle all sort of edge-cases in AsciiDoc sources.
In Asciidoctor, {empty}
and {blank}
are identical, one is just an alias of the other; I personally prefer [empty
to [blank
, for I believe it's clearer, and I'd avoid having having both, since it's redundant.
The [wj
is also very useful in situations where you need to prevent the browser from wrapping a table column during auto-adjustment (e.g. because one column contains words separated by boundaries like spaces, hyphens, brackets, etc.). Or to prevent wrapping a line between a word and its footnote marker, e.g. someword[1]
→ someword
+\n
+[1]
, whereas someword[wj[1]
and sometimes they can just improve source readability
These would be consistent with the current [nl
and [sp
substitutions available in PML.
Version 1.5.0 2021-06-08
When I call [insert file="other file.pml"]
, if the first line of the other file is a comment like so:
[- Here is a comment. -]
Here is a paragraph.
the converter errs with this error:
Error: '-' is an invalid node tag.
Valid tags are: [...].
[ >>> - Here is a comment. -]
line 1, column 2
If the comment is on later lines, there is no error.
Could you please add a new "Editors Support" category in the repository Discussions, and move therein Discussion #7?
Since editors/IDEs support is an important topic, it might worth dedicating to it its own category, and I was thinking of publishing some posts covering topics like scopes naming and strategies for PML syntaxes, where I wanted to share my experience from the Sublime PML package and the tricks I've learned, which can be useful for anyone creating a PML syntax plug-in in any modern editor based on TextMate grammars.
E.g. I've finally managed to come up with a smart and maintainable system to properly handle node attributes so that Sublime PML will only suggest auto-completions for attributes that are pertinent to a given tag, and only when the cursor is right after the opening node tag, or after another attribute definition — i.e. the syntax is now able to define exactly where tags attributes can go, with awareness of \
for line continuations extending the valid insertion area, and that attributes completions suggestions should end at the first EOL or after encountering text which is not an attribute definition. It took me some trial and error to achieve this, but finally I've managed to come up with a single syntax context which is shared by all nodes, which makes maintenance much easier.
The real trick was to allow the syntax to highlight attributes regardless of whether they are supported by a tag, but restrict completions suggestions only to valid attributes for any tags. This satisfies the criteria of an error-tolerant syntax, and at the same time provides an enhanced editing experience through context-aware completions.
Now that this mechanism is in place, it's just a matter of implementing the remaining tags, attributes and completions — this system even catches unimplemented tags and attributes via (temporary) fallback node/attributes catch-all definitions, which makes the syntax immediately usable in production, even if incomplete.
I believe that the lessons learned here can also apply to other editors that use TextMate-like grammars (e.g. VSCode and Atom), and possibly even apply to Language Servers in some degree. So it might be worth sharing them in the repository Discussions, for the benefits of future contributors — we might also get useful feedback on how to improve this approach.
Creating editor packages can often be confusing, especially when it comes to semantic scoping and choosing appropriate scope names for a syntax like PML (which doesn't fit the paradigm of languages like C, Java, Python, etc., around which these scope naming conventions were designed). Many developers focus only on the syntax highlighting aspect, which is merely aesthetic, but the real power of scopes is their ability to enable/disable various plug-in features according to context: auto-completions, symbols indexing, key-bound actions/macros, etc., which can all be implemented smartly, providing a very smooth editing experience where the syntax is tuned to editing needs.
I'd also like to create a thread on the PML Language Server, where to share links on useful articles and tools, and general thoughts, because a PML Lang Server is definitely the ultimate goal in terms of editors support (albeit still faraway).
It's always nice to have quick access to links and past discussion on such topics.
In version 2.1.0 2021-09-09
, the following code
Body of text with a footnote here[sup
[xref node_id="footnote1" text="1"]
].
[div id="footnote1" 1
Footnote contents
]
yields the following error from the compiler.
Error A node with id 'footnote1' does not exist.
Code [xref node_id="footnote1" text="1"]
The order of [xref]
and [div]
does not make a difference.
Possibly related to #58.
@pml-lang, I'm a bit confused about the fact that the [ch
[title
and [subtitle
nodes all support the id
attribute. For all these nodes, the documentation is identical:
Description: A unique identifier for the node.
An id can be used to:
- identify a node so that an internal link can be done with an 'xref' (cross reference) node.
- identify a node so that it can be styled individually with CSS
- create an HTML anchor so that it can be accessed with the # (hash) sign (e.g. writing id=foo will enable you to have an HTML link ending with #foo.
Usually a heading has only one ID in documents, and supporting an ID (anchor) in both the [ch
and [title
nodes seems redundant and confusion prone, especially since you can't have a titleless chapter heading.
The [doc
node doesn't support an ID because obviously it doesn't need one (at least not semantically), since the doc title is the top of the page, although one might argue that assigning an ID to the [doc [title
node could be useful for providing xrefs to jump back to the top of the document.
My argument is that chapter titles only need one.
The following PML source:
[ch (id=chapter_id) [title (id=title_id) Chapter With Double-ID]
produces this HTML code:
<section id="chapter_id" class="pml-chapter">
<h2 id="title_id" class="pml-chapter-title">Chapter With Double-ID</h2>
</section>
What's the point in having double anchors here? They will both jump to the same document position, but they can confuse users as to which one is the idiomatic way of assigning an anchor for cross references — especially if you consider that each ID must be unique.
In collaborative editing, contributors need to know where to place the ID/anchor, should it go on the [ch
or [title
node? Ending up with large documents where the heading IDs are sometimes on the [ch
node and other time on [title
leads to messy documents, especially if editors rely on editor scripts that target attributes by nodes (e.g. to enforce naming conventions), since these scripts might miss any IDs on the other node.
Since the [doc
node doesn't support an ID directly, but only via the [title
subnode, it seems to me that the most reasonable approach would be to drop the id
attribute from [ch
and only keep it on the [title
node, since the latter is shared between both [doc
and [ch
.
Even more confusing is the fact that the [subtitle
node supports the id
attribute too — meaning that a section heading can have up to three IDs! What's the use of placing an ID/anchor on a subtitle? The position of a title and its subtitle within a document are basically one and the same (nothing else should be placed between them) and since you can't have a subtitle without a title, the [subtitle
node is merely an extension of the [title
node, practically speaking, just as [title
is an extension of [doc
or [ch
, since [title
never stands on its own but always leans on a section heading (be it the main doc title or one of its sub-sections headings).
I think these questions should be addressed before v3.0 is out:
id
attribute on [ch
and [subtitle
are valid, then they should be dropped before PML 3.0 is out — otherwise we'll be seeing another MAJOR release cycle with breaking changes within the same MAJOR release (unacceptable under Semantic Versioning).So, am I missing out something here about the reasons for supporting multiple IDs in section headings?
I know that technically speaking this is all valid HTML (you can place anchors wherever you want, including <strong>
and <em>
), but from a documentation writers' perspective it doesn't make much sense (whereas it might for HTML based GUI designers). Since PML is all about documents, IMO we should stick to writers semantics and best practices, so that PML idiomacy is unambiguous to its users.
Please, add to the online PML Reference Manual the PML version it refers to, like it's done with the PML User Manual.
Currently, it's hard to tell what PML version the Ref Man refers to, since it only mentions the publishing (last edited?) date.
The way the User Man displays the info summary via a table just below the document title is very helpful, the same should be done for the Ref Man too.
It would also be quite useful if you could provide an online archive of all the documents and JSON-tags files of the various PML releases, for consultation and comparison purposes — especially useful for developers of PML related projects, so they can keep track of the syntax changes across releases, but also for users who need to migrate documentation projects created for older versions of PML and need to focus on the syntax changes.
Since each version of the documentation source files is specific to the PML syntax of the release it refers to, building them from source is not an option for it would require to install each PML release (for pre-3.0.0 PML versions, which relied on an installer) — hence the need for their pre-converted HTML versions to be stored somewhere accessible.
If space on the official PML website is not a concern, you could just add the HTML docs adopting a version-based naming convention, e.g.:
Alternatively, you could just create a dedicated repository with all these HTML and JSON docs (e.g. pml-docs-archive
) and serve them online via GitHub Pages, so end users can either consult them online or clone the repository locally.
To enhance the repository visibility:
Edit About box setting (repository details):
pml
practical-markup-language
html-converter
(etc.)GitHub topics are a powerful feature, they don't just simplifying find repositories on GitHub: by adding PML keywords to the topics you're actually promoting PML's visibility on GitHub, and once a keyword reaches a certain numbers of repository that are using it you automatically obtain visibility on various GitHub services and sub-pages.
In Settings » Options: "Social preview" you can add a social media preview card for the PML repository, which will be showed whenever the repository is linked in websites, blogs and forums that support media cards. You'll also find a link to a graphic template there, to build your card with.
You can use the SocialSharePreview.com or Twitter Card Validator
services to check how your card looks like. E.g., here's the link to the media preview card of Sublime-PML; and here's a screenshot from Twitter:
If you need any help with the graphics, just buzz me via PM. I work a lot of graphics.
To enhance the landing page of the pml-lang GitHub profile, add a profile README:
pml-lang/pml-lang
README.md
(or .asciidoc
, etc.) with a brief presentation of PML (not 100% sure, but I think you can include images in the repository too).Needless to say, the same tips apply to any other repository and to the pxml-lang as well.
Not really a bug in PMLC itself, but a potential cause of bugs in the generated HTML files.
When invoking PMLC 3.1.0 with command PML_to_HTML
and option --CSS_files
followed by a directory, PMLC then treats any file within that directory as if it was a CSS file, regardless of its extension (or lack thereof), so in the generated HTML file you have something like this:
<meta name="generator" content="PML 3.1.0 (www.pml-lang.dev)" />
<title>Style Sheet Demo Document</title>
<link rel="stylesheet" href="css/demo.html">
<link rel="stylesheet" href="css/extended.html">
<link rel="stylesheet" href="css/pml-default.css">
<link rel="stylesheet" href="css/pml-default.css.map">
<link rel="stylesheet" href="css/pml-default.scss">
<link rel="stylesheet" href="css/pml-print-default.css" media="print">
<link rel="stylesheet" href="css/pml-print-default.css.map" media="print">
<link rel="stylesheet" href="css/pml-print-default.scss" media="print">
This is extremely inconvenient for any developer, since it forces them to specify CSS files individually, whereas it would be convenient to just pass a folder path and expect PMLC to selectively include only files with the .css
extensions.
Having a folder with CSS files only is counter intuitive for a developer, since Sass files, along with generated CSS maps for debugging stylesheets are usually kept in the same directory. So, the idea of having a "pure CSS folder" is rather naive, and in any case there's always the risk of end users forgetting some file behind, or temporary and system files (often hidden from the end user) in that folder ending up in the generated HTML being linked as a stylesheet.
In other words, it makes sense that PMLC should natively filter directory contents by the .css
extension, and accept any individually specified file as is, regardless of its extension. This is IMO a sensible default, since it applies reasonable file-extension conventions for folder contents filtering, without preventing custom extensions being explicitly used for individual files.
Right now, passing a folder path doesn't seem neither practical nor safe, for it only makes sense if the folder contains CSS files only — which is rarely the case, and hard to guarantee since temporary files (including hidden files) can easily end up there, especially since browsers tend to create temporary files next to the CSS stylesheets when accessing the advanced developer tools (e.g. Chrome).
Blindly linking to any files in the CSS target folder could even potentially result in accidentally revealing personal data, or divulging source files (e.g. if the toolchain tracks the linked stylesheets to post-process them, etc.).
In Lenient Parsing we read:
If a formal node has only attributes (no child nodes) the parenthesis around attributes can be omitted.
The problem is knowing which nodes are childless an which aren't — both for taking advantage of this feature while editing, as well as for implementing its support in editor syntaxes/packages.
The User Manual mentions the [image
node as an example, but having access to the full list of these nodes types would be really useful (as opposed to guess work or trial and error).
It would be really helpful if you could add to the JSON file generated via pmlc tag_info
a dedicated entry for each node, specifying whether is allows child nodes or not, along the lines of "is_raw_text_block"
and HTML_attributes_allowed"
. This would also allow easily auto-generating a list of such nodes (e.g. via Mustache), which could be added as an Appendix to the PML Reference Manual.
I'm not sure how this key should be named but, based on the current keys names, I think that something like "child_nodes_allowed"
might be appropriate, especially for a boolean key.
As a general rule, bear in mind that when it comes to creating packages for editor support, having access to similar info is essential in order to implement syntaxes properly.
E.g. knowing which nodes are allowed inside each and every node, and which are not, is another essential piece of info for being able to detect invalid sub-nodes within the syntax — one you know which nodes are supported, you only need to include them, and treat the rest as invalidly placed nodes.
Currently this type of info is not accessible, which only leaves trial and error — with current number of nodes supported by PML, their possible combinations amounts to a huge number.
In most modern editors' syntax definitions, each node is implemented as independent "context" (JSON/YMAL block) which can then be included wherever required (at the root level, within other nodes, etc.). Knowing in advance what other nodes each node can take as its child is a huge helper in task of building PML syntaxes.
The generated pml_tags.json
file of PML 2.3.0 contains a reference to the [text
tag which has no corresponding entry in the PML Reference Manual:
{
"id":"text",
"type":"inline",
"title":"Text",
"description":null,
"examples":"It's a good day.",
"attributes":null,
"default_attribute_id":null,
"HTML_attributes_allowed":false,
"is_inline_type":true,
"is_raw_text_block":false,
"child_nodes_allowed":false,
"opening_tag":"[text",
"closing_tag":"]",
"latest_doc_url":"https://www.pml-lang.dev/docs/reference_manual/index.html#node_text"
},
Its docs links point to a non-existing anchor:
https://www.pml-lang.dev/docs/reference_manual/index.html#node_text
Which one is wrong, the JSON file or the Ref.Man? i.e. does this [text
node really exist, or is it just undocumented?
Please enable Discussion for the repository, so that end user might freely discuss topics that don't directly affect the repo's development (e.g. the pros and cons of adding new features, comparisons to other syntaxes, etc.) and avoid polluting Issues (which should be reserved for practical maintenance).
The documentation states:
The regex of an identifier is: [a-zA-Z][a-zA-Z0-9_]*.
This rule is not enforced by the converter in version 1.4.0.
Will be fixed in the new parser (version 2.0)
PMLC 3.1.0 | Win 10
NOTE — Although this was already mentioned in a side comment of Issues #93, I'm creating a dedicated Issue for this matter so we can link it specifically and track its status.
As of PMLC 3.1.0, the new --CSS_files
option always copies the specified stylesheets into a css/
subfolder created by PMLC, which hinders development of custom stylesheets when using CSS compilers like Sass, LESS, etc.
When compiling to CSS, Sass also generates the required .css.map
files, and at the end of each output CSS adds a comment containing a link to its corresponding map file, e.g.:
/*# sourceMappingURL=pml-default.css.map */
These CSS map files allow developers to inspect and debug their stylesheets directly in their browser via its Developer Tools, which in most modern browsers include support for CSS maps and Sass/Less sources, which means that the end users are shown the real-use effect of custom CSS definitions directly pointing to their Sass sources and modules, not just the compiled CSS output.
But because the PMLC generated HTML documents are using a copy of the .css
files (located in the css/
subfolder) instead of the original CSS files generated by Sass, the CSS map links in these comments won't be pointing to the correct .css.map
files, thus breaking the advanced debugging features of browsers Dev Tools (e.g. Chrome).
We need either:
p2h
option, allowing end users to bypass the CSS-copying stage by having PMLC simply link to the original files specified in the --CSS_files
parameter, as they are, without creating copies.PMLC p2h
behavior when custom CSS files are specified via the --CSS_files
parameter — i.e. achieving the same as point (1) but without requiring additional CLI parameters.Solution (2) is probably a bad idea, since in most cases end users just want to employ the default stylesheets, or some custom stylesheets stored in PMLC data folders, where in both cases the idea is to create a copy of these stylesheet, which are just multi-use templates.
But even in these cases, it might be useful to be able to control where the CSS file copies end up — i.e. being able to bypass the css/
subfoldering convention by either storing them in the same path as the HTML file, or in a custom folder with any arbitrary name.
But it's clearly important to be able to inform PMLC when a set of custom CSS files need to be copied and linked in the final HTML docs, and when they need to be linked only instead — ideally, PMLC should allow even a combination of both, via different parameters that can be used alongside.
Currently there are three possible workarounds to this, all of which require post-PMLC interventions:
Tweak the generated HTML files, substituting all CSS paths within their headers, e.g.:
<link rel="stylesheet" href="css/pml-default.css">
<link rel="stylesheet" href="css/pml-print-default.css" media="print">
by stripping the css/
path segment:
<link rel="stylesheet" href="pml-default.css">
<link rel="stylesheet" href="pml-print-default.css" media="print">
Tweak the CSS copies within the css/
subfolder, substituting all CSS map paths within their end comment, e.g.:
/*# sourceMappingURL=pml-default.css.map */
by adding a ../
to the CSS path in order to seek for it in the parent-directory, where the Sass sources are usually located too, along with the original CSS files:
/*# sourceMappingURL=../pml-default.css.map */
Copy into the css/
folder all the Sass sources too (including their modules), so that the CSS map paths can be matched to their sources again.
Solution (1) is usually better, since it then allows to view changes to the Sass-generated CSS files by simply refreshing the HTML test docs. The only downside is when there are more HTML test documents involved than CSS files.
Solutions (2) and (3) both result in duplicate files, especially the latter which creates redundant copies not just of the CSS files but also all their Sass sources. Solution (3) also requires rebuilding the HTML test documents via PMLC and then copying again all Sass/CSS file when there are significant changes within the Sass sources and/or their modular structure.
As you can imagine, all of these solution are nothing more than hack-&-slash workarounds to the current limitation imposed by the PMLC native subfoldering conventions. Needless to say, in automated projects any of the above solutions is far from ideal and requires considerate extra scripting work to implement as a post PMLC conversion fix.
@pml-lang, while working on the pandoc PML Writer I've started including test documents from pandoc's test suite. These are documents in various formats covering many formatting elements and their possible combinations.
Although the Lua filter is correct, many of these documents fail conversion via PMLC because they either contain images pointing to the Internet, or links with relative paths, etc., which PMLC doesn't support.
Example, a document containing a link pointing to /url
results in the following PMLC error:
pmlc writer.pml
Error '/url' is an invalid value for parameter 'url'. Reason:
'/url' is an invalid URL Reason:
'/url' is not a valid URL. Reason:
no protocol: /url
Code [ch [title Level 2 with an [link url=/url text="embedded link"]]
Error id INVALID_ATTRIBUTE
I really can't understand why PMLC enforces these restrictions on links and images paths, acting like a sort of validator.
The inability to use images stored on the web, or provide links that use relative paths, or protocols others than those accepted by PMLC (from gopher://
to MS res://
, up to custom URL Monikers) is a huge impediment in the adoption of PML for many domain specific applications:
/url
link like the one from the above error message would be a normal link on a custom server.res://
protocol is essential for storing HTML documents (or images and other assets) into DLLs, and then accessing them from within an application (e.g. via the WebControl).When I think of the HTML format and it's innumerable applications (from HTML based eBook formats to software using WebComponent GUIs) I really struggle with these limitations, especially not being able to include images from the web.
Also, why should PMLC check if an image exists at all? In many documentation toolchains the images are generated on the fly, from ASCII blocks within the source document (or elsewhere), so they are deleted before each, and not available until after the conversion. Procedurally generated images are such a strong component of software documentation that I can hardly imagine working without them (think of railroad diagrams, etc.).
You should really consider either revising the way PMLC handles URL attributes, or at least provide some alternative attributes that allow handling relating paths within any URI scheme and/or custom protocols or monikers.
I fail to see the reasons for the current errors, since all of the above mentioned cases adopt the same convention for how a protocol/moniker is expressed in terms of <name>://path/segmented/by/slashes/
.
The fact that so many basic test docs from pandoc test suite are failing to build with PMLC — not due to failed pandoc to PML conversion, but because of unsupported paths/URLs in PMLC — is a strong indicator that there's something wrong with how PMLC approaches resources paths and links. All the markup syntaxes I've worked with don't attempt to validate paths and URLs (unless you specify options like embedding images as Data URIs), for they assume the author knows what he/she's doing — it could be just a document template, or the image is temporarily unreachable due to a server being done, or the HTML page is intended to be used inside a running executable app, from a DLL ... you name it, there could be hundreds of reasons why an external asset is not reachable at the specified path/URL.
I think these problems have to be solved natively, i.e. in the vanilla PML syntax, as opposed to via custom scripts or extensions.
What are the reasons behind the current way PMLC handles images paths and links? Why links are expected to be expressed via protocols, when an HTML page might simply want to link to another page in the same folder (possibly without having to resort to the file://
protocol)?
There are a few nodes for which the HTML writer wrongly ignores the id
attribute - among them title
and subtitle
.
Clicking in the GUI at the point indicated by the arrow, clears the screen:
This results in a blank screen with just the window title:
The black dot seems to be part of a background window mostly hidden by the main window. Clicking anywhere else on the thin border does not cause any problems. Just the black dot clears the screen.
Is this background window required for the GUI to function? In any case, the GUI has to be closed as there is nothing with which to interact.
The [admon]
element is failing for me in version 2.1.0, saying that the "label" is missing, though I have given it.
Error Input parameter 'label' is required.
Code [admon label="text" text]
The download link in the download page for Windows is broken:
https://www.pml-lang.dev/downloads/windows/PML%20to%20HTML%20Converter-1.4.0.exe
any attempts to download the PML to HTML Converter-1.4.0.exe
file result in a non-existing file error.
Also, it's currently hard to learn which is the latest PML Converter version, since it's no mentioned anywhere in the website, not even in the downloads or install pages — to learn which is the latest version one has to actually hover on the download button and check the URL in the browser status bar.
It would be better if the website were to display the latest PML converter version in the shared top banner, and mention it explicitly in all the download related pages.
Also, since there's no auto-update feature, it would be nice to have some mechanism to be informed on new binary releases, e.g. an RSS feed to which one could subscribe (so any updates will be notified on email clients, etc.).
Converting the following PML document with empty [options
node:
[doc [title Test] [options ]]
results in the following crash error:
ERROR:
The operation has been aborted due to the following unexpected application error:
java.lang.NullPointerException: Cannot invoke "dev.pp.parameters.textTokenParameter.TextTokenParameters.getList()" because "parameters" is null
at dev.pp.parameters.textTokenParameter.TextTokenParameters.merge(TextTokenParameters.java:112)
at dev.pmlc.ext.utilities.pmltohtml.options.PMLToHTMLOptionsHelper.createMergedOptions(PMLToHTMLOptionsHelper.java:71)
at dev.pmlc.commands.pmltohtml.PMLToHTMLCommand.convertDocumentNode(PMLToHTMLCommand.java:147)
at dev.pmlc.commands.pmltohtml.PMLToHTMLCommand$Executor.execute(PMLToHTMLCommand.java:120)
at dev.pmlc.commands.pmltohtml.PMLToHTMLCommand$Executor.execute(PMLToHTMLCommand.java:39)
at dev.pp.commands.command.CommandExecutor.execute(CommandExecutor.java:17)
at dev.pp.commands.command.FormalCommand.execute(FormalCommand.java:159)
at dev.pp.commands.picocli.PicocliCommandLineExecutor.executeSubCommand(PicocliCommandLineExecutor.java:72)
at dev.pp.commands.picocli.PicocliCommandLineExecutor.executeCommand(PicocliCommandLineExecutor.java:41)
at dev.pmlc.commands.PMLCommands.runCommand(PMLCommands.java:29)
at dev.pmlc.commands.Start.main(Start.java:20)
Please consider sending the above message to the developers of the application, so that this problem can be fixed.
[Finished in 1.7s]
Empty options should be acceptable, e.g. for procedurally generated documents which might or might not inject options into the node, and in any case PMLC should at the most produce a warning but still convert the rest of the document (if valid).
I noticed that with PMLC 3.1.0 I'm failing to render HTML Attributes for images alt
or title
text:
[image source="./apple.png" html_alt="Some text"]
[image source="./apple.png" html_title="Some text"]
both statements will just produce the following HTML snippet:
<figure style="text-align: left">
<img class="pml-image" src="./apple.png">
</figure>
As far as I can remember, both used to work fine in my previous tests with PML 2.x, and the html_alt
is even mentioned in the PML User Manual examples.
I haven't had a chance to test whether this is affecting just images or other elements too, but it definitely looks like a bug that crept in with the latest updates (either 3.0 or 3.1.0).
Add an attribute to the [title
node that allows excluding an heading from the TOC — something toc_exclude = true
, where the default would be false
, or toc_include
if that's more inline with the way attributes are defined.
This is inspired by AsciiDoc's discrete headings, which can be enabled via the discrete
attribute on any heading:
[discrete]
== Discrete Heading
In Asciidoctor a discrete heading is still generated as an heading tag (<h1>
..<h6>
), but it's excluded from the TOC, and furthermore:
A discrete heading is declared and styled in a manner similar to that of a section title, but:
- it’s not part of the section hierarchy,
- it can be nested in other blocks,
- it cannot have any child blocks,
- it’s not included in the table of contents.
The above points are important in Asciidoctor, because with real headings you can't skip levels (e.g. jump from <h1>
to <h3>
) or use headings inside blocks (e.g. a quotation block, etc.).
As for PML, I think that the goal should be to simply exclude these headings from the TOC generation and computation process (i.e. as if the discrete headings were simply not there).
It might be worth considering whether any child headings of a discrete heading should be computed or not in the TOC. E.g. the problem is that by excluding a Level-2 heading via discrete, if that section has sub-sections then all the sub-headings would need to be manually set as discrete
too, otherwise there would be a level-gap in the final TOC, where the discrete heading results in a direct jump from Level-1 to Level-3 because it's not being considered in the TOC generation. Unless the TOC ends up considering the next [ch
node as being Level-2 (since in PML chapter nodes don't contain level info, but the level is deduced from their nesting level), which probably doesn't make sense.
So, probably it makes more sense to consider any children of a discrete heading as being discrete too, otherwise the computation of nested TOC levels gets all out of synch.
In any case, this needs to be considered because PML differs from other lightweight markups in this respect, where AsciiDoc and Markdown headings contain in themselves their heading-level info (=
, ==
) whereas in PML is the actual nesting in the final document tree that determines their level.
Pleas inject into default CSS styles the version number of the pmlc
tool that generated them, i.e. within the stylesheets commented header, at the beginning.
This might be a safer practice, in case end users are manually modifying copies of these CSS files for substituting the default CSS generated by pmlc
. Having pmlc
version info might warn end users of possible changes in class names or the HTML template structure.
PMLC 3.1.0 | Windows 10 (x64)
The PML source line:
[list (html_style="list-style-type:decimal" html_start=3)
caused the following PARSER_EVENT_HANDLER_ERROR
crash error:
pmlc p2h pandoc.pml
ERROR:
Message An error occurred in the parser's event handler.
Code [list (html_style="list-style-type:decimal" html_start=3)
^
Location pandoc.pml (OMITTED_PATH\pandoc.pml)
Line 113, column 58
Error id PARSER_EVENT_HANDLER_ERROR
Cause:
The operation has been aborted due to the following unexpected application error:
java.util.ConcurrentModificationException
at java.base/java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:756)
at java.base/java.util.LinkedHashMap$LinkedValueIterator.next(LinkedHashMap.java:783)
at dev.pmlc.core.parser.PMLParserEventHandler.setHTMLAttributes(PMLParserEventHandler.java:410)
at dev.pmlc.core.parser.PMLParserEventHandler.setAttributes(PMLParserEventHandler.java:332)
at dev.pmlc.core.parser.PMLParserEventHandler.onAttributes(PMLParserEventHandler.java:262)
at dev.pmlc.core.parser.PMLParserEventHandler.onAttributes(PMLParserEventHandler.java:48)
at dev.pdml.core.parser.PDMLParser.parseAttributes(PDMLParser.java:281)
at dev.pdml.core.parser.PDMLParser.requireNode(PDMLParser.java:150)
at dev.pdml.core.parser.PDMLParser.parseChildNodes(PDMLParser.java:296)
at dev.pdml.core.parser.PDMLParser.requireNode(PDMLParser.java:159)
at dev.pdml.core.parser.PDMLParser.parseChildNodes(PDMLParser.java:296)
at dev.pdml.core.parser.PDMLParser.requireNode(PDMLParser.java:159)
at dev.pdml.core.parser.PDMLParser.parseChildNodes(PDMLParser.java:296)
at dev.pdml.core.parser.PDMLParser.requireNode(PDMLParser.java:159)
at dev.pdml.core.parser.PDMLParser.parseChildNodes(PDMLParser.java:296)
at dev.pdml.core.parser.PDMLParser.requireNode(PDMLParser.java:159)
at dev.pdml.core.parser.PDMLParser.requireRootNode(PDMLParser.java:107)
at dev.pdml.core.parser.PDMLParser.parse(PDMLParser.java:84)
at dev.pdml.core.parser.PDMLParser.parsePDMLReader(PDMLParser.java:71)
at dev.pmlc.core.parser.PMLParser.parseReaderWithoutThrowingIfNonCancellingErrorDetected(PMLParser.java:97)
at dev.pmlc.core.parser.PMLParser.parseReader(PMLParser.java:65)
at dev.pmlc.commands.pmltohtml.PMLToHTMLCommand$Executor.execute(PMLToHTMLCommand.java:112)
at dev.pmlc.commands.pmltohtml.PMLToHTMLCommand$Executor.execute(PMLToHTMLCommand.java:39)
at dev.pp.commands.command.CommandExecutor.execute(CommandExecutor.java:17)
at dev.pp.commands.command.FormalCommand.execute(FormalCommand.java:159)
at dev.pp.commands.picocli.PicocliCommandLineExecutor.executeSubCommand(PicocliCommandLineExecutor.java:72)
at dev.pp.commands.picocli.PicocliCommandLineExecutor.executeCommand(PicocliCommandLineExecutor.java:41)
at dev.pmlc.commands.PMLCommands.runCommand(PMLCommands.java:29)
at dev.pmlc.commands.Start.main(Start.java:20)
Please consider sending the above message to the developers of the application, so that this problem can be fixed.
See also my recent bug report about other problems with HTML attributes handling: #90
Christian, it would be nice to have dedicated options in PMLC to open up a bundled version of the PML Reference Manual and PML User Manual, respectively, which always matches the PMLC version.
Since the online version of these docs don't always match the latest release, and because end users might be sticking to a specific (older) version of PML for their work, it would be a great service to grant quick access to local copies of the docs, matching the exact PMLC version being used.
I'm aware that the PML package does contain the PML Reference Manual sources (but not the PML User Manual) and that users could build the document themselves in a few steps, but having a PMLC option to open up both docs in the browser would be a much easier way to go about it.
Something like:
pmlc userman
pmlc refman
Hi Christian (@pml-lang),
I noticed that the online version of the manual was generated by PML 1.2.0 and that one of the differences from the current 1.3.0 version is that tag has a closing "/" character.
As a further enhancement, in terms of accessibility, it is recommended that each image has a text alternative. Even in cases where there is no valid alternative, an empty alt tag is still recommended.
In the PML Reference Manual, in the section for the image node, there are attributes for captions, node title, etc. but nothing for alternative text. Should this be included? Could alt=""
be added as a default value for this attribute of the tag?
Kind Regards,
Liam
Currently the PMLC generated JSON provides a "type"
key with a value either "block"
or "inline"
. That's great, and it should be kept as is.
But for mustache templates processing, it would be very useful to also have two new boolean keys representing the node type:
"is_block_type"
"is_inline_type"
where (obviously) one will always be true
and the other false
.
The rationale for this addition is that mustache is logic-less, so it can't filter tags by comparing their values against expected values, but only filter them by boolean states true
/false
or null
/non-null.
Having these (redundant) keys would allow mustache template to filter tags according to types, without having to introduce Lambdas (which would render templates language-specific).
I know that having these redundant keys is not DRY, but hopefully it won't hurt either — after all, this auto-generated JSON document has a wide range of potential uses, ranging from tools that fully parse the JSON file to carry out complex operations, down to simpler uses like mustache templates, which operate at a simpler level.
The current "type"
key is still useful in mustache templates, e.g. when generating a markdown table resuming all nodes proprieties, where it can be used to fill-in the cells of a "node type" column with either "block" or "inline". Whereas the proposed boolean keys would be used to produced filtered tags list, i.e. showing all tags of either block or inline type.
This principle of having a double standard in the generated JSON file, i.e. both a key+value and boolean variants thereof holds true for any PML node/tag/attribute which might be worth filtering — obviously, within reason, since if the possible values are in excess of three or four variants it might involve too many additional boolean keys to represent them in a filterable way.
Hopefully, the size of the JSON file shouldn't really matter, since it's intended for machine-processing rather than human consumption, and as long as the newly requested keys are easy to handle on the PMLC code generator side it should be fine.
Now that PML has grown mature, I'm seeing how the autogenerated JSON file is starting to become increasingly useful in a wide range of applications — from self-updating reference documents in lightweight markup languages, to syntax highlighter and editor syntax templates.
Each tool and application domain will probably focus on specific keys, ignoring the rest, so having too many keys/entries shouldn't be a problem either. Again, which keys are "important" is relative to the task at hand.
It's one of these tools that it's either very useful or totally useless, depending on the context, and in the case of mustache templates the lack of boolean alternative keys for filtering tags can make a huge difference in the usability of the JSON file.
So I guess that as time goes by, we'll be seeing more needed keys additions, based on new real case uses.
The line An [c\[admon] block
raises a conversion error:
Error: 'c\' is an invalid node tag.
Forcing to change the line to An [c \[admon] block
.
I would expect the pmlc
parser to consider any invalid token ID character (i.e. [^a-z_]
) as a word boundary, making it unnecessary to insert a space when a tag is followed by an escape, the [
of a nested node, etc.
At least, this is how I've implemented most tags in Sublime PML, where nodes are usually captured via a RegEx like (?<!\\)\[c\b
. This seems the natural way to handle opening node tags, for it will cover all sort of contexts — e.g. the tag being followed by spaces, tabs, or even a new line:
Some [c
inline
code
]
which is perfectly valid PML code.
In any case, these details are important to know to correctly implement editor syntaxes that correctly mimic pmlc
's behaviour — as the saying goes, "The devil is in the details".
Hi Christian (@pml-lang),
I was checking the PML User Manual on my mobile phone and found that the Table of Contents was not appearing correctly. Several words were being cut-off as seen in the screenshots below.
To see this effect using Firefox on my desktop, I went into Developer Tools and selected the Responsive Design Mode icon over on the top-right of the panel:
The alternative method is to select the Web Developer option from the "burger" menu, which gives these options:
In Responsive Design Mode, several Device Settings are available in the drop-down. For example:
Other device settings can be chosen by using the "Edit List..." option at the bottom of the drop-down.
The Galaxy S9/S9+ view in Landscape mode gives this:
The iPhone 6/7/8, again in Landscape mode, has a similar problem:
I know little about responsive design or how the CSS, perhaps, might have an impact on the layout of the page. In any case, the default HTML / CSS might need to be reviewed for how the Table of Contents is displayed on various mobile platforms.
Kind Regards,
Liam
I've just downloaded PML v2.1.0 (for Windows), but after installation I get v2.0.0:
$ pmlc -version
PML version: 2.0.0 2021-09-03
Although the PML Changelog mentions v2.1.0 being a bug fix release, the date is supposed to be 2021-09-09, so it looks like I've downloaded again v2.0.0.
Where can I get the installer for v2.1.0?
While experimenting nodes-nesting with PML 2.3.0
I came across a fatal error when a [text
node is nested within a [title
node.
Trying to convert the following source document:
[doc [title Error Sample]
[ch [title Title With [text Text] Node ]]
]
results in the following error:
THE FOLLOWING APPLICATION ERROR OCCURRED (2022-07-27T04:36:09.8544301):
Should never be called
See file 'D:\some_path\errors.log' for more information.
[Finished in 1.2s]
THE FOLLOWING APPLICATION ERROR OCCURRED (2022-07-27T04:36:09.8544301):
Error : Should never be called
Location : Factory PML_text_node_creator.create_node (dev.pml.converter.tree_creator.node_creator.creators.inline_n
ode.text)
line 9
Time : 2022-07-27 04:36:09
Info : Should never be called
Trace:
> Factory PML_text_node_creator.create_node, line 9 (dev.pml.converter.tree_creator.node_creator.creators.inline_node.text)
> Factory PML_tree_creator.create_inline_child_nodes, line 412 (dev.pml.converter.tree_creator)
> Factory PML_tree_creator.create_node_creator_context, line 92 (dev.pml.converter.tree_creator)
> Factory PML_tree_creator.create_block_child_nodes, line 257 (dev.pml.converter.tree_creator)
> Factory PML_tree_creator.create_node_creator_context, line 97 (dev.pml.converter.tree_creator)
> Factory PML_tree_creator.create_block_child_nodes, line 257 (dev.pml.converter.tree_creator)
> Factory PML_tree_creator.create_node_creator_context, line 97 (dev.pml.converter.tree_creator)
> Factory PML_tree_creator.try_create_tree_2, line 56 (dev.pml.converter.tree_creator)
> Factory PML_tree_creator.try_create_tree, line 17 (dev.pml.converter.tree_creator)
> Service PML_to_HTML_Converter.try_create_HTML_file, line 106 (dev.pml.converter)
> Service PML_to_HTML_Converter.try_convert, line 29 (dev.pml.converter)
> Service PML_convert_command.execute, line 210 (dev.pml.converter.PAIOM_commands)
> Service PML_convert_command.execute, line 165 (dev.pml.converter.PAIOM_commands)
> Factory single_command_executor.execute_command, line 11 (org.ppl.paiom.config.execution.single_command_executor)
> Service execute_command_meta_command.execute_command, line 102 (org.ppl.paiom.meta_commands.commands.execute_command)
> Factory paiom.execute_meta_command, line 156 (org.ppl.paiom)
> Factory paiom.execute_command_from_string_data_2, line 87 (org.ppl.paiom)
> Factory paiom.execute_command_from_string_data, line 43 (org.ppl.paiom)
> Factory paiom.execute_command_from_command_line_arguments, line 14 (org.ppl.paiom)
> Service PAIOM_command_executor.execute_command_line_arguments, line 18 (org.ppl.paiom)
> Service PAIOM_command_executor.execute_command_line_arguments_2, line 35 (org.ppl.paiom)
> Service PAIOM_command_executor.execute_command_line_arguments_3, line 60 (org.ppl.paiom)
> Service CLI_start.execute_command_line_arguments, line 72 (dev.pml.converter)
> Service CLI_start.start, line 34 (dev.pml.converter)
> Service start.start, line 10 (dev.pml.converter)
I wanted to verify which kind of nodes can be used within a [title
, so I tried nesting various block nodes to see which errors they would produce.
So far, it seems that only the [text
node results in PMLC failure, all the other block nodes I've tried failed with a meaningful error message, and even non-existing node (e.g. [xyz
fail gracefully), so it seems to be a problem specific to [text
nodes.
BUG: ID pattern mentioned in PDML and PML differ!
PDML: [a-zA-Z_][a-zA-Z1-9_\.-]*
PML: [a-zA-Z][a-zA-Z0-9_-]*
@pml-lang, in #56 you mentioned:
Yes. To cover all cases, the plugin should use the regex shown in the PDML Specification:
[a-zA-Z_][a-zA-Z1-9_\.-]*
which prompted me to check the PML docs on how ID patterns are defined, and I immediately noticed that in the PML Manual and PML Reference whenever the custom ID pattern is mentioned it's: [a-zA-Z][a-zA-Z0-9_-]*
and not [a-zA-Z_][a-zA-Z1-9_\.-]*
— i.e.:
\.
mentioned in the PDML Specification is missing)._
according to PDML (but not PML).The same when invoking PMLC for tags info:
> pmlc ti -t admon
Admonition
----------
Tag : admon
[...]
Attributes:
1.
Id : id
Title : Node Identifier
Type : string or null
Description : A unique identifier for the node.
[...]
Note for programmers: The regex of an identifier is: [a-zA-Z]
[a-zA-Z0-9_]*. Identifiers are case-sensitive.
So which one is correct? the one with the .
and _
or the one without them?
It would be useful to have an inline node for keystrokes, to generate the <kbd>
HTML tag.
Possible node tags: [key
or just [k
.
Example:
[k Ctrl] [k Shift] [k Z]
which would be rendered as:
Ctrl Shift Z
with HTML code:
<kbd>Ctrl</kbd> <kbd>Shift</kbd> <kbd>Z</kbd>
(see below for an alternative node syntax)
Note that in the above example I've inserted spaces between the keys, but many people don't, while others insert the +
symbol:
[k Ctrl][k Shift][k Z]
[k Ctrl]+[k Shift]+[k Z]
rendered as:
CtrlShiftZ
Ctrl+Shift+Z
... it's a matter of personal taste, but it should be kept into account in the implementation.
Also, not how Asciidoctor implements it via the Keyboard Macro:
kbd:[Ctrl+Shift+Z]
(rendered as: Ctrl+Shift+Z)
It's smart because it uses just one keyword to handle multiple keys, using +
as a separator (two pluses + +
will produce the +
key).
So PML could also do that, and instead of the above proposed implementation, could instead:
[k Ctrl+Shift+Z]
For some nice styling of the keys via ready-to-us CSS stylesheets, see:
IMO, the first link offers the best CSS effects for keys, and also provided different styles.
The second on is beautiful looking, but maybe not so practical for inline styling (keys are too big).
I propose a "simulated run" option that will show the results of a command without truly executing it. Hypothetical example:
Normal run:
pmlc convert --input_file "$inputFilePath" --output_directory "$outputFolderPath"
Simulated run:
pmlc convert --input_file "$inputFilePath" --output_directory "$outputFolderPath" --simulate
The new argument would look like this:
Id : simulate
Title : Simulate
Type : yes_no
Description : If this parameter is set to 'yes' then:
- the output directory is not generated if it doesn't already exist
- no files are copied to the output directory
- the intended changes are revealed to the console output
By default this parameter is set to 'no'.
Required : no
Default value : no
Examples : --simulate
The simulated run can show the intended changes to the generated output, similar to Ansible's --check
or --diff
argument or Terraform's plan
command.
An alternatve implementation might be like Terraform's --auto-approve
option, wherewith the intended changes are revealed, and the executable by default pauses for user input ("Do you want to continue?") before applying the changes, with the auto-approve
argument overriding that behavior to not pause.
The console output might also helpfully reveal the locations of the output_directory
, resources_directory
, etc. as they will appear on your file system after the command is run for real. This in turn can help you know whether your arguments are set correctly. Sample output might include this information, for instance:
Input file : my project/my input file.pml
Input file resolves to : /home/user/my workspace/my project/my input file.pml
Output directory : ../../my generated HTML
Output directory resolves to : /home/user/my generated HTML/
Resources directory : null
Resources directory resolves to : (not generated: resource references will be dangling) <-- (bad wording on my part, but you get the idea)
For inspiration by similarity, see also pmlc command_info --command convert
which appears to dynamically show certain "default values" as resolved relative to your file system:
2.
Id : HTML_header, html_header, header
Type : absolute_or_relative_file_path or null
Required : no
Default value : /home/user/myapps/PML/pml-to-html-converter_1.5.0-1_amd64/lib/runtime/resources/html/default_html_header.txt
I've come across a very odd bug with PML 1.5.0...
The following source:
[doc title = PML BUGS Test \
authors = Tristano Ajmone \
date = 2021-06-26
[ch title = "Miscellanea" \
id = chapter_id
Hello
]
]
will produce an HTML doc where the Hello
paragraph is shown twice in a row — but only if:
id =
line and "Hello" line.]
.If the el
node begins with an open parenthesis, the compiler errs as below. What is the error message talking about when it says it expects a =
? Are parentheses special?
[el (some) text here]
Error: Expecting attribute assignment operator '='.
[el (some >>> ) text here]
Instead of writing a chain of multiple non-breaking-space [sp]
or newline [nl]
nodes:
[sp][sp][sp]
[nl][nl]
we could instead adopt a multiplier-style syntax to indicate node repetitions:
[sp*3]
[nl*2]
Usually when one needs to use the [sp]
node is because a single space is not enough, so this notation would allow to save space by using a single node to represent multiple spaces. Probably the need for multiple [nl]
nodes is less frequent, since it's usually employed just to hard-break within a paragraph, but there might be cases where multiple newlines are needed — and, in any case, it might be worth supporting this notation for both nodes, for consistency sake.
Although this notation doesn't align with the general PML syntax adopted so far, IMO it makes sense in this context due to its simplicity and inactivity — since it resembles the customary multiplication syntax it's very easy to remember.
Both of these nodes are childless and don't support any type of attributes, which might further justify this notation applying to them as an exception to the rule.
The only other context where a similar notation might make sense it's table cells, where the [tc]
node could adopt the x*y
notation to indicate columns and rows spanning — e.g. [tc 2*3]
for a cell spanning two columns and three rows; [tc 4*0]
/[tc 4*]
for spanning four columns; [tc 0*5]
/[tc *5]
spanning five rows, etc.; where a zero-value can be simply omitted, since the position of the other value in respect to the asterisk clearly indicates whether it refers to a column (lhs) or a row (rhs).
PMLC 3.1.0 | Win 10
According to documentation an ID must abide to the RE pattern:
[a-zA-Z_][a-zA-Z0-9_\.-]*
but if you try to compile the following document:
[doc [title ( id = "valid-ID " ) Quoted ID]]
the actual ID in the generated HTML includes the trailing spaces:
<h1 id="valid-ID " class="pml-doc-title">Quoted ID</h1>
PMLC should either (1) emit an error due to invalid ID definition, or (2) strip away the extra spaces from the final ID. IMO solution 1 is better because it enforces stricter documents.
I've come across this inconsistency while implementing quoted IDs in Sublime PML — originally I didn't add support for them, because I though no one would use them since IDs can't contain spaces, but then I noticed that the PML documentation frequently quotes IDs so I started to work on this feature.
Quoted IDs add various extra layers of complexity to editor syntaxes, because of the many edge cases that can encountered — e.g. if there isn't a closing quote on the same line, the syntax needs to gracefully recover so it doesn't break the whole document; along with other cases such as a valid ID followed by spaces, etc.
Whenever I work on a new syntax feature I always carry out some practical experiments with PMLC, just to check how the parser handles edge cases, so that I can find the right balance between how far Sublime PML can support edge cases and how PMLC handles them in real document conversion. This is how I came across this parser bug, i.e. by testing for edge cases handling.
I was quite surprised that such a parsing inconsistency/bug could have slipped by unnoticed, I would have expected the PMLC repository to have a test suite to cover IDs edge cases. Without a solid test suite it's going to be hard to ensure a linear and bug-proof growth of PML — even with Sublime PML, which is just an editor syntax, I wouldn't be able to work on it without covering each feature with extensive tests, to ensure that new features don't break previous ones.
Even though I'm not a Java expert, I know that Java has probably more test libraries than any other language out there, so it shouldn't be hard to add a solid test suite to PMLC.
Description
Immediate segfault on startup.
Reproducing
Download standalone pmlc binary v3.1.0.
Run pmlc
.
Expected vs actual behavior
Expect the app to run.
Actually segfaults.
Application version
PMLC v3.1.0 (standalone)
Your OS name and version
Arch Linux (Garuda)
Linux 5.18.3-zen1-1-zen #1 ZEN SMP PREEMPT_DYNAMIC Thu, 09 Jun 2022 16:14:13 +0000 x86_64 GNU/Linux
openjdk 18.0.1.1 2022-04-22
OpenJDK Runtime Environment (build 18.0.1.1+2)
OpenJDK 64-Bit Server VM (build 18.0.1.1+2, mixed mode)
Log
❯ pmlc
[ [ SubstrateSegfaultHandler caught a segfault in thread 0x000000000b3cec00 ] ]
siginfo: si_signo: 11, si_code: 1, si_addr: 0x00000000000000e5
Current timestamp: 1665367364174
General purpose register values:
RAX 0x0000000000000072 is an unknown value
RBX 0x000000000b3cefd0 is an unknown value
RCX 0x0000000000000000
RDX 0x0000000000000072 is an unknown value
RBP 0x00007f6eca5f42a0 is an unknown value
RSI 0x00007f6eca5f4481 is an unknown value
RDI 0x000000000b3cefd1 is an unknown value
RSP 0x00007fff735ac2c0 points into the stack for thread 0x000000000b3cec00
R8 0x00007f6eca5f449c is an unknown value
R9 0x0000000000000000
R10 0x0000000000001000 is an unknown value
R11 0x0000000000000246 is an unknown value
R12 0x00007fff735ac310 points into the stack for thread 0x000000000b3cec00
R13 0x000000000b3cf3cf is an unknown value
R14 0x0000000000000400 is an unknown value
R15 0x000000000b3cefd0 is an unknown value
EFL 0x0000000000010246 is an unknown value
RIP 0x00007f6eca830ec5 is an unknown value
Printing Instructions (ip=0x00007f6eca830ec5):
0x00007f6eca830ea5: 0x41 0x80 0x7d 0x00 0xff 0x0f 0x85 0xbc 0x00 0x00 0x00 0x48 0x8b 0x05 0xa1 0xfe
0x00007f6eca830eb5: 0x0b 0x00 0x49 0x0f 0xbe 0x17 0x4c 0x89 0xfb 0x64 0x48 0x8b 0x08 0x48 0x89 0xd0
0x00007f6eca830ec5: 0xf6 0x44 0x51 0x01 0x20 0x74 0x17 0x0f 0x1f 0x40 0x00 0x48 0x0f 0xbe 0x53 0x01
0x00007f6eca830ed5: 0x48 0x83 0xc3 0x01 0x48 0x89 0xd0 0xf6 0x44 0x51 0x01 0x20 0x75 0xed 0x84 0xc0
Top of stack (sp=0x00007fff735ac2c0):
0x00007fff735ac2c0: 0x00007f6e00000000 0x000000000b3cefd0
0x00007fff735ac2d0: 0x0000000000000400 0x00007f6eca5f42a0
0x00007fff735ac2e0: 0x000000000b3cd830 0x0000000000000400
0x00007fff735ac2f0: 0x00007fff735ac310 0x00007f6eca835d8d
0x00007fff735ac300: 0x0000000009734b40 0x00000000ca775bf3
0x00007fff735ac310: 0x0000000000000000 0x12f852641483b600
0x00007fff735ac320: 0x00000000000003e8 0x00000000000003e8
0x00007fff735ac330: 0x00007f6eca5f42a0 0x0000000009734b40
0x00007fff735ac340: 0x0000000000000400 0x000000000b3cefd0
0x00007fff735ac350: 0x00000000000003e8 0x00007f6eca836016
0x00007fff735ac360: 0x00007fff735ac3d8 0x000000000b3cd830
0x00007fff735ac370: 0x0000000003bed921 0x00000000000003e8
0x00007fff735ac380: 0x0000000000000400 0x0000000009734b40
0x00007fff735ac390: 0x00000000000003e8 0x000000000b3cefd0
0x00007fff735ac3a0: 0x000000000b3cd830 0x0000000003b77053
0x00007fff735ac3b0: 0xffffffffffffffb0 0x0000000000000000
0x00007fff735ac3c0: 0x0000000000000000 0x00007fff735ac430
0x00007fff735ac3d0: 0x00007f6ecb310918 0x000000000b3d05a0
0x00007fff735ac3e0: 0x00007f6eca835fc0 0x12f852641483b600
0x00007fff735ac3f0: 0x000000004e800000 0x00000000000003e8
0x00007fff735ac400: 0x0000000009734b40 0x0000000000000400
0x00007fff735ac410: 0x00007fff735ac430 0x00007f6ecb500000
0x00007fff735ac420: 0x000000000b3cec00 0x0000000003b76ddb
0x00007fff735ac430: 0x0000000043400000 0x12f852641483b600
0x00007fff735ac440: 0x0000000002717570 0x00007f6ece633cf8
0x00007fff735ac450: 0x00000000008cd5be 0x00007fff735ac480
0x00007fff735ac460: 0x00007f6ecb500000 0x00000000008cd5d1
0x00007fff735ac470: 0x00007fff735ac500 0x0000000002a2fe79
0x00007fff735ac480: 0x00000000008cd5be 0x00007fff735ac470
0x00007fff735ac490: 0x0000000000000000 0x00007f6ece646868
0x00007fff735ac4a0: 0x00007f6ecd4b1d50 0x00000000008b6896
0x00007fff735ac4b0: 0x000000100000000f 0x00007f6ecdf34798
DeoptStubPointer address: 0x000000000083b7b0
Top frame info:
Does not look like a Java Frame. Use JavaFrameAnchors to find LastJavaSP:
Found matching Anchor:0x00007fff735ac480
LastJavaSP 0x00007fff735ac470
LastJavaIP 0x00000000008cd5be
Threads:
0x00007f6ec4000b80 STATUS_IN_NATIVE (ALLOW_SAFEPOINT) "Reference Handler" - 0x00007f6ecde96138, daemon, stack(0x00007f6ecab01000,0x00007f6ecb300000)
0x000000000b3cec00 STATUS_IN_JAVA (PREVENT_VM_FROM_REACHING_SAFEPOINT) "main" - 0x00007f6ecde96080, stack(0x00007fff72db1000,0x00007fff735ae000)
VM thread locals for the failing thread 0x000000000b3cec00:
0 (8 bytes): JNIThreadLocalEnvironment.jniFunctions = (bytes)
0x000000000b3cec00: 0x00007f6ecd8b5010
8 (8 bytes): SubstrateFastThreadLocal.CONTEXT = (Object) null
16 (8 bytes): SubstrateThreadLocalHandshake.STATE = (Object) null
24 (8 bytes): StackOverflowCheckImpl.stackBoundaryTL = (Word) 1 (0x0000000000000001)
32 (4 bytes): Safepoint.safepointRequested = (int) 2147449334 (0x7fff79f6)
36 (4 bytes): StatusSupport.statusTL = (int) 1 (0x00000001)
40 (4 bytes): SubstrateThreadLocalHandshake.PENDING = (int) 0 (0x00000000)
48 (32 bytes): ThreadLocalAllocation.regularTLAB = (bytes)
0x000000000b3cec30: 0x00007f6ecb300000 0x00007f6ecb400000
0x000000000b3cec40: 0x00007f6ecb320ae0 0x0000000000000000
80 (8 bytes): PlatformThreads.currentThread = (Object) java.lang.Thread (0x00007f6ecde96080)
88 (8 bytes): JavaFrameAnchors.lastAnchor = (Word) 140735128716416 (0x00007fff735ac480)
96 (8 bytes): AccessControlContextStack = (Object) java.util.ArrayDeque (0x00007f6ecb302298)
104 (8 bytes): ExceptionUnwind.currentException = (Object) null
112 (8 bytes): IdentityHashCodeSupport.hashCodeGeneratorTL = (Object) java.util.SplittableRandom (0x00007f6ecb308258)
120 (8 bytes): IsolatedCompileClient.currentClient = (Object) null
128 (8 bytes): IsolatedCompileContext.currentContext = (Object) null
136 (8 bytes): JNIObjectHandles.handles = (Object) com.oracle.svm.core.handles.ThreadLocalHandles (0x00007f6ecb3011f0)
144 (8 bytes): JNIThreadLocalPendingException.pendingException = (Object) null
152 (8 bytes): JNIThreadLocalPinnedObjects.pinnedObjectsListHead = (Object) null
160 (8 bytes): JNIThreadOwnedMonitors.ownedMonitors = (Object) null
168 (8 bytes): NoAllocationVerifier.openVerifiers = (Object) null
176 (8 bytes): ThreadingSupportImpl.activeTimer = (Object) null
184 (8 bytes): SubstrateDiagnostics.threadOnlyAttachedForCrashHandler = (bytes)
0x000000000b3cecb8: 0x0000000000000000
192 (8 bytes): ThreadLocalAllocation.allocatedBytes = (Word) 0 (0x0000000000000000)
200 (8 bytes): VMThreads.IsolateTL = (Word) 140113834147840 (0x00007f6ecb500000)
208 (8 bytes): VMThreads.OSThreadHandleTL = (Word) 188536960 (0x000000000b3cd880)
216 (8 bytes): VMThreads.OSThreadIdTL = (Word) 188536960 (0x000000000b3cd880)
224 (8 bytes): VMThreads.StackBase = (Word) 140735128723456 (0x00007fff735ae000)
232 (8 bytes): VMThreads.StackEnd = (Word) 140735120347136 (0x00007fff72db1000)
240 (8 bytes): VMThreads.StartedByCurrentIsolate = (bytes)
0x000000000b3cecf0: 0x0000000000000000
248 (8 bytes): VMThreads.nextTL = (Word) 0 (0x0000000000000000)
256 (8 bytes): VMThreads.unalignedIsolateThreadMemoryTL = (Word) 188541952 (0x000000000b3cec00)
264 (4 bytes): ActionOnExitSafepointSupport.actionTL = (int) 0 (0x00000000)
268 (4 bytes): ActionOnTransitionToJavaSupport.actionTL = (int) 0 (0x00000000)
272 (4 bytes): ImplicitExceptions.implicitExceptionsAreFatal = (int) 0 (0x00000000)
276 (4 bytes): StackOverflowCheckImpl.yellowZoneStateTL = (int) 2130640638 (0x7efefefe)
280 (4 bytes): StatusSupport.safepointBehaviorTL = (int) 1 (0x00000001)
284 (4 bytes): ThreadingSupportImpl.currentPauseDepth = (int) 0 (0x00000000)
No VMOperation in progress
The 15 most recent VM operation status changes (oldest first):
The 20 most recent RuntimeCodeInfo operations (oldest first):
RuntimeCodeInfoMemory contains 0 methods:
Recent deoptimization events (oldest first):
Counters:
Java frame anchors for the failing thread 0x000000000b3cec00:
Anchor 0x00007fff735ac480 LastJavaSP 0x00007fff735ac470 LastJavaIP 0x00000000008cd5be
Stacktrace for the failing thread 0x000000000b3cec00:
SP 0x00007fff735ac2c0 IP 0x00007f6eca830ec5 IP is not within Java code. Trying frame anchor of last Java frame instead.
SP 0x00007fff735ac470 IP 0x00000000008cd5be [image code] com.oracle.svm.core.posix.headers.Pwd.getpwuid(Pwd.java)
SP 0x00007fff735ac470 IP 0x00000000008cd5be [image code] com.oracle.svm.core.posix.PosixSystemPropertiesSupport.userHomeValue(PosixSystemPropertiesSupport.java:52)
SP 0x00007fff735ac4b0 IP 0x00000000008b6896 [image code] com.oracle.svm.core.jdk.SystemPropertiesSupport.userHome(SystemPropertiesSupport.java:239)
SP 0x00007fff735ac4b0 IP 0x00000000008b6896 [image code] com.oracle.svm.core.jdk.SystemPropertiesSupport$$Lambda$c08be315aa20ccffc6d99c8ceeebd4e4a45b68c0.get(Unknown Source)
SP 0x00007fff735ac4d0 IP 0x00000000008b6fb1 [image code] com.oracle.svm.core.jdk.SystemPropertiesSupport.initializeLazyValue(SystemPropertiesSupport.java:217)
SP 0x00007fff735ac510 IP 0x00000000008b6e63 [image code] com.oracle.svm.core.jdk.SystemPropertiesSupport.getProperty(SystemPropertiesSupport.java:170)
SP 0x00007fff735ac530 IP 0x000000000273b8d4 [image code] java.lang.System.getProperty(System.java:303)
SP 0x00007fff735ac550 IP 0x000000000265f512 [image code] dev.pp.basics.utilities.os.OSDirectories.<clinit>(OSDirectories.java:11)
SP 0x00007fff735ac580 IP 0x00000000007ea20b [image code] com.oracle.svm.core.classinitialization.ClassInitializationInfo.invokeClassInitializer(ClassInitializationInfo.java:361)
SP 0x00007fff735ac590 IP 0x00000000007e8a09 [image code] com.oracle.svm.core.classinitialization.ClassInitializationInfo.initialize(ClassInitializationInfo.java:277)
SP 0x00007fff735aca90 IP 0x000000000265a7ce [image code] dev.pp.basics.utilities.directory.DirectoryConfig.userDirectoryForApplication(DirectoryConfig.java:71)
SP 0x00007fff735acae0 IP 0x0000000002659234 [image code] dev.pp.basics.utilities.directory.DirectoryConfig.userConfigDirectoryForApplication(DirectoryConfig.java:58)
SP 0x00007fff735acb10 IP 0x000000000262eab0 [image code] dev.pmlc.ext.PMLCResources.<clinit>(PMLCResources.java:18)
SP 0x00007fff735acb40 IP 0x00000000007ea20b [image code] com.oracle.svm.core.classinitialization.ClassInitializationInfo.invokeClassInitializer(ClassInitializationInfo.java:361)
SP 0x00007fff735acb50 IP 0x00000000007e8a09 [image code] com.oracle.svm.core.classinitialization.ClassInitializationInfo.initialize(ClassInitializationInfo.java:277)
SP 0x00007fff735ad050 IP 0x00000000025e39b3 [image code] dev.pmlc.commands.Start.init(Start.java:31)
SP 0x00007fff735ad070 IP 0x00000000025e39f8 [image code] dev.pmlc.commands.Start.main(Start.java:14)
SP 0x00007fff735ad090 IP 0x00000000007d66a3 [image code] com.oracle.svm.core.JavaMainWrapper.runCore0(JavaMainWrapper.java:166)
SP 0x00007fff735ad0b0 IP 0x00000000007d6445 [image code] com.oracle.svm.core.JavaMainWrapper.runCore(JavaMainWrapper.java:130)
SP 0x00007fff735ad0b0 IP 0x00000000007d6445 [image code] com.oracle.svm.core.JavaMainWrapper.run(JavaMainWrapper.java:214)
SP 0x00007fff735ad0e0 IP 0x000000000082738b [image code] com.oracle.svm.core.code.IsolateEnterStub.JavaMainWrapper_run_5087f5482cc9a6abc971913ece43acb471d2631b(IsolateEnterStub.java:0)
VM mutexes:
mutex "mainVMOperationControlWorkQueue" is unlocked.
mutex "referencePendingList" is unlocked.
mutex "thread" is unlocked.
AOT compiled code is mapped at 0x0000000000403000 - 0x0000000003ae7bbf
Heap settings and statistics:
Supports isolates: true
Heap base: 0x00007f6ecb500000
Object reference size: 8
Aligned chunk size: 1048576
Incremental collections: 0
Complete collections: 0
Native image heap boundaries:
ReadOnly Primitives: 0x00007f6ecb601028 - 0x00007f6eccda6770
ReadOnly References: 0x00007f6eccda6770 - 0x00007f6ecd8b49d0
ReadOnly Relocatables: 0x00007f6ecd8b5000 - 0x00007f6ecdc96400
Writable Primitives: 0x00007f6ecdc97000 - 0x00007f6ecddb5c38
Writable References: 0x00007f6ecddb5c38 - 0x00007f6ecebe52c0
Writable Huge: 0x00007f6ecec00030 - 0x00007f6ececde7c8
ReadOnly Huge: 0x00007f6ececdf030 - 0x00007f6ed110ca80
Heap:
Young generation:
Eden:
edenSpace:
aligned: 0/0 unaligned: 0/0
Survivors:
Survivor-1 From:
aligned: 0/0 unaligned: 0/0
Survivor-1 To:
aligned: 0/0 unaligned: 0/0
Survivor-2 From:
aligned: 0/0 unaligned: 0/0
Survivor-2 To:
aligned: 0/0 unaligned: 0/0
Survivor-3 From:
aligned: 0/0 unaligned: 0/0
Survivor-3 To:
aligned: 0/0 unaligned: 0/0
Survivor-4 From:
aligned: 0/0 unaligned: 0/0
Survivor-4 To:
aligned: 0/0 unaligned: 0/0
Survivor-5 From:
aligned: 0/0 unaligned: 0/0
Survivor-5 To:
aligned: 0/0 unaligned: 0/0
Survivor-6 From:
aligned: 0/0 unaligned: 0/0
Survivor-6 To:
aligned: 0/0 unaligned: 0/0
Survivor-7 From:
aligned: 0/0 unaligned: 0/0
Survivor-7 To:
aligned: 0/0 unaligned: 0/0
Survivor-8 From:
aligned: 0/0 unaligned: 0/0
Survivor-8 To:
aligned: 0/0 unaligned: 0/0
Survivor-9 From:
aligned: 0/0 unaligned: 0/0
Survivor-9 To:
aligned: 0/0 unaligned: 0/0
Survivor-10 From:
aligned: 0/0 unaligned: 0/0
Survivor-10 To:
aligned: 0/0 unaligned: 0/0
Survivor-11 From:
aligned: 0/0 unaligned: 0/0
Survivor-11 To:
aligned: 0/0 unaligned: 0/0
Survivor-12 From:
aligned: 0/0 unaligned: 0/0
Survivor-12 To:
aligned: 0/0 unaligned: 0/0
Survivor-13 From:
aligned: 0/0 unaligned: 0/0
Survivor-13 To:
aligned: 0/0 unaligned: 0/0
Survivor-14 From:
aligned: 0/0 unaligned: 0/0
Survivor-14 To:
aligned: 0/0 unaligned: 0/0
Survivor-15 From:
aligned: 0/0 unaligned: 0/0
Survivor-15 To:
aligned: 0/0 unaligned: 0/0
Old generation:
oldFromSpace:
aligned: 0/0 unaligned: 0/0
oldToSpace:
aligned: 0/0 unaligned: 0/0
Unused:
aligned: 0/0
Segfault detected, aborting process. Use runtime option -R:-InstallSegfaultHandler if you don't want to use SubstrateSegfaultHandler.
Something is not right with Tables' headers in PML 2.3.0.
While HTML headers generated via [table_data
are as expected, the HTML generated via normal [table
nodes are not: header cells in the former are correctly assigned the pml-table-header-cell
class, whereas in the latter they are assigned the pml-table-body-cell
class, which makes the header cells look like normal cells.
You can see this even in the documentation examples, where you'll notice that the ordinary Table headers are not styles in bold.
@pml-lang, PML 4.0.0 now adopts the Delimited Text Syntax for raw-text blocks as the proper way to format raw-blocks (see also tajmone/Sublime-PML#40).
I've noticed that the PDML documentation mentions:
The closing delimiter line must contain at least as many delimiter characters as the opening delimiter line.
And I've tested it and discovered that in fact the closing delimiter can be longer than the opening delimiter, e.g.
[code
===============
print("Hello");
===================
]
I find this choice rather problematic and unconventional.
Usually markup syntaxes require that both delimiters are balanced (i.e. same characters and length), the reason being that it prevents issues in cases where the raw-text contains delimiters.
E.g. a PML listing block like this one requires that all delimiters in the raw-text are shorter than the enclosing block delimiters:
[code
====================
[code
===============
print("Hello");
===================
]
====================
]
Of course, the situation is manageable (one just needs to ensure that the outer delimiters are longer than any inner delimiters, or use different characters: "
or ~
), but I don't understand the benefits of supporting delimiters with unbalanced lengths.
Strictly balanced delimiters reduce the chances of clashes between the block delimiters and any raw-text contents that might cause a false positive match for the closing delimiter — especially when including long external listings via insert_code
directives.
Furthermore, as far as I can tell it's impossible to correctly implement support for different-length delimiters in most syntax packages for PML because they rely on RegEx backreferences ($1
or \1
) to match the same delimiter again — one could achieve this only by ignoring trailing characters, but the correct approach here would be to match the whole line, starting from the line-start anchor ^
up to the end-of-line $
:
^(?=( |\t)*["=~]{3,})
Ultimately, it seems to me that supporting unbalanced delimiters has little or no benefits, but is a potential source of problems for both end users and syntax maintainers.
Any specific reason why you decided to allow closing delimiters to be longer than the opening delimiter?
It would really great if Windows users could install the PML converter app via the Chocolatey package manager, which greatly simplifies updates since it can fully automate the process, from un-installing previous versions, to dealing with dependencies, the registry, etc.
Thanks to the official Chocolatey GUI app, it's even easier to install and update packages, without having to use the command line.
Chocolatey packages are usually hosted on GitHub, and being just PowerShell scripts its common practice to integrate these packages to their original project via automation tools that can update the PS scripts whenever a new version is released — it boils down to recreating the PS scripts with updated version info, links, etc., and then updating the package info on Chocolatey's website.
In my experience, Chocolatey packages are only worth using if they're created by the official maintainers of a project (third party packages often end up going stale when users loose interest in the app/package), especially because of the auto-generated updates offering a strong guarantee that each new product release will be followed immediately by its Choco package being updated.
Creating the initial package might require some reading, because there are tons of settings on Chocolatey, and different ways to handle silent installations, default settings, etc.
https://docs.chocolatey.org/en-us/create/
I've noticed that PML installation currently requires restarting Windows for the process to complete. This might be a problem with Chololatey, and I'm not sure if it can handle (or allows) this, because end users must be able to auto-update multiple packages at once.
I'm not well versed in PowerShell (and it's many incarnations), so I might not of great help here, but I'm willing to dig through the Chocolatey and PowerShell docs it this might help. IMO, it shouldn't be too hard to create a Choco package, but i might require some local testing before publishing, especially for the part concerning auto-updating the Choco files from the PML repository (via some CI service like Travis CI, Circle CI, or GitHub Actions) whenever a new tagged release is published.
But I believe that being able to offer a PML Chocolatey package would be a great incentive for end users, and it would ensure that they'll always have an up to date PML converter without having to go through the manual process.
Hi Christian(@pml-lang),
I have found that a [link
tag does not resolve correctly if a query string exists in the URL. I need to escape the =
sign for the link to appear correctly in the HTML output. Here is a working example:
The query string ?ref=
will not work if entered "as-is". A broken URL up to the question mark appears in the output. I'm guessing that why the =
needs escaping, is because the [link
tag is expecting the next parameter and is not checking that it is preceded by the text
attribute.
This is not a high priority issue since I have found a workaround.
Kind Regards,
Liam
In the generated pml_tags.json
, please remove the "date_time_created"
entry because its time-stamp value make the generated JSON file non-portable — i.e. in repositories which use automated scripts to generate the pml_tags.json
file, each time the JSON file is rebuilt it shows up in Git as changed, which can potentially block any toolchain Git operations that require a clean status.
Unless there are good reasons to preserve the time-stamp, it would be better to drop it (the PML version should suffice, for the same tags info should be generated for a same PML release, regardless of the timestamp of PMLC execution).
It would be far more useful to replace "date_time_created"
with a "release_date"
entry specifying when the current PML version was released (it would complement the "pml_version"
entry).
The following user-defined node
[node
[name timestamp]
[writer
[script
"""
context.write(new Date())
"""
]
]
]
yields the following error in PML 2.2.0 2021-12-14.
Running PMLC on the file "myfolder/Main.pml" ...
Error The following error occurred when a script was executed for node 'timestamp':
java.lang.ExceptionInInitializerError
Error id SCRIPTING_ERROR
-----------------------------------------------------------------------------------------------------------------------
THE FOLLOWING APPLICATION ERROR OCCURRED (2022-02-01T09:41:45.650332221):
Java throwable: org.graalvm.polyglot.PolyglotException: java.lang.ExceptionInInitializerError
See file 'myfolder/errors.log' for more information.
In version 1.5.0 some inline nodes don't collapse the end whitespace when written like this:
Here is a sentence (and "here is a quote"[sup
[xref node_id="my_footnote_28" text="28"]
]), and here is the rest of the sentence.
resulting in an extra space before the end of the node:
... is a quote"<sup class="pml-superscript"><a href="#my_footnote_28" class="pml-xref">28</a> </sup>), and here ...
The image
tag help says this about its source
attribute:
Description : The relative file path to the image file. The path is relative to the target HTML file.
Examples : source = images/ball.png
I get that source
translates directly to href
in the generated HTML anchor. However, I see a few problems here:
/workspace/doc.pml
to include an internal image /workspace/images/ball.png
would naturally expect the source
attribute to be relative to the source folder containing the PML file (or, less ideally, to the working directory where the converter is run), but certainly not to the target directory.source = "../../../workspace/images/ball.jpg"
) or else rely on hard-coded absolute paths (source = "/workspace/images/ball.jpg"
), neither of which is practical when the developer decides to deploy his HTML to a server or move it to another machine.image
tag represents not an image but only an image reference
, meaning any internal images must be deployed to the target outside the PML conversion process.I propose it would be more helpful, in the case of internal images, for said images to be bundled by the converter into the output directory, along with the HTML file and CSS. Then the source
attribute would be relative to the source directory instead of the target directory, a state that is much more in line with a common user's expectation of the proper usage of an image
tag in a compiled language. The same rationale extends to the video
and audio
tags as well.
Of course, this solution concerns only the case of internal images, not the case of external image references. Supporting both cases would perhaps necessitate a new attribute.
Please add a preprocessor option to pmlc
so that it's possible to create a standalone source document from a project that uses [insert
and [insert_code
directives and multiple files.
Possibly, there should also be a way to control whether [const
parameters should be expanded and replaced or whether they should be preserved in the pre-processed document generated via this option.
This option would come handy in various context, from someone wanting to release a document which is generated as part of a more complex toolchain, to the PML projects themselves, which could generate standalone sample docs and documentation files (for inclusion in releases, projects, etc.) without having to give up the power of [insert
and [insert_code
directives in their maintenance.
See also Ascidoctor's coalescer script (soon to become an official extension).
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.