Open BlakeTNC opened 8 years ago
@BlakeTNC thank you for taking the time to sketch this out. I can't speak to the code, but the design you describe would certainly work for the feature I sketched out in #1783. I am wondering if it would need to be implemented as TW5 core code or if it could be written as a plugin? This implementation would meet my needs fine. One thing I noticed is that in the JavaScript implementation in the dummy html file, there seems to be no way back to the TOC without creating another link back to TOC from the target. muscle memory wants to hit the back button to do it, but it doesn't leave a trace in browser history, obviously. automatically generating a link back to TOC for any header or other item picked up in the process of generating the TOC links would seem to be one possibility.
This proposal is an offshoot of the issue https://github.com/Jermolene/TiddlyWiki5/issues/1783 . However, I thought the proposal was different enough from the normal clamor for "Tiddler internal HTML anchors", that it deserved its own issue page. I also wanted to separate technical discussion from philosophy conversations. What I'm proposing is a replacement for the HTML anchor functionality, implemented with JavaScript. The full details and design specs are pasted below.
Original proposal message:
Hello all, I may have a plausible technical solution for internal links. Here is the problem defined by Jermolene.
"@Jermolene wrote: Hi @rcrath the problem isn't that I have a philosophical dislike for internal links. I also can't see a plausible implementation. As you've discovered, naive implementations clash with TiddlyWiki's existing permalink handling."
I researched and found a way to "re-implement" internal anchors without using the normal anchor mechanism (Without using the pound symbol #, and without changing the current browser URL.)
A normal HTML anchor allows you to click on a text link, and the browser window will adjust the scrollbar until a text target is at the top of the browser window. There is a JavaScript method to accomplish this same task, called
scrollIntoView()
. I made a small HTML file to demonstrate how this method can be employed to re-implement the "anchor" functionality. The example is pasted below. To see how it works, copy the HTML text into a text file, save it on your computer with the extension HTML, and open that file in your browser. From my research, the used JavaScript method is implemented by all major browsers.Here is one design for how this feature could be implemented into the TiddlyWiki core.
!Heading 1
), are rendered with an added ID string so that they can function as JavaScript anchor targets. Example:<h1 id="AnchorIdentifier">Heading 1</h1>
.[anchor-link[Pretty Title|Heading 1]]
[external-anchor-link[Pretty Title|Tiddler Name|Heading 1]]
<<anchor "Anchor Name">>
which becomes:<span id="AnchorIdentifier"></span>
(ordiv
instead ofspan
, or whatever works).Limitations: Such JavaScript anchors could not be used to create "anchored bookmarks", because they're not part of the page URL. The anchor links would only work from within TW.
Internal Table of Contents: Once internal anchors are implemented, it would be possible to also implement an "internal table of contents" macro. This macro would automatically insert a table of contents at the top of a Tiddler, based on any headers that exist in the same Tiddler. Clicking on any item in the table of contents would scroll to that header in the Tiddler.
Warm regards BlakeTNC
Algorithm for generating the necessary header and anchor target identifiers:
I've been thinking about the implementation details of the proposal, and I want to address a particular design issue. (Original proposal here: https://github.com/Jermolene/TiddlyWiki5/issues/1783#issuecomment-179561486 )
That the below text will not make much sense unless you have read the original proposal. (It still may not make much sense unless you are a programmer!)
The biggest issue I see in implementing "JavaScript anchors" is how to choose the ID strings for the headers (or manually inserted anchor targets). The ID strings will need to meet various specifications and restrictions. These include:
Considering only the restrictions discovered so far, the actual restrictions on ID strings for this usage appear to be few (from the current research), but I would say it would be common programmer sense to avoid things like new lines, angle brackets, quotation marks, and just to be conservative, probably to avoid special characters in general. It's also worth noting that although "unique" IDs are requested by HTML 5 and JavaScript, they are not required. If getElementById() is called on a non-unique ID, it will just find the first one on the page. Therefore, I think the burden of uniqueness should be placed on the user... It is their job to make sure their header text or manual anchor target names are reasonably unique. Although it is the programmers job to make sure that anchor id tags do not conflict with unrelated id tags used by TW.
Based on all those requirements, I would suggest the following deterministic algorithm for creating ID strings from header strings: (Java pseudocode is used to describe the algorithm.)
You'll need a JavaScript hashcode function to implement the below algorithm. A good, short one is found at this link. http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/
Unless I have missed something, the above algorithm will:
Considerations for user generated anchor links: If the user wants to create a manual anchor link to a specific anchor target (By using the syntax [anchor-link[Pretty Title|Heading 1]] from the original proposal), they will not need to know the generated ID tag. They will only need to know the text of the header or anchor target that they wish to link to. To put that another way, users never need to know the output of this algorithm. They only need to know the input of the algorithm. TW would convert their input text into the matching anchor ID tag whenever it parses the "anchor-link" syntax element.
PS, My JavaScript skills are poor, or I would have presented the algorithm in JavaScript, or just implemented this anchor proposal myself. Since JavaScript is not my native programming language, I thought I would be of greater use by providing a very detailed implementation plan, so that the required effort on any developer who wishes to implement these anchors will be as minimal as I can make it.
Now that the issue of what to use for ID tags has a workable solution, I don't forsee any technical blockers to implementing these anchors. Please let me know if you discover any design issues that I have not anticipated.
Warm regards, BlakeTNC