Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide controls to change text direction and alignment #121

Open
alibghz opened this issue Mar 13, 2019 · 14 comments
Open

Provide controls to change text direction and alignment #121

alibghz opened this issue Mar 13, 2019 · 14 comments
Assignees

Comments

@alibghz
Copy link

alibghz commented Mar 13, 2019

In a multilingual nodebb forum which users may post in both right-to-left and left-to-right languages or use a ltr/rtl theme by their preferences, having no control on selecting proper text direction and alignment is so displeasing!

It would be nice if you could add some controls in the top-side toolbar so the users can specify the proper direction and/or alignment of texts they are posting.

@pitaj
Copy link
Contributor

pitaj commented Mar 13, 2019

Please provide a few examples of the text alignment issues you're referring to.

@alibghz
Copy link
Author

alibghz commented Mar 13, 2019

Here is an example that user selected Persian language form his/her settings and the theme direction is changed to rtl.

image

Persian text looks fine in this situation but the English text not.

image

Now, if a user has the English language selected, English text looks fine but the Persian text not.

image

image

@alibghz
Copy link
Author

alibghz commented Apr 23, 2019

As a quick/temporary solution, I used below custom javascript and css codes in my nodebb forum to set auto direction and text alignment.

Custom Javascript:

(function(window) {
//https://github.com/kavirajk/isRTL/blob/master/isRTL.js with minor changes
var reRTL, rtlChars;

rtlChars = [
	/* arabic ranges*/
	'\u0600-\u06FF',
	'\u0750-\u077F',
	'\uFB50-\uFDFF',
	'\uFE70-\uFEFF',
	/* hebrew range*/
	'\u05D0-\u05FF'
].join("");

reRTL = new RegExp("[" + rtlChars + "]", "g");

window.isRTL = function(text) {
	try{
		return (text.replace(/[0-9\s\\\/.,\-+="']/g, '')[0].match(reRTL) || []).length > 0;
	}catch(e){}
	return false;
};

})(window);

(function(window) {
window.setAutoDir = function() {
	$('.content p:not(.auto-dir)').each(function(){var elm = $(this); if(isRTL(elm.text())){elm.addClass('auto-dir auto-dir-rtl')}else{elm.addClass('auto-dir auto-dir-ltr')}})
	$('.content ul>li:not(.auto-dir)').each(function(){var elm = $(this); if(isRTL(elm.text())){elm.addClass('auto-dir auto-dir-rtl')}else{elm.addClass('auto-dir auto-dir-ltr')}})
}
})(window);

setAutoDir();

Custom CSS/LESS:

.topic .content pre{
    direction: ltr;
    text-align: left;
}

.auto-dir-rtl{
    direction:rtl;
    text-align:right;
}

.auto-dir-ltr{
    direction:ltr;
    text-align:left;
}

It works fine for the loaded elements but when the page loads new elements (posts, etc) it will not be applied to them.

@akhoury akhoury self-assigned this Apr 24, 2019
@akhoury
Copy link
Member

akhoury commented Apr 25, 2019

so, @alibghz are you looking to mix rtl and ltr in the same post content? or is the ask to switch the whole post content to either rtl or ltr?

if we want to support to mixing within the same post, then we need to wrap some content with html tags,

Also, re: alignment, alignment isn't necessarily coupled with the direction, I mean, sure by default
when you read rtl it's usually on the right of the "container" to its left, but it could well be on the left and still read rtl, all I'm saying that this is another feature and should be controlled by a different button or buttons and it would also require wrapping with html tags

@akhoury
Copy link
Member

akhoury commented Apr 25, 2019

also, mixed directions won't work if HTML is not allowed in the markdown plugin, as well as the alignment feature, markdown doesn't really support alignment.

@alibghz
Copy link
Author

alibghz commented Apr 26, 2019

@akhoury, actually, I am looking to mix rtl and ltr in the same post content.

Considering this forum and topic with default theme, all posts' contents are rendered in ltr and of course left-aligned despite they are in Persian or English. now if some users select fa-IR in their settings, they see the content in rtl and right-aligned .

By exploring the post content code in developer tools, we figure out it consists of some p , ul and li tags.

image

Now, I think we need to detect text direction based on first strong Unicode character of each paragraph or list item and set the default direction and alignment for those tags, so, the theme's setting does not change the post content direction and reading problem will be solved.

Adding controls in the editor to change direction and alignment would be a good option but I think it cannot solve the old posts problem since they need to be edited again. Anyway, it is a nice feature for future posts.

@akhoury
Copy link
Member

akhoury commented Apr 26, 2019

I think I may have found a way to even have the old posts display correctly as well.

@julianlam im documenting findings here

In @julianlam 's nodebb-plugin-markdown, where updateParserRules is called we can do two things, either together or choose one

1st

This will add an attribute dir="auto" to every token, this will automatically fix many of the wrongly displayed posts, along with the preview panel in the composer, the only issue here, is that since you want to mix direction, there is nothing we can do about the textarea (at least nothing too drastic without writing our own "text area" editor), but this should work a good amount of the time, well not on browsers that don't support HTML5

parser.use(function (md) {
			md.core.ruler.before('linkify', 'autodir', function (state) {
				state.tokens.forEach(function (token) {
					token.attrJoin('dir', 'auto');
				});
			});
		});

2nd

     // Add support for attributes
     parser.use(require('markdown-it-attrs'));

This will add support for attributes to tokens, so we can then use something like

# hello world { style="text-align:center"} 

to align this, we can even add left/center/right buttons for alignment, if we do this, we can even add overrides to the dir attributes we added above

# hello world {dir="rtl"} 

I tested both approaches, they work, although the second one isn't really markdown, it's just a made up syntax inspired from http://pandoc.org/MANUAL.html#extension-header_attributes and the first one is adding an attribute to each token, I don't know if this not that bad, bad or really bad

@akhoury
Copy link
Member

akhoury commented Apr 26, 2019

here's a screenshot
Screen Shot 2019-04-26 at 8 41 09 PM

@julianlam
Copy link
Member

@akhoury thanks for implementing option #1. I am not as enthusiastic about adding markdown-it-attrs because it introduces complexity that should be avoided.

There are character codes to switch from LTR to RTL and vice versa, right? Could these not be detected and adjusted automatically?

@akhoury
Copy link
Member

akhoury commented May 9, 2019

ok so, we don't really need markdown-it-attrs to set the dir=auto on each token, I just added that to give advanced feature support to users, I just removed that.

However, adding the dir=auto on each token is something just done using that quick plugin function passed to the parser,
I think this is cleaner than using the characters since it's part of the spec - the character codes didn't work for me, I think markdown-it is either filtering these out or encoding them first

We could write our own markdown-plugin to do both, add a dir attribute and a specific style attribute to take care of the text-alignment

@julianlam
Copy link
Member

@akhoury so how would one switch text direction in the middle of a post now? As long as it's easily defined I'm okay with it.

Right now I think the post body inherits directionality from the top html element, but your change would add it for each specific token, right? How would one switch to LTR in an RTL forum?

@akhoury
Copy link
Member

akhoury commented May 16, 2019

So yea, that first PR just detects the language and auto-set the direction for you -

I'm still planning to add a button to select the direction and another button to select the alignment, but we need to decide, either use that markdown-attr plugin or write our plugin, since markdown does not support direction or alignment, it has to be done using dir and style attributes, or we can use class but either way, it's a custom feature, not markdown-standard.

Also, there is no easy way to add a dropdown-button to the composer that basically opens-up a select list of other buttons, so, on hover or maybe on click show a list of other buttons, and the other would have the right click handler to perform actions, i was thinking of adding a general handler instead of a just a click handler here

formatting.addButtonDispatch = function(name, onClick) {
formattingDispatchTable[name] = onClick;
};

Or even make it like a addButtonsGroupDispatch so, each group would have a list of buttons each would then have its own click-handler.

ALIGN-BTN
> ALIGN-LEFT
> ALIGN-CENTER
> ALIGN-RIGHT

DIRECTION-BTN
> LTR
> AUTO
> RTL

@julianlam
Copy link
Member

I feel like we're unnecessarily attempting to reinvent the wheel here... how do other forums or authoring softwares handle mixed LTR and RTL?

@akhoury
Copy link
Member

akhoury commented May 16, 2019

well, for start, github doesn't support manually setting the direction, it's not even automatic.

مرحبا يا بشر.

Discourse doesn't either.

Other forums that support bbcode do have a way to do it [right]this text is aligned to the right[/right] or [rtl]something[/rtl], which generates <p dir="RTL">something</p>

it's really not a thing i've seen offered in markdown editors, it's more in the basic old wysiwyg html editors, where html is manipulated as needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants