Creating Tagged PDF Document in Seam iText - pdf

I am trying to create an accessible PDF using Seam and their iText implementation. I cannot find any references to whether or not this is possible. It seems that iText itself can handle it; the PDF on this example is tagged. But all of the PDFs that we create aren't and I can't seem to figure out how to add it.
Here's some sample code from one of our documents:
<?xml version="1.0" encoding="UTF-8"?>
<p:document xmlns:p="http://jboss.com/products/seam/pdf" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:s="http://jboss.com/products/seam/taglib" xmlns:h="http://java.sun.com/jsf/html" type="PDF" pageSize="letter" title="Letter" margins="15.0 40.0 20.0 10.0">
<f:facet name="header">
<p:font size="10" name="TIMES-ROMAN" style="bold">
<p:header borderWidth="0"/>
<p:footer borderWidthTop="0" borderWidthBottom="0" alignment="center">
FY #{handler.form.year}<p:text value=" #{handler.form.name}"/><p:text value=" "/>CAN #{handler.form.number}<p:text value=" "/>Object Class #{handler.form.class}<p:text value=" "/>#{handler.form.time}
</p:footer>
</p:font>
</f:facet>
<p:font size="10" name="TIMES-ROMAN">
<p:table columns="3" widthPercentage="100" widths="1 2 1">
<p:cell borderWidth="0">
<p:image alignment="left" value="/assets/img/logo.PNG" scalePercent="5"/>
</p:cell>
<p:cell borderWidth="0" horizontalAlignment="center" paddingTop="30">
<p:paragraph>
WORKSHEET
</p:paragraph>
</p:cell>
... snip ...
I realize that's not the best code (I'm just pulling from a document I'll need to clean up). Still, any ideas on if Seam can actually put in PDF tags?

Out-of-the-box tagged PDF is supported since iText 5.4.0 (which is the most recent version).
When you use the high-level objects such as Paragraph, PdfPTable, etc... and you use PdfWriter.setTagged(), then you get good quality Tagged PDF. You can even choose your own roles.
It would surprise me if jBoss/SEAM would be using such a recent version of iText. I've reached out to them to upgrade and the SEAM team never responded. (Who am I? I'm the CEO of iText Software.)

Related

How can I use pagemap with google custom search refinements?

I'm trying to add refinements to my google custom search.
I have meta tags on just about every page of the site, such as
<meta name="type-id" content="241" />
Where there are many different types, and I want to have one refinement for each type.
In the docs, it says
You can also use these more:pagemap: operators with refinement labels
But I have been unable to do that.
Note that I have had success using more:pagemap:metatags-type-id:241 in the search input, or as a webSearchQueryAddition - but despite googles docs, I haven't been able to get it to work with a refinement.
Here's a sample from my cse.xml (removing some attributes from the CustomSearchEngine tag):
<?xml version="1.0" encoding="UTF-8"?>
<CustomSearchEngine>
<Title>Test</Title>
<Context>
<Facet>
<FacetItem>
<Label name="videos" mode="FILTER">
<Rewrite>more:p:metatags-article-keyword:121</Rewrite>
</Label>
<Title>Videos</Title>
</FacetItem>
</Facet>
</Context>
</CustomSearchEngine>
Is this supposed to work? Am I using wrong syntax in the rewrite rule? Has anyone else done something like this?
Your label in the facet should be mode="BOOST" if you want to restrict to a structured data field within the scope of your engine.
<Facet>
<FacetItem>
<Label name="videos" mode="BOOST">
<Rewrite>more:p:metatags-article-keyword:121</Rewrite>
</Label>
<Title>Videos</Title>
</FacetItem>
</Facet>

Why this dash manifest keeps the player stuck until streams are downloaded?

I have this manifest file below . The issue is that the player waits for the streams to download completely before to start playing which is bad for the user experience. Any idea how to fix it? I expected the player to start range requests and feed media source with partial requests instead to wait for the streams to completely download.
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd" profiles="urn:mpeg:dash:profile:isoff-live:2011" type="static" mediaPresentationDuration="PT30M67.6S" minBufferTime="PT2S">
<ProgramInformation></ProgramInformation>
<Period id="0" start="PT0.0S">
<AdaptationSet id="0" contentType="video" segmentAlignment="true" bitstreamSwitching="true" lang="und">
<Representation id="0" mimeType="video/webm" codecs="vp9" bandwidth="770153" width="854" height="480" frameRate="23421/1000">
<BaseURL>https://liveradio.s3.eu-central-1.amazonaws.com/video.webm</BaseURL>
<SegmentList duration="1840613" startNumber="1">
<Initialization range="0-219"/>
<SegmentURL indexRange="220-6592"/>
</SegmentList>
</Representation>
</AdaptationSet>
<AdaptationSet id="1" contentType="audio" segmentAlignment="true" bitstreamSwitching="true" lang="und">
<Representation id="1" mimeType="audio/webm" codecs="opus" bandwidth="115412" audioSamplingRate="48000">
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
<BaseURL>https://liveradio.s3.eu-central-1.amazonaws.com/audio.webm</BaseURL>
<SegmentList duration="1840641" startNumber="1">
<Initialization range="0-258"/>
<SegmentURL indexRange="259-3444"/>
</SegmentList>
</Representation>
</AdaptationSet>
</Period>
</MPD>
You seem to be using a mix of the DASH 'live' profile approach and the 'on-demand' profile one - you can see the profile in the profiles="urn:mpeg:dash:profile:isoff-live:2011" at the top of your manifest.
At a very high level the difference is:
'live' profile manifests contain a list of urls for each segment to be downloaded.
'on-demand' profile manifests contain a URL to a file and an index to where the segments can be found in the file, so the client can download chunks as it wants.
DASH is a complex specification and it may be that some players will accept some mixes of profiles and others not, and not all players support all features - for example Shaka player claims not to support 'indexRange' (or did in 2017: https://github.com/google/shaka-player/issues/765)

Dynamic localization using JSTL [duplicate]

I learnt from Google that Internationalization is the process by which I can make my
web application to use all languages. I want to understand Unicode for the process of internationalization, so I learnt about Unicode from here and there.
I am able to understand about Unicode that how a charset set in encoded to bytes and again bytes decoded to charset. But I don't know how to move forward further. I want to learn how to compare strings and I need to know how to implement internationalization in my web application. Any Suggestions Please? Please guide me.
My Objective:
My main objective is to develop a Web Application for Translation (English to Arabic & vice versa). I want to follow Internationalization. I wish to run my web Application for translation in all the three browsers namely FF, Chrome, IE. How do I achieve this?
In case of a basic JSP/Servlet webapplication, the basic approach would be using JSTL fmt taglib in combination with resource bundles. Resource bundles contain key-value pairs where the key is a constant which is the same for all languages and the value differs per language. Resource bundles are usually properties files which are loaded by ResourceBundle API. This can however be customized so that you can load the key-value pairs from for example a database.
Here's an example how to internationalize the login form of your webapplication with properties file based resource bundles.
Create the following files and put them in some package, e.g. com.example.i18n (in case of Maven, put them in the package structure inside src/main/resources).
text.properties (contains key-value pairs in the default language, usually English)
login.label.username = Username
login.label.password = Password
login.button.submit = Sign in
text_nl.properties (contains Dutch (nl) key-value pairs)
login.label.username = Gebruikersnaam
login.label.password = Wachtwoord
login.button.submit = Inloggen
text_es.properties (contains Spanish (es) key-value pairs)
login.label.username = Nombre de usuario
login.label.password = Contraseña
login.button.submit = Acceder
The resource bundle filename should adhere the following pattern name_ll_CC.properties. The _ll part should be the lowercase ISO 693-1 language code. It is optional and only required whenever the _CC part is present. The _CC part should be the uppercase ISO 3166-1 Alpha-2 country code. It is optional and often only used to distinguish between country-specific language dialects, like American English (_en_US) and British English (_en_GB).
If not done yet, install JSTL as per instructions in this answer: How to install JSTL? The absolute uri: http://java.sun.com/jstl/core cannot be resolved.
Create the following example JSP file and put it in web content folder.
login.jsp
<%# page pageEncoding="UTF-8" %>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%# taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<c:set var="language" value="${not empty param.language ? param.language : not empty language ? language : pageContext.request.locale}" scope="session" />
<fmt:setLocale value="${language}" />
<fmt:setBundle basename="com.example.i18n.text" />
<!DOCTYPE html>
<html lang="${language}">
<head>
<title>JSP/JSTL i18n demo</title>
</head>
<body>
<form>
<select id="language" name="language" onchange="submit()">
<option value="en" ${language == 'en' ? 'selected' : ''}>English</option>
<option value="nl" ${language == 'nl' ? 'selected' : ''}>Nederlands</option>
<option value="es" ${language == 'es' ? 'selected' : ''}>Español</option>
</select>
</form>
<form method="post">
<label for="username"><fmt:message key="login.label.username" />:</label>
<input type="text" id="username" name="username">
<br>
<label for="password"><fmt:message key="login.label.password" />:</label>
<input type="password" id="password" name="password">
<br>
<fmt:message key="login.button.submit" var="buttonValue" />
<input type="submit" name="submit" value="${buttonValue}">
</form>
</body>
</html>
The <c:set var="language"> manages the current language. If the language was supplied as request parameter (by language dropdown), then it will be set. Else if the language was already previously set in the session, then stick to it instead. Else use the user supplied locale in the request header.
The <fmt:setLocale> sets the locale for resource bundle. It's important that this line is before the <fmt:setBundle>.
The <fmt:setBundle> initializes the resource bundle by its base name (that is, the full qualified package name until with the sole name without the _ll_CC specifier).
The <fmt:message> retrieves the message value by the specified bundle key.
The <html lang="${language}"> informs the searchbots what language the page is in so that it won't be marked as duplicate content (thus, good for SEO).
The language dropdown will immediately submit by JavaScript when another language is chosen and the page will be refreshed with the newly chosen language.
You however need to keep in mind that properties files are by default read using ISO-8859-1 character encoding. You would need to escape them by unicode escapes. This can be done using the JDK-supplied native2ascii.exe tool. See also this article section for more detail.
A theoretical alternative would be to supply a bundle with a custom Control to load those files as UTF-8, but that's unfortunately not supported by the basic JSTL fmt taglib. You would need to manage it all yourself with help of a Filter. There are (MVC) frameworks which can handle this in a more transparent manner, like JSF, see also this article.
In addition to what BalusC said, you have to take care about directionality (since English is written Left-To-Right and Arabic the other way round). The easiest way would be to add dir attribute to html element of your JSP web page and externalize it, so the value comes from properties file (just like with other elements or attributes):
<html dir="${direction}">
...
</html>
Also, there are few issues with styling such application - you should to say the least avoid absolute positioning. If you cannot avoid that for some reason, you could either use different stylesheets per (each?) language or do something that is verboten, that is use tables for managing layout. If you want to use div elements, I'd suggest to use relative positioning with "symmetric" left and right style attributes (both having the same value), since this is what makes switching directionality work.
You could find more about Bi-Directional websites here.
based on this tutorial, I am using the following on GAE - Google's App Engine:
A jsp file as follows:
<%# page import="java.io.* %>
<%
String lang = "fr"; //Assign the correct language either by page or user-selected or browser language etc.
ResourceBundle RB = ResourceBundle.getBundle("app", new Locale(lang));
%>
<!DOCTYPE html>
<%# page contentType="text/html;charset=UTF-8" language="java"%>
<head>
</head>
<body>
<p>
<%= RB.getString("greeting") %>
</p>
</body>
And adding the files named: app.properties (default) and app_fr.properties (and so on for every language). Each of these files should contain the strings you need as follows: key:value_in_language, e.g. app_fr.properties contains:
greeting=Bonjour!
app.properties contains:
greeting=Hello!
That's all

FONET/FOP superscript; inline-container not showing up at all

I'm developing a FONET app to generate some simple PDF reports; got everything working except the client would like the registered trademark symbol raised up correctly to superscript level.
I tried text-altitude on an inline element with no success, so after digging around the internet's woeful XSL:FO documentation thought I needed to wrap that in an fo:inline-container. However, that does not show up at all.
I've cut it down by using this basic example:
<?xml version="1.0" encoding="utf-8"?>
<!-- inline-container-Converts-Block-to-Inline.fo
- Copyright (c) 2016, HerongYang.com, All Rights Reserved.
-->
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="page"
margin="0.1in" page-height="4in" page-width="3in">
<fo:region-body region-name="body" background-color="#eeeeee"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="page">
<fo:flow flow-name="body">
<fo:block margin="0.1in" padding="0.2in"
border-width="1px" border-style="solid"
background-color="#eeffff" color="#000000"
font-family="sans-serif" font-size="10pt">
Once upon a time
<fo:inline-container width="0.7in" margin="0in"
alignment-baseline="middle">
<fo:block background-color="#eeeeee" margin="0in"
border-width="1px" border-style="solid"
padding="4px">there were three little pigs</fo:block>
</fo:inline-container>
who lived with their Mother.
Early one morning they woke up and their mother said,
"<fo:inline font-style="italic" color="#ff22ff">you're too big
for this house and its time you left home.</fo:inline>"
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
and tried to run that, but this also does not display anything from the inline-container; tried in this online processor and that also doesn't show anything from the container, so not just a FONET issue.
FONET is a port of FOP 0.2, which should have basic support for both text-altitude and inline-container.
What am I missing? Is it possible to get a superscript effect in this version of FOP?
The conformance page that you link to shows that fo:inline-container is not supported. It still has only partial support in the latest FOP (https://xmlgraphics.apache.org/fop/compliance.html).
I assume that it's because you were trying things to get it to work, but putting "there were three little pigs" in a space 0.7in wide makes for a tall and narrow area from the fo:inline-container.
The good news is that you don't need fo:inline-container to make a superscript. Just use an fo:inline with baseline-shift="super" (see https://www.w3.org/TR/xsl11/#baseline-shift).
You may also want to consider both reducing the font-size for the superscript text (since the FO formatter won't assume that you also want that) and adding line-height-shift-adjustment="disregard-shifts" (see https://www.w3.org/TR/xsl11/#line-height-shift-adjustment) on an ancestor FO so that the superscript doesn't alter your line height:
<fo:block line-height-shift-adjustment="disregard-shifts"
margin="0.1in" padding="0.2in"
border-width="1px" border-style="solid"
background-color="#eeffff" color="#000000"
font-family="sans-serif" font-size="10pt">
Once upon a time<fo:inline
baseline-shift="super" font-size="0.8em">®</fo:inline>
there were three little pigs<fo:inline
baseline-shift="super" font-size="0.8em">®</fo:inline>
who lived with their Mother.
Early one morning they woke up and their mother said,
"<fo:inline font-style="italic" color="#ff22ff">you're too big
for this house and its time you left home.</fo:inline>"
</fo:block>
Also see "Character style setting" in the "Comprehensive XSL-FO Tutorials and Samples Collection" at https://www.antennahouse.com/antenna1/comprehensive-xsl-fo-tutorials-and-samples-collection/
The last resort, when your FO formatter does not implement baseline-shift, is to find a font with a superscript-looking registered trademark symbol. A quick trawl through the Windows 'Character Map' utility showed that 'Calibri' has one.

Docbook publishing for different target audiences

I like to have one docbook xml document that has content for several target audiences. Is there a filter that enables me to filter out the stuff only needed for "advanced" users?
The level attribute is invented by me to express what I have in mind.
<?xml version="1.0"?>
<book>
<title lang="en">Documentation</title>
<chapter id="introduction" level="advanced">
<title>Introduction for advanced users</title>
</chapter>
<chapter id="introduction" level="basic">
<title>Introduction for basic users</title>
</chapter>
<chapter id="ch1">
<para level="basic">Just press the button</para>
<para level="advanced">
Go to preferences to set your
needs and then start the process
by pressing the button.
</para>
</chapter>
</book>
DocBook does not have a level attribute. Perhaps you meant userlevel?
If you are using the DocBook XSL stylesheets to transform your documents, they have built-in support for profiling (conditional text). To use it you need to
use the profiling-enabled version of the stylesheet (e.g. use html/profile-docbook.xsl instead of the usual html/docbook.xsl), and
specify the attribute values you want to profile on via a parameter (e.g. set profile.userlevel to basic).
Chapter 26 of Bob Stayton's DocBook XSL: The Complete Guide has all the details.
Two ways, off the top of my head:
Write a quick script that takes the level as a parameter and, using XPath or regular expressions, that only spits out the XML you want.
Write an XSLT transformation that will spit out the XML you want.
(2) is cleaner, but (1) is probably faster to write up.